开发者

Drupal : how to sort and display nodes grouping by first letter in view

I have a huge list of compan开发者_开发知识库ies (nodetype : company, only field is title) that I want to display in a nice way groupping them by first letter like a dictionnary like this :

A
Abc company
Alot of work company

B
Beautiful company
Best company

Trying to find a way to do it in an elegent way; no module seems to exist for that. Any idea ?


You don't really need to go down the code path to achieve this. You can see some of this described here: http://drupal.org/node/641342

Basically, add the node title to the view twice. The first is your normal field with links, etc. The second one is for the grouping.

The second field you mark to exclude from display, remove the label, and trim the field to a maximum length of 1 (uncheck the word boundary, ellipsis, and html options).

Then, under the "row style" options you'll find the "group by" setting, and you just select the second node title field.

You may need to apply additional theming if you want to have it look a certain way or possibly adding anchors for each letter, but otherwise that should work for version 6 of Drupal with views 2 module

Also, I should point out the group by module http://drupal.org/project/views_groupby which can offer some additional functionality but which isn't really needed for the original question.


Take a look at the Views module, which provides a view called "Glossary". That sorts content alphabetically, and creates a letter index of sorts. Also take a look at http://drupal.org/node/441024 though it's possible she used the Glossary module. There's also a module called Dictionary (demo).


To do what you want to do using Views, and not some other contributed module, like Glossary, you'll have to define and theme your own view.

First, you'll need to create a new node View. I'm going to call it myglossary, but it doesn't matter. Make sure that one of your fields is the node title, and that it's sorted by node title, ascending. In other words, alphabetical order. I'm assuming you'll be using the unformatted row style (it's default), but you can probably do something similar with the other row styles.

Then, you'll have to get into your theme. From the views/theme folder, copy the views-view-unformatted.tpl.php template into the folder of the theme you're using. Rename it to views-view-unformatted--myglossary.tpl.php so it will only be used for this view. Then, open up your theme's template.php file, and add a preprocess function:

//Change mytheme to your theme name
function mytheme_preprocess_views_view_unformatted__myglossary(&$vars) {
  //If you have the devel module installed,
  //this is a great way to see all the available variables
  //dpm($vars);

  $results = $vars['view']->result;
  $rows = $vars['rows'];

  //Sort rows into letter sets
  $letters = array();
  $i = 0;
  foreach ($results as $result) {
    $first_letter = strtolower(substr($result->node_title, 0, 1));
    if (is_array($letters[$first_letter])) {
      array_push($letters[$first_letter], $rows[$i]);
    }
    else {
      $letters[$first_letter] = array($rows[$i]);
    }
    $i++;
  }

  //Generate glossary navigation
  $nav = '';
  foreach($letters as $letter => $rows) {
    $num = count($rows);
    $cap_letter = strtoupper($letter);
    $nav .= <<<NAV
<a href="#$letter" class="letter_link">
  $cap_letter
</a>
($num)
NAV;
  }

  //Add to variables
  $vars['nav'] = $nav;
  $vars['letters'] = $letters;
}

Then, you'll have to change the template file you copied over earlier to add in the navigation, and to output the rows in a glossary style:

<?php if (!empty($title)): ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>

<?php if (!empty($nav)): ?>
  <div id="glossary_nav">
    <?php print $nav; ?>
  </div>
<?php endif; ?>

<?php foreach ($letters as $letter=>$rows): ?>
  <a name="<?php print $letter ?>"></a>
  <h4 class="letter">
    <?php print strtoupper($letter); ?>
  </h4>
  <?php foreach ($rows as $id=>$row): ?>
   <div class="<?php print $classes[$id]; ?>">
    <?php print $row; ?>
   </div>
  <?php endforeach;?>
<?php endforeach; ?>

You might need to regenerate the theme registry to have your changes show up on your site.


The module Views grouping Limit may get you where want to go.


If you use the Views module, have you tried using a preprocess method in the template? You wouldn't be returning the data from your datasource in that fashion but you could sort it by any arbitrary method you wanted to once it was returned, it would look something like this:

function templatename_preprocess_views_view__All_Images(&$vars)
{
    global $base_url;
$images = array();
//drupal_add_js('$("a.colorbox").colorbox();','inline');
foreach($vars['view']->result as $img)
{
    $nid = $img->nid;
    $node = node_load($nid);
    $images[$nid]['orig_img_url'] = $base_url . '/' . file_create_path($node->images['_original']);
    $images[$nid]['thumb_img_url'] = $base_url . '/' . file_create_path($node->images['thumbnail']);
}
$vars['images'] = $images;

}

That way you could sort by first letter and make changes to the array and it would get sent out to your view in the fashion you desire. This is an example I made for image paths but you could use PHP's variety of sorting methods to get the sorting you require.


this can be done simply by views. I did it for making a similar list for a taxonomy:

  1. I made a simple list of all taxonomy terms i.e. term name as field.
  2. Then I added the taxonomy term field again but this time I used it to get the first name of term i.e. set rewrite output->limit number of characters->true. and set limit to 1. Also exclude this field from display.
  3. Now go to Format->settings and use the single character field for grouping. In the end sort the results with taxonomy term filter.


You can achiev similar functionality by creating a view with AZ filter (or you could alter that code). I wrote a post about this issue at my blog. Hope it helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