How to theme the ajax views block

mdroste - January 18, 2008 - 17:48
Project:AJAX Views
Version:5.x-1.0
Component:Miscellaneous
Category:support request
Priority:normal
Assigned:febbraro
Status:active
Description

Per default a Ajax Views Block renders an item list of node titles. I would like to show other fields of my underlying view, such as the teaser and a image field. How can I achieve this?

#1

febbraro - January 22, 2008 - 19:06
Assigned to:Anonymous» febbraro

You can implement theme_views_ajax_page_item it passes a parameter $node as returned from the view. If you want more fields be sure to add them to the Fields section of the view.

#2

mdroste - January 23, 2008 - 14:47

It works. Thanks.

#3

febbraro - January 23, 2008 - 14:52
Status:active» closed

Glad it worked :-)

#4

mavimo - May 28, 2008 - 22:07

This don't work fine.
I've create a new views with page and block. Page is a list views, block is ajax views, if i go to page /demo-ajax-views I correctly see fields added into views, but if I use block, only title is aviable (also with own theming function into template.php). I hacked the ajax_views code, and find some problem; views don't return full node if $views->type = 'page', but only $node->nid object.
Let me explain, if I add a print_r into theme_views_ajax_page function I see only an array of node object similar to:

    [...] => stdClass Object
        (
            [nid] => 101
        )

not a complete node with fields. If I add this block it's called correctly and fields are correctly aviable:
    [...] => stdClass Object
        (
            [nid] => 101
            [node_title] => Ibidem Capto Euismod Caecus Vero Iriure Letalis Valde
            [node_changed] => 1211997952
            [node_comment_statistics_comment_count] => 0
            [users_name] => user1
            [users_uid] => 2
        )

Other information:

  • drupal 5.7
  • ajax_views 1.5
  • views 1.6

I'm intresting to correct this "bug", but i need collaboration, plz contat me.

Bye

#5

febbraro - May 28, 2008 - 20:34
Status:closed» active

I can help you with this, but it might be some time. I am leaving for vacation tomorrow and will return on June 10th.

#6

mavimo - May 28, 2008 - 21:50

Ok, if you can get me some input I'm starting work :D

#7

febbraro - May 29, 2008 - 17:29

The problem is that the main theme function is never "collecting" all of the fields. If you use the theme wizard, the part they tell you to put into your template.php file basically collects the values for you. To give you a push in the right direction I might suggest this 2 things.

#1 The default Page themer loads all of the nodes for you. If you need to override how a particular node is rendered, you should just be able to implement views_ajax_page_item and it will get called for each node in your view results after a call to node_load so all of you data should be around.

If that does not work, try something like the following....

In theme_views_ajax if it is a page type, take hints from the theme wizard and do something like..

$fields = _views_get_fields();

  $taken = array();

  // process & load each field.
  foreach ($view->field as $id => $field) {
    $field_name = $field['field'];
    if (isset($taken[$field_name])) {
      $field_name = $field['queryname'];
    }
    $taken[$field_name] = true;
    $node->$field_name = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
  }

I could be waaaaaaay off with what this code actually does, but basically you want to process each and every field specified on the view and load it's data and set it on the $node. Or you could simply node_load it, or build some entirely different data structure that you pass to the theme function. I think this should give you a push in the right direction, sorry I can't help more, but I could not be MORE in need of a vacation right now. :-)

I'll jump back in and help on my return. Good luck, I'll be checking emails if you have questions but not too frequently.

Frank

#8

mavimo - May 29, 2008 - 20:30

I had this solution before posting message but don't work fine. With node_load i load only main element of node, not complete node with fields & c. (similar fivestars widget, ...) I think generate it from DB is not best way for future extendibility function. If i go to correct page (not in ajax_views) I recive correct info, but into ajax_views this don't work. I'll debug the code, have a nice vacation.

Marco

#9

instromaniac - June 4, 2008 - 22:37

I had a similar problem but I think I found the solution.

First of all you're right you'll need to write your own theme_views_ajax_page_item_viewname($node) theme function. Here you can output all your node fields. If you don't exactly know how they're called do var_dump($node).

There's still one problem though. Some fields aren't rendered as they should. I had this problem with a cck content type that used fivestar and op_video fields.

The trick is making sure you call node_view first. That way all cck fields will be rendered before you're displaying them.

So what I did is calling this in my theme_views_ajax_page function for each node:
module_invoke_all('view', $current), $current being the $node you want to render.

Anyway, it would be awesome if you could make the AJAX block view type similar to a list view type, so that it will include the fields chosen in the view automatically instead of just the titles.

Besides this tiny issue it's an awesome module though :)

#10

instromaniac - June 5, 2008 - 13:48

Little update on my previous findings:

Please replace module_invoke_all('view', $current) with node_view($current) or node_view($current, TRUE).

For some reason this gave privatemsg errors.

#11

mavimo - June 7, 2008 - 17:23

No solution, but just a little update after a long time debugging; into function ajax_views_ajax_argument if I change 'ajax_views' with 'list' a complete page list occur (oks), after that i test to change, into module views, this function:

<?php
function theme_views_view_list($view, $nodes, $type) {
 
$fields = _views_get_fields();
 
$output .= '<div class="ajax_views_headers">';
 
$output .= '<div class="title">' . l($view->page_title, $view->url) . '</div>';
  if (
_has_feed_argument($view) ) {
   
$output .= '<div class="rss">' . theme_image('misc/feed.png') . '&nbsp;' . l("RSS""$view->url/feed") . '</div>';
  }
 
$output .= '<div style="clear:both;"></div>';
 
$output .= '</div>';
   
 
$output .= "<div class='ajax_views_body'>";
  if (
count($nodes)) {
    foreach (
$nodes as $node) {
     
$item = '';
      foreach (
$view->field as $field) {
        if (!isset(
$fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
          if (
$field['label']) {
           
$item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
          }
         
$item .= "<div class='view-field ". views_css_safe('view-data-'. $field['queryname']) ."'>" . views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view) . "</div>";
        }
      }
     
$items[] = "<div class='view-item ". views_css_safe('view-item-'. $view->name) ."'>$item</div>\n"; // l($node->title, "node/$node->nid");
   
}
    if (
$items) {
     
$output .= theme('item_list', $items);
    }
  } else {
   
$output .= views_get_textarea($view, 'block', 'empty');
  }
 
 
$output .= "</div>";
       
 
$output .= theme('views_ajax_block_pager', $view);
 
 
drupal_set_header('Content-Type: text/html; charset=utf-8');
  print
$output;
 
module_invoke_all('exit');
  exit;
}
?>

And content appair correctly into block, filed are correctly themed, and all it's ok, but if i copy this code into file ajax_viers.module, into function theme_views_ajax_page don't work :|
<?php
function theme_views_ajax_page($view, $nodes, $type) {
 
$fields = _views_get_fields();
 
$output .= '<div class="ajax_views_headers">';
 
$output .= '<div class="title">' . l($view->page_title, $view->url) . '</div>';
  if (
_has_feed_argument($view) ) {
   
$output .= '<div class="rss">' . theme_image('misc/feed.png') . '&nbsp;' . l("RSS""$view->url/feed") . '</div>';
  }
 
$output .= '<div style="clear:both;"></div>';
 
$output .= '</div>';
   
 
$output .= "<div class='ajax_views_body'>";
  if (
count($nodes)) {
    foreach (
$nodes as $node) {
     
$item = '';
      foreach (
$view->field as $field) {
        if (!isset(
$fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
          if (
$field['label']) {
           
$item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
          }
         
$item .= "<div class='view-field ". views_css_safe('view-data-'. $field['queryname']) ."'>" . views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view) . "</div>";
        }
      }
     
$items[] = "<div class='view-item ". views_css_safe('view-item-'. $view->name) ."'>$item</div>\n"; // l($node->title, "node/$node->nid");
   
}
    if (
$items) {
     
$output .= theme('item_list', $items);
    }
  } else {
   
$output .= views_get_textarea($view, 'block', 'empty');
  }
 
 
$output .= "</div>";
       
 
$output .= theme('views_ajax_block_pager', $view);
 
 
drupal_set_header('Content-Type: text/html; charset=utf-8');
  print
$output;
 
module_invoke_all('exit');
  exit;
}
?>

some one can explain me why this function work if have some name and not if have another name into other file?

Bye
Mavimo

#12

mavimo - June 8, 2008 - 08:44

Some improvement:
change, into files views.module the function theme_views_view_list() to:

