Twould be nice if build modes were added to the options for the node row style. Then, depending on your view, CCK would load various fields based on your build_mode. This would allow other modules to declare build modes using CCK's hook_content_build_modes which would in turn display those build modes within the node row style options as radios. Then a user can select what fields show up based on that build mode within CCK, and select that same build mode within Views.

I tried to search for a previous feature request for this, so my apologies if this is already in the queue somewhere.

I'm sure I don't understand the complexity of this feature request, but attached is my simple crack at it.

Comments

yched’s picture

Title: Add build modes to node plugin row styles » Use CCK-exposed build modes in node row styles
StatusFileSize
new3.04 KB

I didn't notice this thread before taking my own stab at it.
The attached patch takes a slightly different road : it moves away from the previous 'teaser' checkbox to a 'build mode' dropdown select, whether CCK is enabled or not. It includes minimally intrusive code to account for backwards compatibility with existing views that haven't been updated and still come up with the 'teaser' setting..

In preparation of this patch, CCK has defined a 'views style' property to be used by hook_content_build_modes(). Only build modes with 'views style' = TRUE are taken into account here.
Note that all the build modes that CCK itself exposes (on behalf on core) use 'views style' = FALSE (except teaser and full). So in order to actually see test the patch, you probably need to manually change 'views style' to TRUE in content.modules's search_content_build_modes() , for instance for NODE_BUILD_SEARCH_RESULT (which, now that I think of it, would probably make sense anyway...)

q0rban’s picture

I like how you're handling views_plugin_row_node_view.inc much better than mine (I hadn't thought about handling older views), but I'm not sure I understand why you're overriding the build mode the way you are in node.views.inc:

<?php
  // Handle existing views with deprecated 'teaser' option.
  if (isset($options['teaser'])) {
    $teaser = $options['teaser'];
    $build_mode = NODE_BUILD_NORMAL;
  }
  else {
    $teaser = $options['build_mode'] == 'teaser' ? TRUE : FALSE;
    $build_mode = ($options['build_mode'] == 'teaser' || $options['build_mode'] == 'full') ? NODE_BUILD_NORMAL : $options['build_mode'];
  }
  $node->build_mode = $build_mode;
?>

What about this?

<?php
  // Handle existing views with deprecated 'teaser' option.
  if (isset($options['teaser'])) {
    $teaser = $options['teaser'];
  }
  else {
    $teaser = $options['build_mode'] == 'teaser' ? TRUE : FALSE;
    $node->build_mode = ($options['build_mode'] == 'teaser' || $options['build_mode'] == 'full') ? NODE_BUILD_NORMAL : $options['build_mode'];
  }
?>

That way if $options['build_mode'] isn't set, $node->build_mode isn't touched (in case another module was overriding it)..

q0rban’s picture

Actually, I think we could consolidate that even more:

<?php
   if (empty($node)) {
     return;
   }

  // Handle CCK build modes.
  if (!isset($options['teaser']) {
    $options['teaser'] = ($options['build_mode'] == 'teaser');
    $node->build_mode = ($options['build_mode'] == 'teaser' || $options['build_mode'] == 'full') ? NODE_BUILD_NORMAL : $options['build_mode'];
  }

  $vars['node'] = node_view($node, $options['teaser'], FALSE, $options['links']);

?>

Also, seems to make sense to move empty($node) above our teaser handling stuff.

q0rban’s picture

StatusFileSize
new2.39 KB

Take 2..

yched’s picture

Status: Needs work » Needs review
StatusFileSize
new3.07 KB

re #2 :
A node should have a build_mode set before being rendered. All nodes rendered in core have a build_mode.
"that way $node->build_mode isn't touched (in case another module was overriding it)"
Makes no sense, there's no build mode set for a node coming out of node_load(), so there's nothing to touch or override.
The node workflow is : load a node, set a build_mode, render it. That's it.

re #3 : The point is to deprecate $options['teaser'], and make $options['build_mode'] the new official setting. The code you propose blurs the line. Actually, the attached patch makes the distinction a little clearer (translate the old setting into the new one if needed, then handle the setting in its unique new form)

So, patch rerolled, sticking to the approach in #1.

Tested to work and not break existing views:
- applied the patch, run an existing view use 'teaser' node row style: still displays teasers.
- edit the view, just resave as is: still displays teasers, without going through the 'compatibility' code branch.

q0rban’s picture

Makes no sense, there's no build mode set for a node coming out of node_load(), so there's nothing to touch or override.
The node workflow is : load a node, set a build_mode, render it. That's it.

My point is that a contrib module, using hook_load(), or nodeapi with $op = load, could have set a build mode for it's own specific purposes. I don't think views should necessarily respect that, but the possibility is there nonetheless....

Also,
Your code:

<?php
  $teaser = $options['build_mode'] == 'teaser' ? TRUE : FALSE;
?>

Why not this?

<?php
  $teaser = ($options['build_mode'] == 'teaser');
?>
yched’s picture

StatusFileSize
new3.4 KB

Yes, I did get your point, and the answer is that build_mode should *not* be set at load time. Period. That's a render property. No point in encouraging or allowing this. Core doesn't.

You're right about the code simplification. Rerolled.

merlinofchaos’s picture

1) Let's handle conversion from $options['teaser'] to $options['build_mode'] in init() -- that way that conversation happens in one place and one place only.

2) I hate module_exists. Let's use module_invoke('content', 'build_modes'). Yes this is effectively the same thing, but the code is a little cleaner. Let's put a comment that this is an explicit exception to my normal rule about relying on non-core modules directly as well.

3) Should this retool RSS as well? It's not clear to me if that's necessary.

yched’s picture

1) will try that.

2) module_invoke('content', 'build_modes') is not an actual *hook* invocation, of course, but cck does define hook_content_build_modes(), so this might be a little confusing. Your call.

3) hm. Currently RSS hardcodes $node->build_mode = NODE_BUILD_RSS. We might propose that as a default, and still allow the user to change. The thing is in CCK I explicitly set the rss build mode to *not* be exposed as a mode in views, in order not to confuse users in the regular 'node' row style into thinking they're building an RSS feed :-)
We could keep it excluded in 'node', and have the rss style handler explicitly add it as a possible choice (with a word of explanation saying that if they set a different mode they'll still be building a feed) ?
Or simply keep rss as 'rss build mode' :-)

merlinofchaos’s picture

Or we could do RSS specific build modes. I think that's your call, though.

yched’s picture

StatusFileSize
new3.21 KB

New patch addresses points 1 and 2 in comment #8.

I'd rather leave out the case of RSS row style for now, if that's OK with you. It's tricky, because RSS build mode still lets you specify 'teaser' or 'full node', which affects non CCK stuff (body, etc...), but is overlooked by CCK, that use the display settings defined for a single 'RSS' mode. Maybe CCK should expose 'RSS full' and 'RSS teaser', but I'm really not convinced it's worth the trouble.

merlinofchaos’s picture

Needs a reroll, it looks like. :/

yched’s picture

Version: 6.x-2.2 » 6.x-2.x-dev
StatusFileSize
new3.21 KB

Sure, it was bound to conflict at least with #327366: Let row plugins follow relationship.
Rerolled.

yched’s picture

Status: Needs review » Fixed

This got committed in 2.5 release

Status: Fixed » Closed (fixed)

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