Footnotes module would rock if there was an arrow at the end of each footnote that returns to the location in the text where the note was referenced. The first place I saw it was at Daring Fireball and it's now being used at sites like Ars Technica. Accessibility Matters discusses the accessibility implications.

CommentFileSizeAuthor
#9 footnotes-theme-9.patch4.88 KBemfabric

Comments

hingo’s picture

Status: Active » Closed (works as designed)

Hi chris

If you are using the newest version of Footnotes (and the HTML variant), you should already have this feature. I have chosen not to print the little arrow or any other symbol, but the number of the footnote is a link that leads back to the original place in text. (So the link is at the beginning, not the end.)

The current design decision was based on a philosophy of not adding any icons or text to the text the user writes himself. (The arrow is actually a unicode character. As you see here, it may not even show correctly: http://daringfireball.net/2005/07/footnotes#fn2-2005-07-20)

So I feel that this feature exists and will close this issue. If you want to convince me to specifically use the arrow symbol, go ahead and try to persuade me :-)

Christefano-oldaccount’s picture

Ah, I see now where this feature is. Cool! I didn't see it before because, well... it's been a while since I've installed Footnotes and I didn't see this feature mentioned in the documentation.

This is a great addition to Footnotes. Thanks, and thank you for the really quick reply to this issue.

I'd prefer to have a setting in the input format configuration that would allow changing the placement of the link and giving it a Unicode character. Clicking the number to go back really isn't an immediately obvious thing to do. The good part about having the return arrow at the end of the text is that that's exactly where the reader's eyes will already be after reading the footnote.

If you'd like to reopen this issue, hopefully I or someone else will have the time to contribute a patch that adds a settings form.

hingo’s picture

Status: Closed (works as designed) » Active

Wow, if there is potential for an incoming patch...

Status now active again :-)

beginner’s picture

Title: Add link at the end of a footnote that returns to the text » make the footnote output themable

I've been thinking about this and other output related feature requests.

The thing is, right now all the output html is hardcoded, mainly in _footnotes_replace_callback().

The ideal approach would be to make the output themable, thus the default output can be overridden at the theme level. D6 has a vastly improved theme abstraction layer.
We need to implement hook_theme() and put all the html output in a separate theme function. After that, people will be to customize the output the way they want.

I don't have time to produce a patch, but if christefano of someone produces one, I'll review it.

hingo’s picture

Hi beginner

I completely agree, very good comment. thanks.

Ie: No configuration options, we should use themeability and hook_theme.

emfabric’s picture

I'm thinking about taking a crack at implementing themability. It seems like there'd need to be two themable output functions, one for a footnote link in the text, the other for the list of footnotes at the end of the text.

Two ways come to mind for specifying the link output function:
function theme_footnote_link($footnote_text,$footnote_label,$randstr) where the three string variables hold the attributes for the link, or
function theme_footnote_link($fn) where $fn is either a simple object or an associative array, containing the same attributes as properties or keys.

The list output function could then parallel that, taking a form such as
function theme_footnote_list($footnotes) where $footnotes is an array of $fn objects/arrays.

I lean towards implementing both functions with minimal attributes to ease their implementation in overriding themes.

I don't really understand what's going on in the textile filter, or if it would somehow need to relate to themed output.

hingo’s picture

