Skip to content

Issues with multiple references to the same footnote #25

Open
@jsma

Description

@jsma

The current implementation assigns an ID to <sup> elements based on the footnote's index.

return f'<a href="#footnote-{index}" id="footnote-source-{index}"><sup>[{index}]</sup></a>'

This leads to duplicate id values so that browsers (tested in Chrome and Firefox) will only return to the first occurrence in the copy. This can cause issues if the first instance of "[1]" is not currently visible (e.g. in a collapsed accordion), the browser won't do anything when the "Back to content" link is clicked.

I've started working on an implementation to fix this situation which borrows ideas from Wikipedia. They handle this by always assigning unique IDs and then have individual links back to each reference in the copy, using letters of the alphabet. If there is a single reference, then the caret is clickable, otherwise the caret is not clickable, only the letters are:

Screen Shot 2022-02-24 at 1 10 20 PM

I have a basic WIP in my fork so that the block rendering will handle assigning unique IDs to the links and tracks these on the page object so when footnotes are rendered, they can be accessed.

This WIP does not currently change anything on the front-end. I'm still experimenting but so far can solve our issue by using a custom template and template tag to process multiple back links. For simplicity, I'm just using integers as the link text but it shouldn't be too hard to convert these to letters of the alphabet a la Wikipedia:

{% load core_tags %}
{% load wagtailcore_tags %}

{% if page.footnotes_list %}
  <ol>
    {% for footnote in page.footnotes_list %}
      <li id="footnote-{{ forloop.counter }}">
        {{ footnote.text|richtext }}
        {% with reference_ids=page|get_references:footnote.uuid %}
          {% with num=reference_ids|length %}
            {% if num == 1 %}
              <a href="#{{ reference_ids.0 }}" aria-label="Back to content">↩</a>
            {% else %}
              <span aria-label="Back to content">↩</span>
              {% for reference_id in reference_ids %}
                <a href="#{{ reference_id }}">
                  <sup>
                    <i><b>{{ forloop.counter }}</b></i>
                  </sup>
                </a>
              {% endfor %}
            {% endif %}
          {% endwith %}
        {% endwith %}
      </li>
    {% endfor %}
  </ol>
{% endif %}

And a simple template tag since we can't do variable lookups in dictionaries:

@register.filter
def get_references(value, footnote_uuid):
    return value.footnotes_references[footnote_uuid]

Let me know if something like this could be considered for inclusion. Happy to make a formal and comprehensive PR, but looking for feedback first. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions