[development] proposal for theming nodes

Scott Courtney scott at 4th.com
Wed Dec 14 22:13:44 UTC 2005


On Wednesday 14 December 2005 16:30, Darrel O'Pry wrote:
>  I don't think the cms should have any
> set notions of where things belong.

I agree with the notion that the CMS shouldn't have any set notion of where
things belong *in page layout*, but I disagree when it comes to the content
relationship.

I'm currently working on the links_related module, which generates content
that is a web equivalent to footnotes, in that it is not germane to the
node body but rather provides links to further information. It is very
unlikely that a web designer would think putting this before the content
itself made any sense, because the links are probably meaningless until the
viewer has at least skimmed the content.

So yes, the content-generating module needs some way to "tell" the theme that
it's doing something that's an appendix to the content, vs. something that
introduces the content, vs. something that is not sequentially-related at all.

I think your weighting thing sounds cool, and maybe could be adapted to handle
what I suggest. But I have concerns about this:

> 0_nodevote, 1_node, 3_book it gets pretty easy to make them sortable...
> but making the key naming consistent and programmatic is what I need to
> figure out.   

How does 05_abc sort relative to 5_xyz or 539_def or 57_ghi?

If we're going to use true weighting, then instead of strings, let's follow
Drupal convention and use true integer weighting. I like your ideal, Darrel,
but let's take it to its fulfillment.

Consider the following hypothetical array, where the order in which I show
the sub-arrays represents a hypothetical order in which they are added by
a hook invocation:

$node->extra = array();

$node->extra[] = array(
    'module'=>'example_module_1',
    'weight'=>-1,
    'value'=>   "This is logically before the main node body, but probably "
          ."after other insertions."
);  
$node->extra[] = array(
    'module'=>'example_module_2',
    'weight'=>5,
    'value'=>   "This is a footnote-like item that logically follows the body."
);
$node->extra[] = array(
    'module'=>'example_module_3',
    'weight'=>5,
    'value'=>   "Another footnote-like item."
);
$node->extra[] = array(
    'module'=>'example_module_4',
    'weight'=>-10,
    'value'=>   "I want this to be seen as early as possible by the user."
);
$node->extra[] = array(
    'module'=>'example_module_5',
    'weight'=>10,
    'value'=>   "This is something of little importance that is logically last."
);
$node->extra[] = array(
    'module'=>'example_module_6',
    'weight'=>0,
    'value'=>   "It doesn't matter where on the page this renders."
);

In practice, the order of rendering for these would be:

  I want this to be seen as early as possible by the user.
  This is logically before the main node body, but probably after other insertions.
  ($node->body)
  It doesn't matter where on the page this renders.
  This is a footnote-like item that logically follows the body.
  Another footnote-like item.
  This is something of little importance that is logically last.

I'm betting that most existing modules append, rather than prepend, to
$node->body, so the zero-weights probably ought to go after rather than
before the body *in the default theme*. But a custom theme might render
them beside the body, or watermarked under the body text, or in a popup
window, or ... whatever.

The hook could be robustly written so that implementing modules could return:

* A simple string (themed HTML), in which case Drupal core wraps an array
  around it with a default weight of zero and the appropriate module name.
  Simple nodes that don't want to bother with the complex array can exploit
  this.

* An array of strings, in which case Drupal core does the above for each one.

* An array of arrays, in the $node->extra[] format, in which case Drupal core
  merges this array with what it's already built from other modules' return
  values.

After the hook invocation, core needs to use PHP's user-defined sorting feature
to sort the outer array by the weights of the inner arrays. Items that have
the same weight can render in any order.

Sidenote: The 'module' element of the subarrays is for debugging purposes
mostly; Drupal core wouldn't necessarily need to enforce the presence of
this element. But it does allow a theme to recognize and specially-handle
the output of particular modules. I don't recommend that as a general rule
for *published* themes, but if you're creating a theme for your own site...
why not? :-) Even published themes might want to specially-handle module
names that are part of Drupal core.

Darrel, I like this merger of our ideas better than my original proposal. For
one thing, it accomplishes with a single array what I did with three. The
weight of zero is an elegant "I don't care" value, eliminating my $node-extra
array's need. Your concept is more elegant than mine, and with the above
adaptation, it encapsulates everything I wanted to incorporate as well,
but with simpler semantics and with only one new hook.

In effect, what I'm proposing is that $node->body intrinsically fits into
this with an implied weight of zero, so that all the negative-value weights
float "above" the body and all the positive-value weights sink "below". I
quote the two relative positions to emphasize that it is up to the *theme*
to decide what these mean. Modules get to ask for the relationship they
want vis-a-vis the node body, and themes get to decide how that actually
renders on the page.

If there is interest in this concept, I'll volunteer to submit a patch to
node.module. "Talk is silver, code is gold." :-)

Scott

-- 
------------------------------------------------------------------------------
Scott Courtney         | "I don't mind Microsoft making money. I mind them
scott at 4th.com          | having a bad operating system."    -- Linus Torvalds
http://4th.com/        | ("The Rebel Code," NY Times, 21 February 1999)
                       | PGP Public Key at http://4th.com/keys/scott.pubkey


More information about the development mailing list