Here's my problem. First of all -- I've been tinkering around with this issue for days now -- been maybe 1 or 2 weeks I think actually. Here's my situation...

I want to add tabs to specific node types. An example. Let's say I have an "event" type (that is a content type) and I want to add "schedule" tab and "registration" tab. That's easy... You would simply configure the following in a view... OR SO I THOUGHT.

My trek started here...

(page)
Provide Page View: Yes
URL: event/$arg/overview
View Type: List View

(menu)
Provide Menu: Yes
Provide Menu as Tab: Yes
Menu Title: Overview

And obviously I would choose an argument like node id for exampe. So then following the example above I would create some more views like this...

event/$arg/overview
event/$arg/schedule
event/$arg/registration

This worked all fine and dandy until I realized something...

Event though I have my nice tabs -- how am I going to serve up a list of these events? There is no way! Why? Because of this reason -- when you create another view let's say -- to show a list of the nodes -- when you click on the nodes -- you get -- the node... NOT my nice tabbed view... The solution? If I could somehow change the url of the "node title" and re-write it -- let's stop for a moment ... I need to explain how I'm creating the list so we're not confusing each other here...

So -- let's say we have a view called "event/listing" and we apply the following filters...

(filters)
Node: Published ... Equals ... yes
Node: Type ... Is One Of ... event

Ok so if we ran that view -- we would get something like this... (we're using table view here...)

Title
Some event title
Another event title
Third event title

When you click on any of these events you're going to get a node view -- not my tabbed view -- because the url of those links would be "node/#" and my views are "event/[nid]/overview"

SO -- the solution would be to re-write the links so they will be like this...

<?PHP PRINT "event/" . $node->nid . "/overview"; ?>

But the question is -- how do you change the links of your view? Theme the view? I have no idea how to theme the view -- and I am HIGHLY suspicious that it would not accomplish what we're looking to do here... I need to be able to get at the code of the view to do what you can do with for example node.tpl.php ...

If you've read this far -- maybe I should pay you -- lol -- via paypal or something! Anyways -- If you know the solution I will thank you indeed and maybe we'll talk PayPal -- lol!

Comments

GreenLED’s picture

Anybody heave some ideas????

» Respectfully, GreenLED
» Stable Files . net

vm’s picture

crossposted node removed. Please refrain from crossposting.

_____________________________________________________________________
My posts & comments are usually dripping with sarcasm.
If you ask nicely I'll give you a towel : )

GreenLED’s picture

Trying to get some attention. No responses as of yet -- only yours. However, I should have not double posted -- sorry.

Do you have any answers to this question?

» Respectfully, GreenLED
» Stable Files . net

jfall’s picture

I think this may solve your problem... this is totally untested code, but I think the idea will work as I've done something similar:

I am assuming you are using a phptemplate theme and that in your theme folder, your node.tpl.php file has a line like:

<?php if ($page == 0): ?>
  <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
<?php endif; ?>

Notice that $node_url contains the offending URL - we need to change this for your event-type nodes only.
Look in your theme for a file named template.php - if there is not one, create it and put: <?php
at the top.
You need to add to this function:
function _phptemplate_variables($hook, $vars = array())
if it doesn't exist yet, add it.

Here's the snippet you need (or something similar in any case):

       // This snippet will override the URL for a node... 
       //   from "node/[nid]" to "[node-type]/[nid]/overview"
       $override_types = array('event');  // add more node types here
       if (in_array($node->type, $override_types)) {
         $node_url = '/' . $node->type . '/' . $node->nid . '/overview';
       }

So, the complete package (assuming this is a new template.php file, otherwise you need to add these things in the right place):

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    case 'node':
       // This snippet will override the URL for a node... 
       //   from "node/[nid]" to "[node-type]/[nid]/overview"
       $override_types = array('event');  // add more node types here if you like
       if (in_array($node->type, $override_types)) {
         $node_url = '/' . $node->type . '/' . $node->nid . '/overview';
       }
    break;
  }
  return $vars;
}

(Note: no closing ?> php tag in file is not a typo)

This could easily be generalized further, but should hopefully be what you are looking for? Please report back.

GreenLED’s picture

I have just seen this -- and didn't think anyone would answer me... I think you've hit the nail on the head. I have not tested it yet, but you can be sure I will test it later on 2nite. Thank you very much for putting effort into it. What you've got down looks exactly like what needs to take place -- I will report back once I have tried it. Thanks man -- thanks a lot!! Seriously. This has been the thorniest place I've stumbled acrossed in Drupal so far -- Think this will work. See you on the other side of the problem. l9r.

