More fun with sub sub pages
-
I’ve been reading around a lot of the discussion following sub pages and sub-sub pages, but I haven’t quite found the answer I’m looking for (most of the posts seem to concern wp_list_pages showing a proper nav list when on page, child, or sub-child…)
I think I know roughly how you would do this in plain English, but my PHP isn’t that strong.
Problem
I need to define a variable for templating reasons that if you are on a page, any of its sub-pages, or any of those sub-page’s sub-pages.. and so on.
Following the codec example I have thus far got:
<?php if (is_page('20') || $post->post_parent=="20") { $sidebar_call = 1; } elseif (is_page('34') || $post->post_parent=="34") { $sidebar_call = 2; } elseif (is_page('11') || $post->post_parent=="11") { $sidebar_call = 3; } elseif (is_page('12') || $post->post_parent=="12") { $sidebar_call = 4; } else { $sidebar_call = "default"; } ?>
As I expected, this works fine on any of the above pages or their sub-pages, but when you get to a sub-sub-page the variable is assigned the default value.
I can imagine that I need to create an array (as can now be done in 2.5), but am not sure how to go about it.
I know there is a function for get_children, but I haven’t found any documentation on how that works (and whether it gets children of the children!).
My English version of the code would be:
<?php if (is_page('20') || (is_page(get an array of all children and sub children of page 20...) { $sidebar_call = 1; } elseif (is_page('34') || (is_page(get an array of all children and sub children of page 34...) { $sidebar_call = 2; } etc... ?>
However I’m not sure exactly how to make this happen….
Any ideas?
-
Hmm, it looks like it just hangs – not even returning an error – so I assume it’s caught in an endless loop (seeing as the first time it’s executed is at the body element, that would explain why none of the page loads).
I’m going to fiddle around with a few more options to see if I can work out what’s causing it – I’ll probably take the function out of the body to see where it’s getting to – go back to echoing the pageid so I can see what it’s printing!
ahh sorry, I changed variable names, and missed a spot…..
function eval_page($pageid) { $eus_page = "Default"; // Set the page type as default while ($pageid) { if ($pageid==20) $eus_page = 'CLC'; if ($pageid==34) $eus_page = 'Community Link'; if ($pageid==11) $eus_page = 'Recycle Scotland'; if ($pageid==12) $eus_page = 'Stepping Stones'; $page = get_post($pageid); $pageid = $page->post_parent; } return $eus_page; }
I desperately need sleep, but my altered state of mind says this *should* work. I’m off to bed now, so I sincerely hope it does ??
good luck, lol
Oh I was thinking about the class names in the body – the only reason I had originally returned those longhand names is because I thought it would be more human readable to have the sidebars named after each project – and whilst I can still call the Default sidebar with
dynamic_sidebar(1);
I thought I might be less likely to mess things up if I used longhand strings.
At first I thought that I’d have to run switch and assign proper class names to the body, but then I thought about trying this:
echo str_replace(' ', '', (eval_page($post->ID)));
Which seems to work nicely.
Now, back to the other issue ??
Heh, we were writing at the same time there.
Aye, I’m not sure how much longer I’m going to last now. I’ve been working for the last 14 hours so I’m probably not at my sharpest either.
Absolutely legend amount of help there though! Can I buy you a beer somehow?
Legend, that worked a charm. I only wish I’d spotted the wayward $parentid – I was sure I’d double checked all the variable names.
I guess it’s a good reminder of the importance of good naming structures for your variables – all of these ID’s, post ids, page ids, etc, it gets a bit confusing ??
So I’ve now managed to structure it so that the function assigns the right sidebar and class when you’re viewing a single post from category that relates to that project
(I’m now forced to ensure that each project author can only assign to his project category…)
Anyway, here’s how the function is shaping up:
FUNCTION
function eval_page($pageid,$single=FALSE) { $eus_page = "Default"; // Set the page type as default if ($single==FALSE) { // If the page isn't a single post, then work out what project the page belongs to. while ($pageid) { if ($pageid==11) $eus_page = 'Recycle Scotland'; if ($pageid==12) $eus_page = 'Stepping Stones'; if ($pageid==20) $eus_page = 'CLC'; if ($pageid==34) $eus_page = 'Community Link'; $page = get_post($pageid); $pageid = $page->post_parent; } } else { if ( in_category(4) ) $eus_page = 'Stepping Stones'; if ( in_category(5) ) $eus_page = 'CLC'; if ( in_category(6) ) $eus_page = 'Community Link'; } return $eus_page; }
I figure I could probably work these things together by dropping the if/else and any use of is_single by doing something like
while ($pageid) { if ( ($pageid==11) || (is_category(3) ) ) $eus_page = 'Recycle Scotland';
but I’ll have to test that.
USAGE
And so in my header.php and footer.php I’m getting class and sidebar with:
<body class="<?php echo str_replace(' ', '', ( eval_page( $post->ID, is_single() ) ) ); ?>">
and:
dynamic_sidebar( eval_page( $post->ID, is_single() ) );
It all seems to work solidly. I also assume that if my above assumption about being able to just combine my $pageid and in_category is true, then I could probably include is_category(3) to ensure the correct sidebars on category pages (i’m not even going to think about sub-categories right now.
This is the danger with offering different page colouring for sub sections of a website..
I just got back to my desk… lemme dig through a little stuff here, but in the mean time I want to suggest making a little shift in thinking…
I think it would be a mistake to lump all this into a single function because I’m sure that would triple the necessary length of it all. Instead, lets consider breaking this up into more managable (and therefore more updatable) smaller functions.
For example…
Evaluate for Page Templates: eval_page();
function eval_page($pageid) { global $eus_page; //global, because it's just that useful. $eus_page = "Default"; // Set the page type as default while ($pageid) { if ($pageid==20) $eus_page = 'CLC'; if ($pageid==34) $eus_page = 'Community Link'; if ($pageid==11) $eus_page = 'Recycle Scotland'; if ($pageid==12) $eus_page = 'Stepping Stones'; $page = get_post($pageid); $pageid = $page->post_parent; } return $eus_page; }
I quite liked the simplicity of this, so I vote to keep it (with a little modification, which will allow us to call the right sidebar, regardless of what the hell is going on elsewhere.
don’t worry about all that is_single stuff, lets work on that elsewhere.
I’m gonna break this up into bite-sized posts so it’s easier to follow, so bear with me as I keep posting chunks.
In the mean time, I propose a new function to be used in the sidebar, while the above function is used on PAGE TEMPLATES only like page.php and friends to construct the body tag.
…
Because the body tag is *always* set before the sidebar is called, and because it relies on context-sensitive information like IDs etc, the bulk of the work need be done at that point. For the sidebar, we don’t want to do it again. Instead lets just grab the work we’ve already done.
Evaluate Sidebar: eval_sidebar();
function eval_sidebar() { global $eus_page; return $eus_page; }
tada. This should be used to put the value we prepared earlier, into the dynamic sidebar. I’ll refer to this function in my next post too, bear with me. We’re still only on pages… I’ll get to single posts in just a minute.
ok, now we can deal with single posts…
Given that single posts have their own template file, there’s absolutely no reason to complicate things by processing posts and pages in the same function… as long as we can still put our results into the sidebar, we’re golden.
so lets think about a new function.
Evaluate for Single Posts: eval_post();
function eval_post() { global $eus_page; $eus_page = "Default"; // There must be a fallback $post = $wp_query->post; //pull $post so in_category works (not sure if necessary, but unable to test right now) if (in_category(4)) $eus_page = 'Stepping Stones'; if (in_category(5)) $eus_page = 'CLC'; if (in_category(6)) $eus_page = 'Community Link'; return $eus_page; }
just like your eval_page function, this resides inside the body tag, but only in single.php.
This is where you can decide on a sidebar priority system. Simply decide which sidebar is more important, if by chance your post happens to be in two or more of these categories, which of course, should be discouraged.
Whichever is the HIGHEST priority should appear at the END of the list. Does that make sense?
but that doesn’t really deal with every possible case… you might want to put your posts in sub-categories of these categories. What then? *home alone face*
Mind if I address that a couple of posts from now?… let me construct the meat of that first, but for a different purpose.
remember… eval_sidebar(); is still sitting there in the sidebar template, just fishing these global $eus_page values out of the air, as required… because the body tag always happens before we get there.
I’m making an aside here and giving you something you didn’t ask for, because I think I can sort of predict where we’re going here…
What about browsing category archives? surely you’ll want to be able to click on category names and view all posts in that category – in the same style as the posts themselves, right?
Right.
so lets deal with styling the category archive pages. As it turns out, it’s actually easier to do this with names, so I hope that’s not a problem…
Evaluate for Category Archives: eval_cat();
// feed me the category ID when you call me in the body tag function eval_cat($catid) { global $eus_page; $eus_page = "Default"; // what? you again!? $post = $wp_query->post; //pull $post so is_category works (again not sure if this is necessary, you find out :) ) $categories = explode('|',get_category_parents($catid,false,'|')); if (is_category(4) || $categories[0]=='Cat4Name') $eus_page = 'Stepping Stones'; if (is_category(5) || $categories[0]=='Cat5Name') $eus_page = 'CLC'; if (is_category(6) || $categories[0]=='Cat6Name') $eus_page = 'Community Link'; return $eus_page; }
this will (and I use the term ‘will’ loosely) work when browsing top-level categories, and any children of those categories… or their children and so forth.
So, lets say you have subcategories of Community Link called “Free booze and haggis”, you’ll be able to browse that subcategory in the same style as the commlink section.
again.. the sidebar on your cat archive pages will be proudly brought to you by eval_sidebar() and global $eus_page.
…
Which brings me back to the single posts business (remember *home alone face* ?)
What if a post is ticked as being only in “booze and haggis”? It won’t be directly flagged as being a part of the community link section, because in_category(6) won’t trigger.
So we need to extend eval_post() to make that work too…
This will take a sec to cobble together, make yourself comfortable (and forgive me for any errors, as again I won’t be curteous enough to actually test this beyond the code snippits I’m stealing from my functioning blog (sorry)…
It’s at this point that you ask yourself: “does he want to sleep with me?
No, actually this is going to be useful for the next phase of a project I’ve started recently, so it’s as much for me as it is for you ??
…
I also realised I forgot to mention – most templates open the body tag in the header.php… in order for your life to remain livable, I would suggest you don’t do that.
Instead take the navigation/banner/bullshit components out of your header template and open the body in the *actual template you’re using to display your content*
for example:
<?php get_header(); ?> <body class="<?php eval_func($seed); ?>"> <div id="page"> <?php include (TEMPLATEPATH . '/navigation.php'); ?>
note the use of the include. This lets you keep your navigation separate from each template (in a template of its own), but also separate from the header, so you can jump in-between with the glorious body tag.
The capital TEMPLATEPATH is a bona-fide constant, not something you need to replace with your template path.
ok… back to the single posts, and making them work regardless of how many sub-sub-cats deep your post is being categorised under.
Lets replace the eval_post() function:
Evaluate for Single Posts: eval_post(); – redux –
//feed this function with get_the_category() //when calling it in the single post template body tag. function eval_post($categories) { global $eus_page; $eus_page = "Default"; // Again with the default //for every cat we're associated with foreach($categories as $category) { //pull the parents $parentcats = explode('|',get_category_parents($category->cat_ID,false,'|')); //remember, most important cat goes LAST in case of multiple membership if ($category->cat_ID==4 || $parentcats[0]=='Cat4Name') $eus_page = 'Stepping Stones'; if ($category->cat_ID==5 || $parentcats[0]=='Cat5Name') $eus_page = 'CLC'; if ($category->cat_ID==6 || $parentcats[0]=='Cat6Name') $eus_page = 'Community Link'; } return $eus_page; }
due to the relative complexity of this, and the fact that I haven’t actually put it in a page to test it… this is the least likely of all to work… so do let me know how you go, and we’ll work on making it happen. Don’t be discouraged immediately, I’m confident it’ll go.
in the body tag of your single.php, you’ll then need to call this function as follows:
<?php eval_post(get_the_category()); ?>
This is to ensure that you’re passing all of the current post’s associated categories, whose parents should be discovered.
Time for a coffee… I’ll be around working on some junk, so when you get to this, I won’t be too far off.
That’s a legend amount of work there ??
I’ll have a to trawl through it to work out what’s going on exactly. Back at my computer after a nice long weekend away. I’m glad to hear this will be useful to you as well now, always good to see something being reused.
Hey Ivovic,
Well it’s been a mammoth 3 weeks since I last worked on this. The joy of a client not getting content to me when expected. Hence forth I had to sideline it and focus on some other stuff.
I’m now returning to it with a vengeance (they suddenly want the site live tomorrow – I don’t think that’s going to happen – in their eyes, it’s ready to go, in my web design attuned eyes, it’s a million miles away!).
Anyway, not sure if you’re still around, but I have a feeling I’ll be posting more stuff up here soon.
And if I miraculously don’t have any questions, I’ll hopefully be posting a finished site live link!
Actually I do have a question – before I go digging and testing things out. Will the eval_cat function work much the same for general archives rendered with the archives.php template?
I’m not too concerned about it as I haven’t gotten near that point, but will probably look at it later.
I’m about to move on to single posts, so will be interested to see how that works out.
I’m pleased to report that your eval_cat function works beautifully!
I did need to grab the category ID outside of the loop, but that seems to work well on my category.php template file using:
<?php $catid = get_query_var('cat'); ?> <div id="bd" class="categories <?php echo str_replace(' ', '', ( eval_cat( $catid ) ) ); ?>">
(reason for grabbing category id outside of the loop was to avoid much repeating of code)
With my str_replace giving me a class name with no spaces. It looks like fortunately I don’t have to worry about moving the body element out of header.php as I noticed that my template already has a div id=”bd” just after the header call and allows me to do all of the required section colouring that I need. Of course, if they wanted different site background colours, well that would be a different question.. but fortunately they don’t!Onwards.
Just noticed that eval_sidebar function could do with it’s own fallback, in case the global isn’t set by one of the pages – for example, on my 404 template I don’t really need to worry about calling the eval_page function. So I’ve adjusted the eval_sidebar function to be:
function eval_sidebar() { global $eus_page; if ($eus_page == NULL) {$eus_page = "Default"; } // If no global set, then set the page type as default return $eus_page; }
Again, don’t know if this is the best way to do this, but just in case I miss a template it’s good to know it will fallback.
- The topic ‘More fun with sub sub pages’ is closed to new replies.