What great news! If we get this done, it would make a great 2.0 release of Footnotes. (I was considering dropping/postponing this, so it's really great if you want to do it!) In fact, apart from this #198050: What package to use in footnotes.info ("Input filters")? Affects grouping in Admin panel. is the only one left I'd be semi-interested in closing before 2.0.

First: I'm considering deprecating the textile filter, no need to focus on that. (Or if not deprecating, but there is nothing to do there anyway.)

Arguments: My reading of http://api.drupal.org/api/function/hook_theme/6 especially

arguments: (required) An array of arguments that this theme hook uses. This value allows the theme layer to properly utilize templates. The array keys represent the name of the variable, and the value will be used as the default value if not specified to the theme() function. These arguments must be in the same order that they will be given to the theme() function.

to me it says:

1. We can define anything
2. "Between the lines" it kind of implies separate arguments and basic types (strings, numbers) to be used as arguments, not one compound array. Is this just my interpretation or is it reality? How are theme functions typically done in modules? How does it help overriding themes if it is an array? (Ah, I see it now, if things are added to an associative array, you can still use old themes and new stuff would just be ignored.)

You are right that the second function is an array in any case, since it is a list of indefinite length. In that sense using an array also in the first case might be straightforward, since you can then re-use the arrays directly.

I guess I have no strong opinion either way, just these insights. Feel free to just go ahead.

hingo’s picture

When committing your other patch I realised we need to clean up the api here. The using of $randstr as a separate variable is ok as long as it is inside on function, but actually it is an internal thing that theme developers shouldn't need to know about. This just got worse now that I needed to separate $value (the label) and $value_id (safe to use in html id attribute), we simply cannot send all of these to theme functions.

So the interface should rather be

function theme_footnote_link($value, $text, $ref_id, $fn_id) {
  // Need to process $text to be safe for using in html attribute (copy existing code)
  ...
  // Other than that, this one is just a one liner:
  return '<a class="see_footnote" id="' . $ref_id . '" title="' . $text . '" href="#' . $fn_id . '">' . $value . '</a>';
}
function theme_footnote_list($footnotes) {
  ...
  $str .= '<li><a class="footnote" id="' . $fn_id .'" href="#' . $ref_id . '">' . $value . '.</a> ';
  $str .= $text . "</li>\n";
  ...
}

As discussed above, those may be more appropriately passed in an associative array, but this was easier to use in an example.

emfabric’s picture

Version: 6.x-1.x-dev » 6.x-2.x-dev
Status: Active » Needs work
StatusFileSize
new4.88 KB

Ok, here's a go at a patch. It seems to work on my test installation, including overriding the theme functions.

I've defined an associative array that holds the information for a footnote as follows:

  $fn = array(
    'value' => $value,
    'text' => $matches[2],  // the text from a patten match
    'fn_id' => 'footnote' . $value_id . '_' . $randstr,
    'ref_id' => 'footnoteref' . $value_id . '_' . $randstr
  );

These arrays are then used in the two theme functions:

/**
 * Themed output of a footnote link appearing in the text body
 *
 * Accepts a single associative array, containing values on the following keys:
 *   text   - the raw unprocessed text extracted from within the [fn] tag
 *   value  - the raw unprocessed footnote number or other identifying label
 *   fn_id  - the globally unique identifier for the in-body footnote link 
 *            anchor, used to allow links from the list to the body
 *   ref_id - the globally unique identifier for the footnote's anchor in the  
 *            footnote listing, used to allow links to the list from the body
 */
function theme_footnote_link($fn) {
  $allowed_tags = array();  
  $title = filter_xss($fn['text'], $allowed_tags);
  // HTML attribute cannot contain quotes
  $title = str_replace('"', "&quot;", $title);
  // Remove newlines. Browsers don't support them anyway and they'll confuse line break converter in filter.module
  $title = str_replace("\n", " ", $title);
  $title = str_replace("\r", "", $title);
    
  return '<a class="see_footnote" id="' . $fn['ref_id'] . 
         '" title="' . $title . '" href="#' . $fn['fn_id'] . '">' . 
         $fn['value'] . '</a>';
}

/**
 * Themed output of the footnotes list appearing at at [footnotes]
 *
 * Accepts an array containing an ordered listing of associative arrays, each 
 * containing values on the following keys:
 *   text   - the raw unprocessed text extracted from within the [fn] tag
 *   value  - the raw unprocessed footnote number or other identifying label
 *   fn_id  - the globally unique identifier for the in-body footnote link 
 *            anchor, used to allow links from the list to the body
 *   ref_id - the globally unique identifier for the footnote's anchor in the  
 *            footnote listing, used to allow links to the list from the body
 */
function theme_footnote_list($footnotes) {
  $str = '<ol class="footnotes">';
  // loop through the footnotes
  foreach ($footnotes as $fn) {
    $str .= '<li><a class="footnote" id="' . $fn['fn_id'] .'" href="#' . $fn['ref_id'] . '">' . $fn['value'] . '.</a> ';
    $str .= $fn['text'] . "</li>\n";    
  }
  $str .= "</ol>\n";
  return $str;
}
hingo’s picture

Status: Needs work » Fixed

I had a problem that I needed to disable and re-enable the module before it started working. Before doing that all footnotes just disappeared (in other words, the theme functions were not called).

I made a last minute change of mind: I moved back this code:

  // Create a sanitized version of $text that is suitable for using as HTML attribute
  // value. (In particular, as the title attribute to the footnote link.)
  $allowed_tags = array();
  $text_clean = filter_xss($matches['2'], $allowed_tags);
  // HTML attribute cannot contain quotes
  $text_clean = str_replace('"', "&quot;", $text_clean);
  // Remove newlines. Browsers don't support them anyway and they'll confuse line break converter in filter.module
  $text_clean = str_replace("\n", " ", $text_clean);
  $text_clean = str_replace("\r", "", $text_clean);

to footnotes_replace_callback(). It is kind of wrong I guess, since it is up to the theme if it wants to show the text in a title attribute or something else or nothing. So it is unneccessary work that the theme may not use and is redundant with the raw text attribute. Even so I felt it can just as well be done here as a convenience to theme authors. The footnote_link theme is now just a one liner thanks to this.

So the attribute array becomes:


  // Create a footnote item as an array.
  $fn = array(
    'value' => $value,
    'text' => $matches[2],
    'text_clean' => $text_clean,
    'fn_id' => 'footnote' . $value_id . '_' . $randstr,
    'ref_id' => 'footnoteref' . $value_id . '_' . $randstr
  );

I've committed this to CVS. I'll figure out this one #198050: What package to use in footnotes.info ("Input filters")? Affects grouping in Admin panel. somehow too and in a couple of days I'll make a 2.0 release! Thanks again for this :-)

emfabric’s picture

I think it also works to clear the cache via "Clear cached data" on the performance page (admin/settings/performance), to get drupal to recognize the presence of themed functions.

I'm not sure how all that effects users upgrading. It shouldn't matter if people are following the recommended procedure of disabling modules prior to installing new versions.

Another thought that I had for maximum themability is to parse the full attribute string on the <fn>...</fn> and <footnotes /> and pass it to the theme functions. For example, this would allow a note of <fn class="highlighted">...</fn> to be passed to the theme function with an extra array element of $fn['attributes']['class'] with the "highlighted" value. In the case of the footnotes list, this would require a second argument on the theme_footnote_list function.

I don't have a personal need for such functionality, and it would add some additionally complexity.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.