jfall’s picture

Once you've got it working, how about cobbling together the bits and pieces here to create a tutorial for others? A child-page of the Views Snippets? http://drupal.org/node/47412

GreenLED’s picture

That's a great idea -- I'll take you up on that. I'm going to be testing this real shortly here this morning. Will get back to you.

» Respectfully, GreenLED
» Stable Files . net

GreenLED’s picture

Something is not quite working. I am able to customize the "Teaser" link manually by simply replacing...

<?PHP IF ($page == 0) { ?>
<H2 CLASS="title"><A HREF="
<?PHP print $node_url?>
"><?PHP print $title ?></A>
</H2><?PHP }; ?>

to...

<?PHP IF ($page == 0) { ?>
<H2 CLASS="title">
<A HREF="
<?PHP print "event/" . $node->nid . "/overview"; ?>
"><?PHP print $title ?></A>
</H2><?PHP }; ?>

However, the function you provided in template.php would cover all instances of the node url -- is that right? That's the one I cannot get to work. See if you can accomplish this on a local install you have or something -- something is not quite working. I do have a php-template by the way. Let me know if you are able to do it. So far all I can do is change the url for the teaser -- but that doesn't get me all the way because I have to have that same node url changed in every instance -- i.e. when I have a listing of nodes in a table (in a view of course). I'm going to keep trying -- let me know.

» Respectfully, GreenLED
» Stable Files . net

GreenLED’s picture

Question: I need to be able to test whether or not this function that you've given me is actually being processed in template.php. I have a feeling that the function is not working or is not outputting. In an attempt to test whether or not the funciton was actually processing, the following code was put into node.php

<?PHP PRINT $override_types; ?>

This is to see whether that variable actually exists at the node level. Is this the right method. The output was nothing. The output did not show a single thing, so my suspicoun is that something is not getting processed. Any ideas? How can I run some tests to make sure that this function is actually running.

Also... I already have a _phptemplate_variables in my template.php file which is used to prevent "crashes" on my server from a custom login script I have. Should I just "add" this snippet to that function instead of creating another one in the file .. aparently it does not like it when you have 2 of these function in one file. I get the error "cannot re-decalre..." etc. This is secondary though -- I just want to focus on getting the script working first. Hope this helps will get us farther -- I actually have a deadline today and I am hoping I can get this work real soon. Thanks for al your effort -- it is HIGHLY appreciated.

jfall’s picture

OK...

Should I just "add" this snippet to that function instead of creating another one

YES. you cannot re-define the same function twice, so you need to integrate the snippet into your existing _phptemplate_varialbes function

However, the function you provided in template.php would cover all instances of the node url -- is that right?

Yes and No. Your solution of printing the url override directly in node.tpl.php will work just fine - but it will do it for all node types, not just events, so now all nodes will link to "/event/[nid]/overview".
What my code (attempts to) do is fix the $node_url variable for only node types you want. I have set it up to do 'event' node types (please ensure your node type really is named 'event' - that's the machine name), but it could also do, say, a 'news' type, substituting the url to "/news/[nid]/overview".

However - you are right - there IS a bug in my code. The variables that are sent to the tpl are stored in the $vars array - so here's a (hopefully) fixed version:

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    case 'page':
       // stuff to set up variables for page.tpl.php
    case 'node':
       $node = $vars['node'];
       // stuff to set up variables for node.tpl.php

       // This snippet will override the URL for a node...
       //   from "node/[nid]" to "[node-type]/[nid]/overview"
       $override_types = array('event');  // add more node types here if you like
       if (in_array($node->type, $override_types)) {
         $node->path = '/' . $node->type . '/' . $node->nid . '/overview';
         $vars['node_url'] = $node->path;
       }
    break;
  }
  return $vars;
}

Sorry about that - I tested this version quickly and it seems to work.

but that doesn't get me all the way because I have to have that same node url changed in every instance

Hmmmm. View tables and lists are created by a function in Views - I'd have to look at that code to see how to override the default behaviour...
Also - check the "page" title link when a node is shown in Full view - Drupal does some funky stuff with the title in that case (thus the if ($page==0) bit around the title handling in node.tpl.php)

Question: I need to be able to test whether or not this function that you've given me is actually being processed in template.php.

