{%- macro moderated_post_warning(post) -%}
  <div class="js-post-moderation-message with-warning-icon">
    {% set post_type=post.get_post_type_display() %}
    {% trans %}This {{ post_type }} is being moderated, please do not repost it!{% endtrans %}
  </div>
{%- endmacro -%}

{%- macro used_count(count=0) -%}
  <span class="used-count">&#215;{{ count }}</span>
{%- endmacro -%}

{%- macro share(site = None) -%}
  <a class="js-{{ site }}-share with-{{site}}-icon share-btn"
    title="{% trans %}Share this content on {{site}}{% endtrans %}"
  ></a>
{%- endmacro -%}

{%- macro post_flag_buttons(post) -%}
  <span id="js-post-flag-btn-{{post.id}}" class="action-link with-flag-icon js-post-flag-btn">
    {% trans %}flag offensive{% endtrans %}
    <span class="js-post-flag-count {% if post.offensive_flag_count == 0 %}js-hidden{% endif %}"
    >{{ post.offensive_flag_count }}</span>
  </span>
  <span id="js-post-unflag-btn-{{post.id}}" class="action-link with-flag-icon js-post-unflag-btn {% if post.offensive_flag_count == 0 %}js-hidden{% endif %}">
    {% trans %}remove flag{% endtrans %}
  </span>
{%- endmacro -%}

