I've just been thinking about ways to 'theme' the relativity links UI. I love the logic - just wanted to tweak the layout a bit.

here's a couple of crap illustrations:

eg with all perms:

node body  ...

  RELATED CHILD1s                            (remove)
+---------+----------------------------------+-----+
| child1a   data ...                           [X] |
| child1b   data ...                           [X] |
| child1c   data ...                           [X] |
+---------+----------------------------------+-----+
[create new Child1] [attach old Child1]           

RELATED CHILD2s                            (remove)
+---------+----------------------------------+-----+
| child2a   data ...                           [X] |
| child2b   data ...                           [X] |
| child2c   data ...                           [X] |
| child2d   data ...                           [X] |
+---------+----------------------------------+-----+        
 [create new Child2] [attach old Child2]   

eg with only create_Child2_perms

node body ...

 RELATED CHILD1s                            
+---------+----------------------------------------+
| child1a     data ...                             | 
| child1b     data ...                             |
| child1c     data ...                             | 
+---------+----------------------------------------+

 RELATED CHILD2s                          
+---------+----------------------------------------+
| child2a     data ...                             |
| child2b     data ...                             |
| child2c     data ...                             |
| child2d     data ...                             |
+---------+----------------------------------------+
 [create new Child2] [attach old Child2]          

My plan is :

1- embed a Page View (table) for each of the child node types (allowing me to pull in other node data fields).
* done (I think) see #13 in http://drupal.org/node/82415.
* a Block_View shouldn't be a very easy variation ...

2- display the 'remove ...' operator_links in a column in the view_table
* operator_link = 'relativity/unparent/$parent_nid/$nid'.
* Create a field_disown_child for Views ? by adding some functions to relativity_views.inc ?

3- apply user_permission_display rules to the whole 'remove ...' column.
* Not a clue. Even after staring numbly at the theme_functions in module and robert's patch (http://drupal.org/node/121207)

4- display 'create new ...' and 'attach existing ...' operator_links below each appropriate view_table.
* Well, I sort of hacked this in a PHPtemplate, but this bypasses the user-display-permissions thing :(

Please can anyone provide any pointers / advice?
many thanks, J

Comments

JohnG-1’s picture

Status: Active » Needs review

problems 2 & 3 completed! I hacked a (Node: Edit) function from views.module and spliced it into darius' relativity_views.inc. What this does :

It creates a views_field containing a 'Remove' link per node that severs the bond between the relevant child node and the current_view parent. (ie a 'themeable' remove_child link)

* In view/edit, add a 'Relativity: Parent Title' to your Fields list,
* Set the field's Handler option to 'Remove Link' (yes I know it's a rather ambiguous label ... suggestions welcome).
* The link is permission checked before it is displayed :)(code copied from "function views_handler_node_edit" in views.module v 1.166.2.6 2007/01/21 21:03:37 merlinofchaos)

patch: I can't write proper patch files but there are only 2 changes to relativity_views.inc:

First, find the handler array and insert the extra handler thus (note you can change the label here :)

        'handler' => array(
          'views_handler_field_relativity_parent_title'    => t('As Link'),
          'views_handler_field_relativity_parent_title_nl' => t('Without Link'),
          'views_handler_field_relativity_parent_title_remove' => t('Remove Link'),                // added this line 
        ),

Second, add this whole new function at the end of the inc file, after the other functions :

// add this whole function :
function views_handler_field_relativity_parent_title_remove($fieldinfo, $fielddata, $value, $data) {        
  $data->type = $data->node_type;
  $data->uid = $data->node_uid;
  if (node_access('update', $data)) {
    $link_text = $fielddata['options'] ? $fielddata['options'] : t('Remove');                               
    return l($link_text, "relativity/unparent/$data->relativity_parent_node_nid/$data->nid");               
  }
}
// th-th-th-that's all folks

Tested: I've tested this with :
* a View_Table embeded into the 'parent' node (via it's node-parent.tpl.php)

... Now how on earth am I going to display 'create new ...' and 'attach existing ...' operator_links below each appropriate view_table ? ... any suggestions ?

JohnG-1’s picture

Got it :)

see a demo at my sandbox site : http://oneirica.com/test_relativity/node/14

First: make sure you apply the previous #1 patch to relativity_views.inc - or you'll lose the 'Remove child' links altogether ;)

Second: you will need to make a separate View for each content type involved in the relativity system, and name it 'childview_$type' (where $type is the name of the content type) - or you'll get 'foreach()...' errors if it can't find the view. The childviews need to be set up like this:

I'm going to use Folicle as an example node type so you can see how the labels work.

  1. Name -> "childview_Folicle"
  2. Provide Page View -> "yes" (checked)
  3. View Type -> "Table View"
  4. Use Pager -> "no" (unchecked)
  5. Nodes Per Page: -> "0" (zero = unlimited)
  6. add Field 'Node: Title' and label it 'Folicles'
  7. add Field 'Relativity: Parent Title' and select 'Remove Link' as the handler.
  8. add other fields if you like, and play with the sort order etc.
  9. add Argument 'Relativity: Parent Node ID' and set to 'Display All Values'
  10. add Filter 'Node: Type' and set it to 'Is one of' and 'Folicle'

and that's it!

now save this view and clone it. Edit each clone, changing all 3 occurances of Folicle to the name of the next node type;

  1. change Name "childview_Folicle"
  2. change Field 'Node: Title' label 'Folicles'
  3. change Filter 'Node: Type' to 'Is one of' 'Folicle'

Third: Add this one-drop patch to your template.php (ie it only works with PHPtemplate themes - only tested on Garland 5.1). All it does is 'change' 2 Relativity theme functions: theme_relativity_show_children and theme_relativity_links. it doesn't touch parents or ancestor links...

/**
* Template Relativity to insert Views of related nodes.
* in Views you MUST:
* create a table childview_$type for each CCK type,
* and ensure each one has :
* 1. a 'Node: Type' filter and
* 2. a 'Relativity: Parent Title' argument.
* Otherwise you will get errors from views module like:
* "warning: Invalid argument supplied for foreach() ..."
*/

// Catch function : theme_relativity_show_children
function phptemplate_relativity_show_children($node, $fieldset=1) {
$output = '';
return $output;
}

/**
* This function themes the output of the $types array. It should
* print a list of links to attach a node.
*/
function phptemplate_relativity_links($types, $parent, $op='view') {
global $current_view;
$current_view->args[0]=$parent->nid;
$output = '';
$parent_nid = $parent->nid;

// remove "default" type
if (is_array($types)) {
$keys = array_keys($types, "default");
if (count($keys))
unset($types[$keys[0]]);
}

if (!is_array($types) || count($types) == 0 || !$parent_nid) {
return;
}

$types = relativity_sort_types($types);

foreach($types as $type) {
if (relativity_may_add_child($parent_nid, $type)) {
$type_name = node_get_types('name',$type);
if (!$type_name) {
$type_name = $type;
}

$childview = views_get_view('childview_' . $type);
// $output .= '' . t('children of type: ' . $type) . '';
$output .= views_build_view('embed', $childview, $current_view->args, false, false);

$may_create = relativity_may_attach_new_child_type($parent->type, $type);

// only offer to let user create new child if user has 'create' access
// and common child relationship isn't required
if ($may_create && node_access('update', $parent)) {
$output .= l(t('create new !type', array('!type'=>$type_name)), "node/add/$type/parent/$parent_nid");
}

// only show link to attach existing node when the potential child doesn't require a parent.
if ((!relativity_requires_parent($type) || relativity_multi_parent($type)) && node_access('update', $parent)) {
// Use 'create' privilege to change up the link text
if ($may_create) {
$ltitle = t('attach existing !type', array('!type'=>$type_name));
}
else {
$ltitle = t('attach !type', array('!type'=>$type_name));
}
$output .= ' | ' . l($ltitle, "relativity/listnodes/$type/parent/$parent_nid") . "\n";
}
}
}
return $output;

whew!

next I'll start on the 'Parent nodes' links to see if we can't make a pager ... ;)

JohnG-1’s picture

oops i missed the close bracket off the above patch function :P

at the end it should read:

...
}
}
}
return $output;
}

sorry about that

JohnG-1’s picture

StatusFileSize
new2.5 KB

I've added a couple of error checks for more harmless integration of the theme code that goes at the end of your template.php.

1. theme code now checks that views.module is installed and active, if not it skips the phptemplate_theme functions, allowing relativity to use it's normal theme_functions.

2. if a childview_$type is missing or misnamed (ie if you haven't set up a childview_* for a particular node type), you get a helpful, inline error message rather than the views errors you used to get :)

3. the patch for relativity_views inc (above) is still current, and you will need it to provide the 'remove' links for detaching children to your childview_*

so now it's just alot more friendly ... if it can't find the bits it needs, it doesn't fall over :)

there's a full demo and some notes on my testsite : http://oneirica.com/test_relativity/node/14

feedback most welcome.

owahab’s picture

StatusFileSize
new4.52 KB

I actually thought about this in a different way: why not allow relativity to render children of type "foo" using a view created with views module. This allows for enormous flexibility.
I have just finished writing the code and I tested a little bit.
Feedback is welcome.

JohnG-1’s picture

#5 : relativity_3.patch: Omar - you beauty!!! This is a huge improvement! I had also been thinking about how to build the views option into the display options, but I wasn't really sure where to start - but you've done it for me with perfect timing too :) Thank you !!!!

OK so I have applied relativity_3.patch to a clean $Id: relativity.module,v 1.36.2.1 2007/02/10 05:20:27 darius Exp $, using an unpatched relativity_views.inc. Have I got that right? or should relativity_3.patch go on top of other patches? Anyway, here are my observations of the relativity_3.patch only results (where '@' = good new feature, '+' = problem):

Views integration
@ This patch to relativity.module creates new Rendering option for children nodes of type ... , to display children as a View - it even gives you a list of your views to choose from.
@ It displays a separate list or table of child-nodes for each node-type.
+ When applied to a Full Nodes or Teaser List View it's not very happy ;) (but I can't think of a reason to use these options anyway ;)
@ When applied to a Calendar View it plays quite nicely ... :)

Link Operations
@ When applied with a Table or List View it also displays a field containing Remove links for each child, and Create new ... link nicely below the table.
+ Neither these new Remove links nor their containing field are permission checked ... everyone has access to the Remove links.
+ Restricting the View Permission (admin/build/views/#child_view) does not hide the #child_view from unauthorised users at all.
+ When applied with a Table or List View it does not hide the Link Operations fieldset, duplicating the Remove Create new ...and links.

Views Arguments
+ (First) View Argument Handler set to Relativity: Parent Node ID (display all values) does not filter the list. I assume this is because the parent node is not passing its parent_nid to the embedded view.
+ (Second) View Argument Handler set to Node: Type (display all values) ... as relativity_3.patch builds a view for each child node-type, it would be useful to pass the node-type as an argument as well.
+ My guess is the following code should go at the top of the function theme_relativity_links (but that isn't working for me ... )

    global $current_view;
    $current_view->args[0]=$parent->nid;
//    $current_view->args[1]=$nodetype;      //not sure if $nodetype is the right variable to use here ... ?

I'll keep tinkering with this, but in the mean time any pointers are most welcome :)

owahab’s picture

StatusFileSize
new5.71 KB

I didn't think anyone will like the patch to that extent, anyways I have made some fixes for some issues you mentioned since they were known bugs for me.
I have fixed the following with the last patch:
- Permission check for Remove and Attach links.
- Commented out the original Attach/Remove code to show links once.
- Added the parent node type as the second parameter.
- Added the child node type as third parameter.

And the following bug was found in views module:
- Views can't handle sorting when more than one view are rendered in the same page so you end up with disabling sorting in your embeded views.

JohnG-1’s picture

Omar you continue to make drupal slightly less infuriating ;)
This patch is superb - thank you!

I did struggle to configure the view argument handlers - I almost doubted your genius ;)
But I've cracked it now :) This is how I explained it to myself ...

<?php
// send the current_node's NID as $view_args(0)
	$view_args = array($node->nid);
/** so set the first view Argument Handler to 
  * [Relativity: Parent Node ID] - [Display All Values]
  * so only children of the current node are listed.
  */ 
// send the current_node's TYPE as $view_args(1) 
	$view_args[] = $node->type;
/** so set the second view Argument Handler to 
  * [Node: Type] -[Return Page Not Found]
  * so a view Filter [Node: Type] can select which 
  * child_type_tables are displayed. (returns the 
  * view 'Empty text' for unselected child_types)
  */ 
// send the child_table's TYPE as $view_args(2) 
	$view_args[] = $nodetype;
/** so set the third view Argument Handler to 
  * [Node: Type] - [Display All Values]
  * so it displays only children whose TYPE
  * corresponds to child_table_TYPE.  
  */
?>

I'm working on a generic Relativity_children view which could be rolled into the module / patch as a default view.
It's delayed because I haven't got the Argument Handling Code for the Block View working. Page View works fine :)

JohnG-1’s picture

Status: Needs review » Closed (fixed)

Omar's patch (which now has a thread of it's own http://drupal.org/node/130870) is definitely a better approach than most of the stuff on this thread, so I'm to close this issue and relegate it to history.
I hope nobody minds. ... and a huge thank you to Omar :)

jlalvarezmedina’s picture

Title: how to theme relativity link operations using Views ? » an alternative solution

I've been trying hard to apply the different patches I saw, with no success :(

So I tried to solve the problem on my own. And I found a way around :)

I took the official 2.x version, and I did the following modifications:

I un-commented the following block in relativity.module

/*
// the $view will maintain its field contents, so I wanna make sure
// I will add the extra field only once..
static $fields_count;
$fields_count = count($view->field);
$view->field[$fields_count] = array(
'vid' => count($view->field),
'tablename' => 'node',
'field' => 'nid',
'label' => '',
'handler' => 'relativity_handle_view_links',
'sortable' => 0,
'defaultsort' => 0,
'fullname' => 'node.nid',
'queryname' => 'node_nid',
);
*/

Then, I changed the function relativity_handle_view_links in the same module, by replacing the $parent variable, in this case, meaning the parent node ID (it was being obtained directly from the relativity table starting from a child node ID, but this is wrong as a single node may have many different parents) and took it from the right parent. So I took it from a safe place: the URL :)

function relativity_handle_view_links(&$field, &$view, $nid, &$node){
$parent_nid = arg(1);
if (relativity_may_unchild(node_load($parent_nid), $node)) {
return l(t('remove'), 'relativity/unparent/'. $parent_nid .'/' . $node->nid);
}
}

with this two small changes, I solved it. Now I can remove the "link operation" block, or at least the ugly "remove" links on it

jlalvarezmedina’s picture

Title: an alternative solution » how to theme relativity link operations using Views ?

If someone knows about some problem that could emerge from this changes, please let me know