What you tried there won't work (for the same reasons the code I gave you didn't ;-) If you want to see if the script is being executed, put the following statement just above the break;:
print 'Processing Node type: ' . $node->type . ' URL=' . $node->path;

If you are curious about what your node looks like after processing, put this just before the break;:
print '<pre>'; print_r($node); print '</pre>';
But only look at a page with one node or teaser, or it will generate too much output...

Anyhow - for the time being, get the script working and I'll see if I can pull out some time today to look at overriding the List and Table views...

GreenLED’s picture

Good stuff. Been F5'ing waiting for your response, lol. (hopefully you're a windows user) I will go ahead and test this puppy out. Also, I think when we will put this into a page for others -- you should adjust the commenting in your line that says you can add more content types here -- so that it reads something like "Add more content types here ... format (format to use)" Just as a handy reference. It will make it much easier to add in those other types into the array. Cheers, see you soon.

jfall’s picture

hopefully you're a windows user

What a terrible thing to wish on someone 8D - I am, but unwillingly....
good luck.

GreenLED’s picture

*snickering* Yes, Bill has driven me mad many times with his "Easy" operating system, but you know -- it's really hard to argue when he owns 95% of the industry. The other 5 or so percent -- well that's just the rebels -- and you always will have them :) I wish that MS Word was Linux compatible -- cuz then I'd switch to Linux for good, oh but one other problem -- everyone I help uses Windows, darn ... freedom was so close, but still "no cigar"

» Respectfully, GreenLED
» Stable Files . net

jfall’s picture

This is not trivial (to paraphrase the Views developer...)

There is a VERY good handbook on theming your views:
http://drupal.org/node/42597

I think you'd be looking at overriding:

function theme_views_handle_field_TABLENAME_FIELDNAME($fields, $field, $data);

to override the title field.

This would take some investigation and I still have some outstanding questions about how to do this.

When I first saw your post my initial reaction was to use URL aliases to do the job. This requires 'clean urls' (i.e., mod_rewrite in Apache)... but it's not obvious to me how you can create a re-write rule for just one node type that incorporates the node id. Hmmmm.
It might be possible with pathauto?

Both of these potential solutions are worth considering. I remain convinced that what you are trying to do is possible, but will require some r&d, so not today!

I'll check back a little later to see how you are faring.

GreenLED’s picture

IT WORKS! Been lazy -- haven't tried it until tonight. I should be ashamed of myself after you went to all that trouble -- sorry about that. Anyhow -- the code works great -- this is the solution for sure! Thanks a million. Especially for adding that "page" note to add those functions that are separate (in that function I mean). I'll write more later. Now, I want to tweak the code and see if it does perform on all fronts (that is whether it will work with views, etc.). Thanks again man!

GreenLED’s picture

False victory -- A further look reveals that it looks like it only is affecting the teaser link. This was brought to my attention by the fact that when I pull up the "Recent Posts" view it still links up as "node/" We need to take a look at theming. Unfortunately I know next to nothing about that -- I'll need help with that. What should we do from here?

» Respectfully, GreenLED
» Stable Files . net

mooffie’s picture

want to add tabs to specific node types. An example. Let's say I have an "event" type
[...]
URL: event/$arg/overview