<?php
function theme_views_view_list($view, $nodes, $type) {
 
// Send result to add into block
 
drupal_set_header('Content-Type: text/html; charset=utf-8');
  print
theme_ajax_view_block_content($view, $nodes, $type);
 
module_invoke_all('exit');
  exit;
}
?>

this is not the good solution, but only a temporary solution!!!
After that chage your ajax_views.module with file into attchment.
Current change:

  • Using page with View Type:List view and your fields correctly appair into block
  • First page of block correctly load all CSS/JS for fields (like fivestars and similar)

next improvement

  • Removing change into views.module!
  • Completly remove first AJAX request
  • Having opportunity to use *tpl.php like Theming widzard for best content theming into block.

Bye
Mavimo

AttachmentSize
ajax_views.zip 3.71 KB

#13

asak - September 29, 2008 - 22:49

@mavimo: I've done what you described in comment #12 but have a problem:

The AJAX formatter is gone, both for the page view and the block view. the argument for ajax is still there.
Any idea where could it go... should it just disappear?

Before changing the files, I got a working AJAX pager in a block, which displayd the titles of the nodes.
Now I get an empty block.

What I want is to display a table with a pager.

#14

asak - September 29, 2008 - 22:51

The page view displays the correct list of nodes, with the fields i've selected.

The problem is with the ajax_views.module file.
I will try and see what's going on.

#15

hawk007 - November 28, 2008 - 09:07

I use these two functions in the template.php, the first is the one that creates the span of all content, the second makes each item of the view:

function theme_views_ajax_page

function theme_views_ajax_page_name_of_view($view, $nodes, $type) {
$output .= '<div class="ajax_views_headers">';
if ( _has_feed_argument($view) ) {
    $output .= '<div class="rss">' . theme_image('misc/feed.png') . '&nbsp;' . l("RSS",  "$view->url/feed") . '</div>';
}
$output .= '<div style="clear:both;"></div>';
$output .= '</div>';

$output .= "<div class='ajax_views_body'>";
if (count($nodes)) {

$function = "views_ajax_page_item";
if (!($func = theme_get_function($function . "_" . $view->name))) {
$func = theme_get_function($function);
}

$rendered_nodes = array();
foreach($nodes as $node) {
$current = node_load($node->nid);
$output .= theme_views_ajax_page_item_name_of_view($current);
}
}
else {
$output .= views_get_textarea($view, 'block', 'empty');
}
$output .= "</div>";

$output .= theme('views_ajax_block_pager', $view);

drupal_set_header('Content-Type: text/html; charset=utf-8');
print $output;
module_invoke_all('exit');
exit;
}

in this function is where I created a custom template

function theme_views_ajax_page_item

function theme_views_ajax_page_item_name_of_view($node) {
global $base_url;
$output .='<table cellspacing="0" cellpadding="0" border="0" width="100%" class="td_fons_gris"><tbody>
        <tr>
            <td align="center"><img src="'.$base_url.'/'.$node->field_imatge[0]['filepath'].'" title="'.check_plain($node->title).'" alt="'.check_plain($node->title).'" class="img_150" /></td>
        </tr>
        <tr>
            <td><span class="titol_blau_not">&nbsp;<a href="'.$base_url.'/node/'.$node->nid.'">'.check_plain($node->title).'</a></span></td>
        </tr>
        <tr>
            <td><span class="text_noticia_breu">&nbsp;'.cortarTexto($node->body,'250').'</span></td>
        </tr>
        <tr>
            <td>&nbsp;<a target="_blank" href="'.check_plain($node->field_enllas[0]['value']).'">'.check_plain($node->field_enllas[0]['value']).'</a></td>
        </tr>
</tbody></table><br/>';
return $output;
}

is very important that we take the view that the pager activated and the type page has a URL

#16

Ehud - January 18, 2009 - 12:03

Hi,

Those two functions helped me display node fields only when the call to the view was embeded in a node or as a block. it works great.
But when i embed the call to the view in the front page(page-front.tpl.php), it doesn't show. i only get the progress.gif and the view content is empty.
Please help me understand the difference (between page.tpl.php and page-front.tpl.php) and what can solve that problem.

Thanks a lot!

 
 

Drupal is a registered trademark of Dries Buytaert.