{%- macro inbox_message_snippet(message) -%}
<div class="js-message-details" data-message-id="{{ message.id }}">
  <div class="message-meta">
    <input type="checkbox" />
    {{ gravatar(message.user, 16, hide_rep=True) }}
    <a class="username" href="{{ message.user.get_absolute_url() }}">{{ message.user.username|escape }}</a>
    <a class="post-link" href="{{ message.url }}">{{ message.message_type }}</a>
    ({{ timeago(message.timestamp) }})
  </div>
  {#<div class="snippet">{{ message.snippet }}</div>#}
  <div class="post-content">{{ message.content }}</div>
</div>
{%- endmacro -%}

{%- macro mailto_link(email) -%}
    <a href="mailto:{{ email }}">{{ email }}</a>
{%- endmacro -%}

{%- macro moderation_queue_message(message) -%}
<div class="message-details" data-message-id="{{ message.id }}">
  <div class="message-info">
    <input type="checkbox" />
    {{ gravatar(message.user, 16, hide_rep=True) }}
    <a class="username" href="{{ message.user.get_absolute_url() }}">{{ message.user.username|escape }}</a><span>|</span>
    {%- if message['memo_type'] == 'edit' -%}
      {{ mailto_link(message.user.email) }}<span>|</span>
      ip=<span class="ip-addr">{{ message.ip_addr }}</span><span>|</span>
    {%- endif %}
    <a class="forum-post-link" href="{{ message.url }}">{{ message.message_type }}</a>
    ({{ timeago(message.timestamp) }})
  </div>
  <div class="post-content">{{ message.content }}</div>
</div>
{%- endmacro -%}

{%- macro post_vote_buttons(post = None) -%}
<div class="js-post-vote-btn-group">
  <div id="js-post-upvote-btn-{{ post.id }}"
    class="js-post-vote-btn js-post-upvote-btn with-upvote-icon"
    data-post-id="{{post.id}}"
    data-post-type="{{post.post_type}}"
  ></div>
  <div class="js-post-vote-number"
    title="{% trans count=post.score %}{{ count }} vote{% pluralize %}{{ count }} votes{% endtrans %}"
  >{{ post.score|humanize_counter }}</div>
  <div id="js-post-downvote-btn-{{ post.id }}"
    class="js-post-vote-btn js-post-downvote-btn with-downvote-icon"
    data-post-id="{{post.id}}"
    data-post-type="{{post.post_type}}"
  >
  </div>
  <script type="text/javascript">
      askbot['functions']['renderPostVoteButtons']('{{post.id}}');
  </script>
</div>
{%- endmacro -%}

{%- macro post_last_updater_and_creator_info(post, visitor=None) -%}
  <div class='post-update-info-container'>
    {% if post.wiki %}
      <div class='post-update-info'>
        <div class="with-wiki-icon"></div>
        <div>
          {% set last_rev = post.get_latest_revision(visitor) %}
          <div>{{ timeago(post.added_at, action_performed=last_rev.get_action_label()) }}</div>
          {% set wiki_min_rep = settings.MIN_REP_TO_EDIT_WIKI %}
          <div class="tip">{% trans %}This post is a wiki.
          Anyone with karma &gt;{{wiki_min_rep}} is welcome to improve it.{% endtrans %}</div>
        </div>
      </div>
    {% else %}
      {% set first_rev = post.get_earliest_revision(visitor) %}
      {% set last_rev = post.get_latest_revision(visitor) %}
      {{ post_contributor_info(first_rev, last_rev) }}
      {% if first_rev != last_rev and first_rev.author_id != last_rev.author_id %}
        {{ post_contributor_info(last_rev) }}
      {% endif %}
    {% endif %}
  </div>
{%- endmacro -%}

{%- macro post_revision_link(revision) -%}
  <a class="post-revision-link"
    {% if revision.post.post_type == 'question' %}
      href="{{ url('question_revisions',  revision.post.id ) }}"
    {% else %}
      href="{{ url('answer_revisions',  revision.post.id ) }}"
    {% endif %}
  >{{ timeago(revision.revised_at, action_performed=revision.get_action_label()) }}</a>
{%- endmacro -%}

{%- macro post_contributor_info(revision, last_revision=None) -%}
<div class='post-update-info'>
  <div class='post-update-info-avatar'>
  {% if revision.is_anonymous %}
    {{ anon_avatar(32) }}
  {% else %}
    {{ gravatar(revision.author, 32) }}
  {% endif %}
  </div>
  <div class='post-update-info-details'>
    <div class='post-update-info-author-name'>
      {% if revision.is_anonymous %}
        {{ settings.NAME_OF_ANONYMOUS_USER }}
      {% else %}
        <a class="user-name-link" href="{{ revision.author.get_absolute_url() }}">{{ revision.author.username }}</a>
        {% if settings.GROUPS_ENABLED %}
          {{ user_primary_group(revision.author) }}
        {% endif %}
      {% endif %}
    </div>
    <div class='post-update-info-revision-links'>
      {{ post_revision_link(revision) }}
      {%- if revision != last_revision and revision.author_id == last_revision.author_id -%},
        {{ post_revision_link(last_revision) }}
      {% endif %}
    </div>
  </div>
</div>
{%- endmacro -%}

{%- macro if_else(condition, if_true, if_false) -%}
    {%- if condition == True -%}
        {{if_true}}
    {%- else -%}
        {{if_false}}
    {%- endif -%}
{%- endmacro -%}

{%- macro tag_cloud(tags = None, font_sizes = None, search_state = None) -%}
    {% for tag in tags %}
    <span class="tag-size-{{ font_sizes[tag.name]|escape }}">
        <a
            class="link-typeA"
            title="Number of entries: {{ tag.used_count }}"
            href="{{ search_state.add_tag(tag.name).full_url() }}"
        >{{ tag.name|escape }}</a>
    </span>
    {% endfor %}
{%- endmacro -%}

{%- macro tag_list_widget(
  tags,
  id=None,
  deletable=False,
  label=None,
  make_links=True,
  search_state=None,
  css_class=None,
  truncate_long_tags=False,
  question_id=None,
  with_edit_link=False
)
-%}
  <ul class="tags{% if tags %} js-has-tags{% endif %}{% if css_class %} {{css_class}}{% endif %}">
    {% if tags %}
      {% if label %}
        <li class="js-search-tags-label">{{ label }}</li>
      {% endif %}
      {%- for tag in tags -%}
        {% filter trim %}
        <li>
            {{ tag_widget(
                tag,
                deletable=deletable,
                is_link=make_links,
                search_state=search_state,
                truncate_long_tag=False
            )}}
        </li>
        {% endfilter %}
      {%- endfor -%}
    {% endif %}
    {% if with_edit_link %}
      <li class="js-retag-btn-ctr">
        <span
          class="js-retag-btn action-link {% if not tags %}js-hidden{% endif %}"
          data-question-id="{{ question_id }}"
        >
          {% trans %}retag{% endtrans %}
        </span>
        <span
          class="js-retag-btn action-link {% if tags %}js-hidden{% endif %} with-tags-icon"
          data-question-id="{{ question_id }}"
        >
          {% trans %}add tags{% endtrans %}
        </span>
      </li>
    {% endif %}
  </ul>
{%- endmacro -%}

{%- macro user_group_link(group) -%}
    <a class="group-name"
        href="{{ url('users_by_group', group.id, group.name|replace('-', ' ')|slugify) }}"
    >{{ group.name|escape }}</a>
{%- endmacro -%}

{%- macro user_group(group, membership_info, show_count=False) -%}
    <td>
        {{ user_group_link(group) }}
    </td>
    {% if show_count %}
        <td>{{ group.users_count }}</td>
    {% endif %}
    <td>
      {% if group.description %}
        {{ group.description.summary }}
      {% endif %}
    </td>
{%- endmacro -%}

{%- macro user_primary_group(user) -%}
    {% set group=user.get_primary_group() %}
    {% if group %}
        <span class="primary-group-name"><a
            class="primary-group-name"
            href="{{ url('users_by_group', group.id, group.name|replace('-', ' ')|slugify) }}"
        >{{ group.name|replace('-', ' ')|escape }}</a></span>
    {% endif %}
{%- endmacro -%}

{%- macro group_join_button(
    group_id=None, acceptance_level='closed', membership_level='none')
-%}
    {% if acceptance_level in ('open', 'moderated') %}
        <button
            class="btn js-join-group-btn button"
            data-group-id="{{group_id}}"
            data-is-on="{{ membership_level|not_equal('none')|as_js_bool }}"
            {% if acceptance_level == 'open' %}
                data-off-prompt-text="{% trans %}Leave this group{% endtrans %}"
                data-on-prompt-text="{% trans %}Join this group{% endtrans %}"
                data-on-state-text="{% trans %}You are a member{% endtrans %}"
                data-off-state-text="{% trans %}Join this group{% endtrans %}"
            {% else %}
                {% if membership_level == 'full' %}
                    data-off-prompt-text="{% trans %}Leave this group{% endtrans %}"
                    data-on-state-text="{% trans %}You are a member{% endtrans %}"
                {% else %}
                    data-off-prompt-text="{% trans %}Cancel application{% endtrans %}"
                    data-on-state-text="{% trans %}Awaiting approval{% endtrans %}"
                {% endif %}
                data-on-prompt-text="{% trans %}Ask to join{% endtrans %}"
                data-off-state-text="{% trans %}Ask to join{% endtrans %}"
            {% endif %}
        >
            {% if membership_level == 'full' %}
                {% trans %}You are a member{% endtrans %}
            {% elif membership_level == 'pending' %}
                {% trans %}Awaiting approval{% endtrans %}
            {% else %}
                {% if acceptance_level == 'open' %}
                    {% trans %}Join this group{% endtrans %}
                {% else %}
                    {% trans %}Ask to join{% endtrans %}
                {% endif %}
            {% endif %}
        </button>
    {% endif %}
{%- endmacro -%}

{# todo: remove the extra content argument to make its usage more explicit #}
{%- macro tag_widget(
            tag,
            deletable=False,
            is_link=True,
            css_class=None,
            search_state=None,
            extra_content='',
            truncate_long_tag=False
        )
-%}
  {% if not search_state %}  {#  get empty SearchState() if there's none; CAUTION: for some reason this doesn't work inside `spaceless` tag below! #}
      {% set search_state=search_state|get_empty_search_state %}
  {% endif %}
  {% filter trim %}
    <div class="js-tag{% if tag|is_admin_tag %} js-admin-tag{% endif %}{% if deletable %} js-deletable-tag{% endif %}">
        <{% if is_link %}a{% else %}span{% endif %}
            class="js-tag-name{% if css_class %} {{ css_class }}{% endif %}"
            rel="tag"
            {% if is_link and not tag.endswith('*') %}
            href="{{ search_state.add_tag(tag).full_url() }}"
            {% endif %}
            data-tag-name="{{ tag|escape }}"
        >{% if truncate_long_tag -%}
                {{ tag|truncate(17, True)|escape|replace('*', '&#10045;')}}
            {%- else -%}
                {{ tag|escape|replace('*', '&#10045;') }}
            {%- endif -%}
        </{% if is_link %}a{% else %}span{% endif %}>
        {%- if deletable -%}
            <span class="js-delete-icon">&times;</span>
        {%- endif %}
        {% if extra_content %}
        <span class="js-tag-extra-content">{{ extra_content }}</span>
        {% endif %}
    </div>
  {% endfilter %}
{%- endmacro -%}

{%- macro radio_select(name = None, value = None, choices = None) -%}
  {% for choice in choices %}
    {% set id = "id_" ~ name ~ "_" ~ choice[0] %}
    <label class="radio-button-choice" for="{{ id }}">
      <input
        id="{{ id }}"
        name="{{ name }}"
        value="{{ choice[0] }}"
        type="radio"
        {% if value == choice[0] %}
        checked="checked"
        {% endif %}
      />
      {{ choice[1] }}
    </label>
  {% endfor %}
{%- endmacro -%}

{# Warning! Any changes to the comment markup here must be duplicated in post.js
for the purposes of the AJAX comment editor #}

{%- macro comments_widget_buttons(post=None, max_comments=None, user=None) -%}
  {% set more_comments = post.get_comments_count(user) > max_comments %}
  <a id="js-add-comment-for-post-{{ post.id }}-btn" class="js-add-comment-btn action-link {% if more_comments %}js-hidden{% endif %}"
  >{% trans %}add a comment{% endtrans %}</a>
  <a class="js-load-comments-btn action-link {% if not more_comments %}js-hidden{% endif %}">{% trans %}see more comments{% endtrans %}</a>
  <script type="text/javascript">
    if (!askbot.data.userCanPostComments) {
      var btn = document.getElementById('js-add-comment-for-post-' + {{ post.id }} + '-btn');
      btn.style.display = 'none'
    }
  </script>
{%- endmacro -%}

{%- macro csrf_middleware_token(csrf_token) -%}
    <div style="display: none;">
        <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}" />
    </div>
{%- endmacro -%}

{%- macro comment_widget(comment, csrf_token=None) -%}
  <div id="js-post-{{comment.id}}" class="js-comment" data-post-id="{{ comment.id }}">
    <div class="comment-votes">
      <div id="js-post-upvote-btn-{{comment.id}}"
        class="js-post-upvote-btn js-score with-comment-upvote-icon"
        title="{% trans %}upvote comment{% endtrans %}"
      >{% if comment.score > 0 %}{{ comment.score }}{% endif %}</div>
      {% if comment.id %}
      <script type="text/javascript">
        askbot['functions']['renderPostVoteButtons']('{{ comment.id }}');
      </script>
      {% endif %}
    </div>
    <div class="js-comment-content">
      {% if comment.needs_moderation() %}
        {{ moderated_post_warning(comment) }}
      {% endif %}
      <div class="js-comment-body">
        {{ comment.summary }}
      </div>
      <div class="js-comment-controls">
        {# important - the same number for avatar size must be in question/javascript.html #}
        {% if hasattr(comment.author, 'is_terminated') and comment.author.is_terminated() %}
          {{ anon_avatar(16) }}
          <span class="js-comment-author">{{ comment.author.get_anonymous_name() }}</span>
        {% else %}
          {{ gravatar(comment.author, 16, hide_rep=True) }}
          <a class="js-comment-author" href="{{ comment.author.get_profile_url() }}"
          >{{comment.author.username|escape}}</a>
        {% endif %}
        <span class="comment-age">({{ timeago(comment.added_at) }})</span>
        <span class="action-link js-comment-edit-btn js-edit">{% trans %}edit{% endtrans %}</span>
        <div class="js-dropdown-menu js-toolbar-dropdown-menu action-link">
          <div class="js-dropdown-trigger with-caret-down-icon">{% trans %}more{% endtrans %}</div>
          <ul class="js-dropdown-target">
            <li>
              <span class="action-link js-comment-delete-btn"
                title="{% trans %}delete this comment{% endtrans %}">delete</span>
            </li>
            <li>
              <form class="repost-comment-as-answer" action="{{ url('comment_to_answer') }}" method="POST" accept-charset="utf-8">
                <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}" />
                <input type="hidden" value="{{ comment.id }}" name="comment_id">
                <input class="action-link js-comment-convert-btn with-convert-post-icon" type="submit" value="{% trans %}convert to answer{% endtrans %}">
              </form>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  {% if comment.id %}
  <script type="text/javascript">
      askbot.functions.hideConvertLinks();
      askbot.functions.renderPostControls('{{ comment.id }}', false);
  </script>
  {% endif %}
{%- endmacro -%}

{%- macro post_comments(
  post=None,
  show_post=None,
  show_comment=None,
  show_comment_position=None,
  user=None,
  max_comments=None,
  csrf_token=None
) -%}
  {% if show_post == post and show_comment and show_comment_position > max_comments %}
    {% set comments = post.get_cached_comments()[:show_comment_position] %}
  {% else %}
    {% set comments = post.get_cached_comments()[:max_comments] %}
  {% endif %}
  {% set comments_count = comments|length %}
  <div class="js-post-comments {% if comments_count == 0 %}js-empty{% endif %}"
    data-parent-post-id="{{ post.pk }}"
    data-parent-post-type="{{ post.post_type }}">
    <h2 class="js-comments-list-title {% if comments_count == 0 %}js-hidden{% endif %}"
    >{% trans %}Comments{% endtrans %}</h2>
    <div class="js-comments-list">
      {% for comment in comments %}
        {{ comment_widget(comment, csrf_token) }}
      {% endfor %}
    </div>
    <div class="comments-list-controls">
      {% if show_post == post and show_comment and show_comment_position > max_comments %}
        {{ comments_widget_buttons(post=post, max_comments=show_comment_position, user=user) }}
      {% else %}
        {{ comments_widget_buttons(post=post, max_comments=max_comments, user=user) }}
      {% endif %}
    </div>
  </div>
{%- endmacro -%}

{%- macro reversible_sort_button(
  sort_by=None,
  asc_tooltip=None,
  desc_tooltip=None,
  label=None,
  current_sort_method=None,
  search_state=None)
-%}
{#
    sort button where descending sort is default
    and the search method is togglable between ascending and descending
    buttons are rendered as links with id constructed as
    "by_" + button_sort_criterium
    class "on" is added when current_sort_method is one of
    button_sort_criterium + "asc" or "desc"
#}
  {% if current_sort_method == sort_by + "-asc" %}{# "worst" first #}
    <a href="{{ search_state.change_sort(sort_by+"-desc").full_url() }}"
       class="js-sort-by-{{sort_by}} js-selected js-with-sort-ascending-icon"
       title="{{desc_tooltip}}"
       data-sort-by="{{sort_by}}"
    >
      {{label}}
    </a>
  {% elif current_sort_method == sort_by + "-desc" %}{# "best first" #}
    <a href="{{ search_state.change_sort(sort_by+"-asc").full_url() }}"
       class="js-sort-by-{{sort_by}} js-selected js-with-sort-descending-icon"
       title="{{asc_tooltip}}"
       data-sort-by="{{sort_by}}"
    >
      {{label}}
    </a>
  {% else %}{# default, when other button is active #}
    <a href="{{ search_state.change_sort(sort_by+"-desc").full_url() }}"
       class="js-sort-by-{{sort_by}}"
       data-sort-by="{{sort_by}}"
       title="{{desc_tooltip}}"
    >
      {{label}}
    </a>
  {% endif %}
  <script type="text/javascript">{# need to pass on text translations to js #}
    askbot['data']['sortButtonData'] = askbot['data']['sortButtonData'] || {};
    askbot['data']['sortButtonData']['{{sort_by}}'] = {
      label: '{{label}}',
      asc_tooltip: '{{asc_tooltip}}',
      desc_tooltip: '{{desc_tooltip}}'
    };
  </script>
{%- endmacro %}

{%- macro checkbox_in_div(checkbox_field, class = 'checkbox') -%}
    <div{% if class %} class="{{class}}"{% endif %}
        title="{{checkbox_field.help_text}}">
        {{ checkbox_field.errors }}
        {{ checkbox_field }}
        {{ checkbox_field.label_tag() }}
    </div>
{%- endmacro -%}

{%- macro edit_post(post_form, settings, post_html=None) -%}
    {# todo: retire this macro, this will require renaming
    or using "set" on some template variables #}
    {% include "editors/rich_text.html" %}
{%- endmacro -%}

{%- macro tag_autocomplete_js(id = '#id_tags') -%}
    var tagAc = new AutoCompleter({
            url: '{{ url('get_tag_list') }}',
            minChars: 1,
            useCache: true,
            matchInside: true,
            maxCacheLength: 100,
            delay: 10
    });
    tagAc.decorate($("{{ id }}"));
{%- endmacro -%}

{%- macro user_long_score_and_badge_summary(user) -%}
  {%- include "widgets/user_long_score_and_badge_summary.html" -%}
{%- endmacro -%}

{%- macro user_country_flag(user) -%}
  {% if user.country and user.country.code != 'none' and user.show_country %}
    <img class="flag"
      {# src="{{ user.country.flag }}" this is better but not compatible with v 1.0.5 #}
      src="{{ ('/images/flags/' ~ user.country.code|lower ~ '.gif')|media }}" {# use 'local' copy of flags #}
      alt="{% trans
              country=user.country.name
              %}flag of {{country}}{%
          endtrans %}"
      title="{% trans
              country=user.country.name,
              person=user.username|escape %}{{person}} is from {{country}}{%
           endtrans %}"
    />
  {% endif %}
{%- endmacro -%}

{%- macro user_country_name_and_flag(user) -%}
    {% if user.country and user.show_country %}
        {{ user.country.name }}
        {{ user_country_flag(user) }}
    {% endif %}
{%- endmacro -%}

{%- macro user_full_location(user) -%}
    {% if user.location %}
        {{ user.location|escape }},
    {% endif %}
    {{ user_country_name_and_flag(user) }}
{%- endmacro -%}

{% macro user_card(user) %}
  {% include "components/user_card.html" %}
{% endmacro %}

{%- macro users_list(users) -%}
    {% include "components/users_list.html" %}
{%- endmacro -%}

{# does not call any user methods #}
{%- macro simple_avatar(user_data) -%}
  {% set username=user_data['username']|escape %}
  <a class="js-avatar-box" href="{{ user_data['profile_url'] }}"><img class="js-avatar gravatar" 
      src="{{ user_data['avatar_url'] }}"
      title="{{ username }}" 
      alt="{% trans %}{{username}}'s avatar{% endtrans %}"
  />
  {%- if user_data['reputation'] and settings.KARMA_MODE == 'public' -%}
    <div class="reputation-badge">
      {{ user_data['reputation']|humanize_counter }}
    </div>
  {%- endif -%}
  </a>
{%- endmacro -%}

{#todo: rename this to avatar #}
{%- macro gravatar(user, size, hide_rep=False) -%}
  {{ simple_avatar({
    'id': user.id,
    'avatar_url': user.get_avatar_url(size),
    'profile_url': user.get_absolute_url(),
    'username': user.username,
    'reputation': (not hide_rep) and user.get_localized_profile().get_reputation()
  })}}
{%- endmacro -%}

{%- macro anon_avatar(size) -%}
  <span class="js-avatar-box">
    <img class="js-avatar gravatar"
      alt="{% trans %}anonymous user{% endtrans %}"
      src="{{ '/images/anon.png'|media }}"
      width="{{ size }}"
      height="{{ size }}"
    />
  </span>
{%- endmacro -%}

{%- macro user_website_link(user, max_display_length=25, force_show=False) -%}
  {% if user.website and (force_show or (not (user.is_blocked() or user.is_watched()))) %}
    <a href="{{user.website|escape}}"
      class="user-website-link"
      title="{% trans username=user.username|escape, url=user.website|escape %}{{username}}'s website is {{url}}{% endtrans %}"
      {% if user.can_have_strong_url() == False %}
      rel="nofollow"
      {% endif %}
    >
    {{user.website|strip_website_url|truncate(length=max_display_length, killwords=True, end='...')}}
    </a>
  {% endif %}
{%- endmacro -%}

{%- macro paginator(p, anchor='') -%}{# p is paginator context dictionary #}
  {% filter trim %}
    {% if p.is_paginated %}
      <div class="paginator" data-num-pages="{{ p.pages }}">
        <a class="js-prev-page prev-page with-caret-left-icon{% if p and not p.has_previous %} js-disabled{% endif %}"
          href="{{p.base_url}}page={{ p.previous }}{{ anchor }}"
          aria-label="{% trans %}previous{% endtrans %}"
        ></a>

        <span class="js-first-page-block"
          {% if p.in_leading_range %}style="display: none"{% endif %}
        >
          <a class="page"
            href="{{p.base_url}}page={{1}}{{ anchor }}"
            aria-label="{% trans %}first{% endtrans %}"
            data-page="1"
          >1</a>
          <span class="with-ellipsis-h-icon"></span>
        </span>

        {% for num in p.page_numbers %}
          {% if num == p.page %}
            <a class="current-page page"
              data-page="{{ num }}"
              aria-label="{% trans %}current page{% endtrans %}"
            >
              {{ num }}
            </a>
          {% else %}
            <a class="page"
              href="{{p.base_url}}page={{ num }}{{ anchor }}"
              data-page="{{ num }}"
              aria-label="{% trans %}page {{num}}{% endtrans %}"
            >
              {{ num }}
            </a>
          {% endif %}
        {% endfor %}

        <span class="js-last-page-block"
          {% if p.in_trailing_range %}style="display: none"{% endif %}
        >
          <span class="with-ellipsis-h-icon"></span>
          <a href="{{ p.base_url }}page={{ p.pages }}{{ anchor }}"
            class="page"
            data-page="{{p.pages}}"
            aria-label="{% trans num=p.pages %}page {{ num }}{% endtrans %}"
          >
            {{ p.pages }}
          </a>
        </span>
        <a class="js-next-page next-page with-caret-right-icon{% if p and not p.has_next %} js-disabled{% endif %}"
          href="{{p.base_url}}page={{ p.next }}{{ anchor }}"
          aria-label="{% trans %}next page{% endtrans %}"
        ></a>
      </div>
    {% endif %}
  {% endfilter %}
{%- endmacro -%}

{# p is paginator context dictionary #}
{%- macro ajax_paginator(p, class="js-paginator", data_url=None, result_placement_selector=None, request_params=None) -%}
  <div class="{{ class }}"
    {% if not p or not p.is_paginated %}style="display: none"{% endif %}
    {% if p and p.pages %}data-num-pages="{{ p.pages }}"{% endif %}
    {% if data_url %}data-data-url="{{ data_url }}"{% endif %}
    {% if result_placement_selector %}data-result-placement-selector="{{ result_placement_selector }}"{% endif %}
    {% if request_params %}data-request-params='{{ request_params|as_json }}'{% endif %}
  >
    <a class="js-prev-page with-caret-left-icon{% if p and not p.has_previous %} js-disabled{% endif %}"
      {% if p and p.previous %}data-page="{{ p.previous }}"{% endif %}
      aria-label="{% trans %}previous{% endtrans %}"
    ></a>

    <span class="js-first-page-block"
      {% if p and p.in_leading_range %}style="display: none"{% endif %}
    >
      <a class="js-page"
        aria-label="{% trans %}first page{% endtrans %}"
        data-page="1"
      >1</a>
      <span class="js-paginator-ellipsis with-ellipsis-h-icon"></span>
    </span>

    <span class="js-main-pages-block"
      {% if not p or not p.page_numbers %}style="display: none"{% endif %}
    >
      {% for num in p.page_numbers %}
        {% if num == p.page %}
          <a class="js-page js-current-page"
            data-page="{{ num }}"
            aria-label="{% trans %}current page{% endtrans %}"
          >
            {{ num }}
          </a>
        {% else %}
          <a class="js-page"
            data-page="{{ num }}"
            aria-label="{% trans %}page {{num}}{% endtrans %}"
          >
            {{ num }}
          </a>
        {% endif %}
      {% endfor %}
    </span>

    <span class="js-last-page-block"
      {% if p.in_trailing_range %}style="display: none"{% endif %}
    >
      <span class="js-paginator-ellipsis with-ellipsis-h-icon"></span>
      <a class="js-page"
        data-page="{{p.pages}}"
        aria-label="{% trans num=p.pages %}page {{ num }}{% endtrans %}"
      >
        {{ p.pages }}
      </a>
    </span>

    <a class="js-next-page with-caret-right-icon{% if p and not p.has_next %} js-disabled{% endif %}"
      data-page="{{ p.next }}"
      aria-label="{% trans %}next page{% endtrans %}"
    ></a>
  </div>
{%- endmacro -%}

{%- macro paginator_questions(p, search_state) -%} {# p is paginator context dictionary #}
  {% filter trim %}
    {% if p.is_paginated %}
      <div class='paginator'>
        <a class='with-caret-left-icon prev-page{% if p and not p.has_previous %} js-disabled{% endif %}'
          href='{{ search_state.change_page(p.previous).full_url() }}'
          aria-label='{% trans %}previous{% endtrans %}'
        ></a>
        {% if not p.in_leading_range %}
        <span class="js-first-page-block">
          {% for num in p.pages_outside_trailing_range %}
            <a class='page'
              href='{{ search_state.change_page(num).full_url() }}'
              aria-label='{% trans num=p.pages %}page {{ num }}{% endtrans %}'
            >
              {{ num }}
            </a>
          {% endfor %}
          <span class='with-ellipsis-h-icon'></span>
        </span>
        {% endif %}

        {% for num in p.page_numbers %}
          {% if num == p.page and p.pages != 1%}
            <a class='current-page page'>{{ num }}</a>
          {% else %}
            <a class='page'
              href="{{ search_state.change_page(num).full_url() }}"
              aria-label='{% trans num=p.pages %}page {{ num }}{% endtrans %}'
            >
              {{ num }}
            </a>
          {% endif %}
        {% endfor %}

        {% if not p.in_trailing_range %}
        <span class="js-last-page-block">
          <span class='with-ellipsis-h-icon'></span>
          {% for num in p.pages_outside_leading_range|reverse %}
            <a class='page'
              href='{{ search_state.change_page(num).full_url() }}'
              aria-label='{% trans num=p.pages %}page {{ num }}{% endtrans %}'
            >
              {{ num }}
            </a>
          {% endfor %}
        </span>
        {% endif %}
        <a class='with-caret-right-icon next-page{% if p and not p.has_next %} js-disabled{% endif %}'
          href="{{ search_state.change_page(p.next).full_url() }}"
          aria-label="{% trans %}next page{% endtrans %}"
        ></a>
      </div>
    {% endif %}
  {% endfilter %}
{%- endmacro -%}

{%- macro moderation_items_link(user, moderation_items) -%}
    {% if moderation_items %}
        <a id="ab-responses" href="{{ url('moderation_queue') }}">
        {% if moderation_items['new_count'] > 0 %}
            <img src="{{'/images/dialog-warning.png'|media}}"
            {% if moderation_items['seen_count'] > 0 %}
                alt="{% trans new=moderation_items['new_count'], seen=moderation_items['seen_count']%}{{new}} new flagged posts and {{seen}} previous{% endtrans %}"
                title="{% trans new=moderation_items['new_count'], seen=moderation_items['seen_count']%}{{new}} new flagged posts and {{seen}} previous{% endtrans %}"
            {% else %}
                alt="{% trans new=moderation_items['new_count'] %}{{new}} new flagged posts{% endtrans %}"
                title="{% trans new=moderation_items['new_count'] %}{{new}} new flagged posts{% endtrans %}"
            {% endif %}
            />
        {% elif moderation_items['seen_count'] > 0 %}
            <img src={{'/images/dialog-warning-off.png'|media}}
                alt="{% trans seen=moderation_items['seen_count'] %}{{seen}} flagged posts{% endtrans %}"
                title="{% trans seen=moderation_items['seen_count'] %}{{seen}} flagged posts{% endtrans %}"
            />
        {% endif %}
        </a>
    {% endif %}
{%- endmacro -%}

{%- macro timeago(datetime_object, action_performed=None) -%}
{%- set when='<abbr class="js-timeago" title="'
              ~ datetime_object.replace(microsecond=0)|add_tz_offset
              ~ '">'
              ~ datetime_object.replace(microsecond=0)|add_tz_offset
              ~ '</abbr>'
  -%}
  {%- if action_performed -%}
    {# action and time can be reversed, depending on language #}
    {% trans %}{{ action_performed }} {{ when }}{% endtrans %}
  {%- else -%}
    {{ when }}
  {%- endif -%}
{%- endmacro -%}

{% macro one_shot_form_js(form=None, submit_button=None) %}
    <script type="text/javascript">
        (function() {
            var form = new OneShotForm();
            form.setSubmitButton($("{{submit_button}}"));
            form.decorate($("{{form}}"));
        })();
    </script>
{% endmacro %}

{% macro form_field_with_errors(field) %}
    {% if field.errors %}
        <p class="error">{{ field.errors|join(", ") }}</p>
    {% endif %}
    {{ field }}
{% endmacro %}