If I understand your question correctly, and it's very likely that I don't, then all you have to do is change the URL to 'node/$node-event/overview'. Explanation:

  • 'node/$arg/overview' puts a tab on all URLs of the form 'node/something[/...]'.
  • 'node/$node/overview' puts a tab on all URLs of the form 'node/123245[/...], where the number is a valid node ID.
  • 'node/$node-story/overview' puts a tab all nodes of type story (it's an undocumented feature).
jfall’s picture

That is OUTRAGEOUSLY COOL!

That should definitely be documented - any advice on the best place to write it up?

I think that should solve your issue Green - unless what you were trying to do was to break up a single, large node's fields onto several tabs. If that was the plan, I'd recommend using Jquery JS Tabs instead, as it will look MUCH faster to your users and reduce load on your server (because you won't run as many queries). (Although moofie's suggestion will work, but the node will appear in all it's glory, with parts of the data repeated on each tab.)

If this really is a set of separate views, then you don't need the "overview" tab anymore - that is just your basic full node view. And you can add the schedule, etc. tabs using the method above. You don't need to worry about the URL anymore, because the node lives "at home" now!

Thanks moofie - Views just never cease to amaze me!

GreenLED’s picture

*snickering very loudly* oh you guys crack me up, *smiles* I've been through all of that before. Yes, it is "OUTRAGEOUSLY COOL!" to add tabs to nodes -- but that is not the issue here. Granted -- adding tabs to nodes, I actually figured that out without the help of this site... it was a video tutorial that showed me how to create tabs in an other fashion, and I implemented what I learned and did that tab thing with nodes... but... I digress...

What I mean to say is -- yes that's very neat how you can do that, but it doesn't solve the problem because you can't add node tabs to JUST one specific content type --- follow? You can't just say ...

Ok, for node/123 I'm doing to have tabs, but for... node/456 I'm not going to place tabs. You see? If I could do that -- this wouldn't be a problem, I would be all set to go. But, the issue here is I've created custom views that are not "system" urls. So, I have to find a way -- so when I create a view that gives me back a list of nodes I need to be albe to click on those nodes and NOT be taken to the node, but to my custom view with that node ID or title plugged into the view... a quick example...

If I make 5 nodes with the titles...

  • Car Name 1
  • Car Name 2
  • Car Name 3
  • Car Name 4
  • Car Name 5

    Then I create a view called "car/$arg/specs" and "car/$arg/photo"
    These would be tabbed pages -- the views that is... now when I create another view called "car/list" that will pull me a up a listing of nodes 1-5 right? Follow?

    Next we see a listing of the nodes from our view... like this...

    Car Listing

  • Car Name 1
  • Car Name 2
  • Car Name 3
  • Car Name 4
  • Car Name 5

    When I click one of those cars to get a look at one I'm going to get a node -- NOT a view, therefore -- I must somehow alter the normal "node/123" url that those nodes are leading to and change it to something like "car/123/specs" follow?

    That way when I click a node -- it wil NOT show me a node -- but it will be plugged in so-to-speak to my view and therefore my argument will be satisfied and the view will be tabbed, like thus...

    Car Name 1
    _| Specifications | Photos |_

    See?

  • jfall’s picture

    That is the problem I understood you were trying to solve, and was working towards (btw - did you get that script to run?) But if you look carefully at what moofie said, you CAN define a view tab to show up for only ONE node type! That is what I thought was so cool.

    Are you saying that you only want this behaviour (Canuk sp, eh) for specific nodes? NOT all the nodes of one specific type? Because the solution I was working at assumed application to all nodes of one type. A solution for a collection of specific nodes, not identifiable by type is probably not reasonable - or rather, it is probably easy, but would need to be hand-coded for each specific node you wanted to apply this to. To solve anything programmatically, you need to be able to identify the nodes you want to select, and node type is the easiest way to do that...

    Continuing under the assumption that you actually do want to apply this to ALL of your event type nodes, I gave moofie's trick a try using the View path event/$node-event/schedule with Node:ID as a view arg, and low and behold, it added a schedule tab ONLY to all of my event type nodes.

    That means you don't need to re-route the links because the node can live "at home" and you can just add your extra tabs onto it. Am I missing something?

    mooffie’s picture

    1. You want your links to point to "car/[nid]/specs" instead of "node/[nid]"? There's a custom link module that does this.

    2. Use '$node' instead of '$arg' in your URLs, as you don't want phantom tabs.

    GreenLED’s picture

    Explain what you mean by "$node" vs "$arg" I only have used "$arg" in my url because I've seen the help text in the url in views, but I did know the time would come when I would have to get passed using just $arg. What's the difference? Can I get a list of things to enter in the url field in views? What exactly do you mean by a phantom tab -- explain that. Thanks.

    jfall’s picture

    Give moofie's first advice a try:

    create a test view with path 'node/$node-event/something', and select menu as tab.

    Now the something tab will show up on every event node page - I'll say it again, it really is very cool. I really think this solves your problem IF you can live with the "overview" page living at the normal node home (i.e., it is the basic full node listing, which, of course, can be customized, but will say "View" on the tab instead of "Overview" - although Drupal knows, there's probably a way to change that too ;-)

    And on the other front, if you look through my replies above you'll see that I did look into custom theming the node links returned by views, but I really don't think it is feasible - links to nodes are created by MANY modules and views and handlers and ... Catching the teasers is easy, but I think the rest would be a real challenge because the raw links don't get passed through the theme engine... there may be a way, but I can't see it.

    Did you try out moofie's custom module - perhaps that'll do the trick?

    Good luck man.

    zcc_nz’s picture

    Thank you mooffie... I was going mad trying to working this one out.