Need Help outputting Page Meta Description using Jordan Lev's "Clean" Auto-Nav block


I hate to ask for help... but I seem to be spinning my wheels. I'm trying to make a page that displays a site map with each page's meta description displayed with the link to the page (like I do with Rapidweaver all the time, like on this site: ).

First thought I could just make a page, add a Page List block and then style it. But then I realized that the Page List block doesn't include logic for iterating through child pages and creating a separate structure to hold them so that I can indent them under their parent in the sitemap display.

So... then I figured "WAIT! The AUTO-NAV block does this, maybe THAT will be easier to work with... I just have to add in the ability to retrieve an attribute from each page as the <LI>'s are being built!" And off I went. I found Jordan Lev's "clean" blocks (including the Auto Nav block... THANKS, btw! You can find them here: ) and I created a new Auto Nav template using his view.php. I cleaned up the structure for the <UL>'s and <LI>'s to be simpler and more what I need, like this:
echo '<div id="sitemap">';//opens the sitemap wrapper
echo '<ul>'; //opens the top-level menu
foreach ($navItems as $ni) {
   echo '<li>'; //opens a nav item
   echo '<a href="' . $ni->url . '" target="' . $ni->target . '">' . $ni->name . '</a>';
   if ($ni->has_submenu) {
      echo '<ul>'; //opens a dropdown sub-menu
   } else {
      echo '</li>'; //closes a nav item
      echo str_repeat('</ul></li>', $ni->sub_depth); //closes dropdown sub-menu(s) and their top-level nav item(s)
echo '</ul>'; //closes the top-level menu
echo '</div>'; //closes the sitemap wrapper

My problem is that I'm not sure how to access the Page from here... so I haven't been able to get the "Meta Description" to print out.

I tried putting something like this in (embarrassing, I know! It's assembled bits of code I've found by searching the forums for similar problems/solutions):
$ak = CollectionAttributeKey::getByHandle('meta-description');
$value = $_c->getAttributeValue($ak->getAttributeKeyHandle());
echo $value;

But I got nothing. Bupkis!

Can someone start me on the right path? I seem to keep getting confused by what I do/don't have access to when I'm in various files within the system (view.php, custom block template, controller, etc.).


- John

View Replies: View Best Answer
mkly replied on at Permalink Reply
The magic is that the file is broken up in sections. It's a fantastic example of what I feel is good best practice type stuff for making block templates in general.

1. Load up a $navItem object
2. Then you spit them back out at the bottom.

Take a look at the below and see if it helps out.

Down around line 134ish you can add
$navItem->description = $ni->getDescription();

Then down around line 219 you can grab the description with

ni gets used a couple times which may be confusing you. It's only local to the foreach loop it's in.

At the top ni is an AutonavBlockItem which is defined in the autonav block's controller.php
mkly replied on at Permalink Best Answer Reply
Oh oops. You meed meta-description.

Around line 68ish
for ($i = 0; $i < $navItemCount; $i++) {
  $ni = $includedNavItems[$i];
  $_c = $ni->getCollectionObject();
  $current_level = $ni->getLevel();
  // add this
  $description = $_c->getAttribute('meta-description');

Then load up the navItem with
$navItem->description = $description;

and use it at the bottom the same way I described above.
arrestingdevelopment replied on at Permalink Reply

Dude! You rock! Thanks so much for this... it works perfectly. THANKS!

And NOW I see how it's working! So I got the functionality AND a learning experience. AWESOME!

Question: what's the difference between "$c" and "$_c"? Is it a matter of scope?

Thanks again!

- John
mkly replied on at Permalink Reply
The $_c thing(actually the $_ thing) is just a convention afaik. There was already a $c from the global scope so the $_c is just using $c again but indicating it's the local one. It isn't actually a php thing as much as a coding convention.

concrete5's use of $c in the global scope will probably just confuse you more if I explained it. I'll just say that $c gets thrown around a lot with global $c's so don't use $c as a matter a safe waters.

But ya, about breaking up the files. A lot of times we as concrete5 developers are overriding functionality of blocks and addons in the template file. Probably one of the most common tasks I do.

Since you are stuck using only one file you can still break it up in a pseudo mvc'ish manner but separating the sections of the file. Like using the top as you would controller.php and the bottom as you would view.php

As a side note, I am a full on ooCSS convert after something I was working on this week. In the concrete5 sense it almost feels mandatory to me now. When skinning a bunch of different addons/blocks to look the same, not having any abstractions to work with is a nightmare.
arrestingdevelopment replied on at Permalink Reply

So when working in the local scope of a block, custom template, etc., it's just safer to use a local scope instance of a collection object, rather than the global $c, to avoid issues of referencing the wrong object? Seems to make good sense! Thanks!

Re: ooCSS... COOL! Would love to hear more about the specific circumstances that led you to "convert", if you've got the time. Sounds interesting. ;)

Thanks for your help!

- John
mkly replied on at Permalink Reply
Well most everything should be locally scoped without having to do anything. But with the global $c thing that pulls $c in as a global variable you can have issues.

There are some coding conventions that tell you to add an underscore before all private and protected methods. It's probably because of php4 where there aren't afaik private methods. Python does something kind of like that for that reason.

On the ooCSS. I don't want to talk about it. Let's just say it's almost 2:30am over here.