As we were doing the theme part of our website, our designer asked us to add css class to distinguish between the first and next elements, and to have an odd-even system like. This patch allow composite to add a wrapper around each element of a zone.

<div class="composite-zone-inner">
<div class="first odd">
....
My first element
...
</div>
<div class="even">
... second element...
</div>
<div class="odd">
...third element...
</div>
<div class="even">
... fourth element...
</div>
</div>

Comments

raphael waeselynck’s picture

StatusFileSize
new3.86 KB

Here is the patch I worked on

bengtan’s picture

Status: Active » Postponed (maintainer needs more info)
StatusFileSize
new1.76 KB

Hi,

Actually, you didn't need to save position into the database since that can be computed from the weights.

I have reimplemented your idea in a cleaner way. Please try out the attached patch.

To use it, you have to override theme_composite_zone_item() in your theme with something like:

function yourtheme_composite_zone_item($text, $reference) {
  $position = $reference['position'];
  $class = '';
  if ($position == 1) {
    $class .= 'first ';
  }
  $class .= ($position % 2) ? 'odd' : 'even';
  return '<div class="' . $class . '">' . $text . '</div>';
}

Also, you have to clear your theme registry for this theme hook to be enabled.

Please give it a try and let me know how you go.

raphael waeselynck’s picture

I should have though "more reusable" :$
I'm testing your solution, but at first sight it should be fine
I'll tell you right away
cheers
Raphael

raphael waeselynck’s picture

Ok, the system is fine but there is a bug.
In composite_views, when you get your references with

$references = _composite_references_preprocess($references, $layout['zones'], FALSE);

They are not sorted by weight. So their positions does not mean anything.
Other point : we choose to put the computing of the position in composite.pages.inc in composite_zones_form_submit in aim to avoid computing positions each time we want to display our composite node. Indeed the computing is quite long, since it needs to study our references array two times : one for sorting, and second to set positions.
So what do you think about it ?
Regards,
Raphael

raphael waeselynck’s picture

Here is what I suggest for composite_views :

function composite_view($node, $layout = array(), $references = array()) {
  $composite_content = array();
  $references = _composite_references_preprocess($references, $layout['zones'], FALSE);
  $zone_positions = array();

  $elements = array(); //contains composite elements to dispatch on zones, indexed by zones, then by their weight
  foreach (element_children($references) as $id) {
    $reference = $references[$id];
    if (array_key_exists($reference['zone'], $layout['zones'])) {
      $elements[$reference['zone']][$reference['weight']] = $reference;
    }
  }

  foreach ($elements as $zone => &$zone_elements) {
    if (ksort($zone_elements)) {
      foreach ($zone_elements as $weight => $reference) {
        $output = composite_invoke_referenceapi($reference, 'view', $node);
        if ($output) {
          if (!isset($zone_positions[$reference['zone']])) {
            $zone_positions[$reference['zone']] = 1;
          }
          $reference['position'] = $zone_positions[$reference['zone']]++;
          // Allow themes to modify or override the output
          $output = theme('composite_zone_item', $output, $reference);
          $composite_content[$reference['zone']][$reference['id']] = array(
            '#value' => $output,
            '#weight' => $reference['weight'],
          );
        }
      }
    }
  }
  return $composite_content;
}

With your patch, it works fine. Please tell me if it is fine for you

bengtan’s picture

Hi,

My apologies. I developed my patch based against a dataset which I didn't realise was already in order because of when the items were created.

As a general rule, I avoid storing derived values (such as position) in the database. However when you say that sorting everytime the node is loaded takes long, then that's also fair enough. Presumably you have many more items than I would expect.

So let's see if we can find a middle ground that suits both of us.

We have a couple of approaches.

1) If you still want to precompute position on node save, maybe I can insert a hook or two to facilitate. Then, Composite Layout will, by default, not store the position in the database (which suits me), but you can write some custom code to do this (so it only affects your site).

2) Reducing the time required to compute position on node view.

I had a thought ... we can get the database to sort by weight when loading items. Around line 632 of composite.module, change the db_query() from:

  $result = db_query("SELECT type, weight, id, data, zone FROM {node_composite_references} WHERE vid = %d", $node->vid);
  

to:

  $result = db_query("SELECT type, weight, id, data, zone FROM {node_composite_references} WHERE vid = %d ORDER BY weight", $node->vid);

Would this solve your problem, and is it acceptably fast enough?

raphael waeselynck’s picture

First, thanks for your concern :) Our team really appreciate it.
Then, to tell you the truth, when we had to determine the position of our references in each zone, our first thought was composite module has a lack of hooks for customizing the theme of a reference. That's why your first proposal seems very good as far as I am concerned, especially if you really do not want to store additional information in the database.
I am pretty sure having the ability to distinguish elements (odd-even) in a zone will be interesting anyway for everyone.
For your second sugestion, as I said, computing the position will be useful I guess, so reducing the time to compute it will help.
Why not implement both of your solutions ?

bengtan’s picture

Well, lets deal with ordering by weight first. Can you make the change suggested in comment #6 and see whether that's acceptable to you?

As for adding more hooks ... I don't mind doing so, but I don't really want to second-guess and try to predict what hooks people will use or not use. If you need to do a particular thing, and can think of suitable hooks in Composite Layout that will facilitate, then please let me know and I'll consider them.

sdelbosc’s picture

Raphael and I belong to the same team. He will soon suggest a patch based on post #2 and second option of post#6.

sdelbosc’s picture

An undesired second click on save. Sorry.

bengtan’s picture

Hi,

Please be aware that is a potential patch from #817302: More theme subsection code encapsulation, and zone template which may impact your code and may require a re-roll of any patch. I'm not expecting any conflicts (hopfully) but just something to keep an eye on.

Thanks.

bengtan’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

Expiring this issue as it is old and uncertain whether it is still applicable.