-
Posts
198 -
Joined
-
Last visited
Everything posted by Zahari M.
-
Hi everyone and thanks so much for looking! This post is perhaps a bit long winded. I do apologise. But i think the background might be important for other newbies like myself to better understand what's going on and how to setup ProcessWire... and for those of you who can help, at least you can better understand what I'm trying to do... Ok... The Question.... How do we create a general purpose function that we can use to lists all the child pages of a parent page? Why we might want this... Lets say we want to create a "section" and call this section of our website "blog"... We start writing and create some pages: home/blog/blog-post-1 home/blog/blog-post-2 home/blog/blog-post-3 home/blog/blog-post-4 I and my visitors can go to each of these URL's and see each of them as individual blog posts. No problems there! What happens though when we go to to the url "home/blog"? Well, in standard form, it would just be another page and thus it would show us the contents of that page. But what myself and many of my visitors have come to expect on this page is to instead see a "listing" of all the blog posts that we have. An index of sorts... So we obviously need to do something a bit different here. The solution lies in creating a new "list_blog_pages.php" template file, adding it into the system via the admin setup and associating it with the page url "home/blog". Next we set it up in system admin such that any children of this "list_blog_pages" template file, which are effectively going to be our blog posts, will automatically use our regular article template which happens to be basic-page.php So, whenever someone goes to the url "home/blog", the template file "list_blog_pages.php" is called up. What we need to do now is make this template file list out all the child pages i.e. our blog posts. If we take a look inside the Standard ProcessWire Profile, we can find this bit of code located smack in the middle of our html template that we can reuse in our template file that provides us with just the functionality we need to do this... <?php if($page->numChildren) { echo "<ul class='nav'>"; foreach($page->children as $child) { echo "<li><p><a href='{$child->url}'>{$child->title}</a><br /> <span class='summary'>{$child->summary}</span></p></li>"; } echo "</ul>"; } ?> So what it does is it generates and displays our list of child pages or in this case a list of all our blog articles and their summaries. It works just fine! BUT.... As a personal quirk, preference or whatever you want to call it, I would like to try and remove such code from my html template. The reason for me wanting to do this is that I would prefer to minimize the mixing of logic and presentation in my theme files. Sure, just this snippet on its own isn't a lot of code. But if you want to start adding footers and conditional sidebars etc, ones template files can become very messy! Fortunately for us, the Foundation Processwire Profile that Ryan recently created gives us an elegant solution to this problem! It does this by way of creating various "renderNav" functions. So... instead of inserting the block of code shown above into our template, Ryan is adding something like this instead to our template files... $body .= renderBodyNav($page->children); This is much cleaner! I really like this approach and would like to implement this elesewhere in my template files. SO... Upon studying all the various render functions that are located in _nav.php, what I can "just" about understand with my limited abilities is this.... there is a base function called renderNav. This renderNav generates an unordered list of all child pages of a parent page. Its a very clever function in that it has a defined set of display options and renderNav can be used by other functions that enable you to change these options depending on where in the page you want to display these pages, i.e. in the main content area or the sidebars etc... Looking at the comments in _nav.php, we have these functions.... * renderNav(PageArray $items, [$options]) - Render a generic navigation list * renderSubNav(Page $page) - Render Foundation 'side-nav' list for given $page * renderBodyNav(PageArray $items) - Render Foundation 'side-nav' for bodycopy placement * renderBreadcrumbs(PageArray $items) - Render Foundation 'breadcrumbs' list * renderPagination(PageArray $items) - Render pagination links using Foundation classes * renderTopBar(PageArray $items, [array $options]) - Render Foundation 'top-bar' navigation * renderOrbit($images, [$width], [$height]) - Render a Foundation 'orbit' slideshow Now, bit by bit, I am slowly seeing how this all works. It's all very efficient and clever and reuses code. Unfortunately, for a beginner like me, its a bit of a stretch to be fully comfortable working with all these various options of functions into functions. So, what I would like to do instead is build my own function based on renderNav that I, with my limited abilities, can more readily understand So here is what I came up with. I did two things.... 1. Inside my "list_blog_pages.php" template file I inserted a "simplified" version of renderNav as seen below. Basically I copied renderNav, simplified it by stripping out the options array and renaming it as my function "renderBlogPosts" function renderBlogPosts(PageArray $items) { if(!count($items)) return ''; $out = "<ul>"; foreach($items as $item) { $out .= "<li><a href='$item->url'>$item->title</a></li>"; $out .= "<p class='summary'>$item->summary</p>"; } $out .= "</ul>"; return $out; } 2. Inside the "basic-page.php" template that is the default article template in the ProcessWire Foundation Profile, I added this to it... $body .= renderBlogPosts($page->children); Guess what? It works! Yay! So why this post? Well, we can start getting to the actual questions now.... This is the bit I do not understand.... (PageArray $items) . I do not understand what it does and where in the documents it is mentioned. Where I got it from was from the first line of the original function renderNav... function renderNav(PageArray $items, array $options = array()) { Since I wanted to simplify things by basically removing the options and instead hard code them I stripped away the array $options = array() bit from the renderNav function. To be honest, it was just an educated guess to do that! So dear gents... Q1. Can anyone explain to me what (PageArray $items) is, where it comes from and what it actually does? Q2. Is this function, for the purposes of generating a list of pages, correctly and efficiently coded? Q3. As I havent gotten to pagination yet, how or where would I add pagination to the above? Well... whoever read this... thanks so much for your patience! Cheers!
-
About Ryan and ProcessWire - an interview with Ryan Cramer
Zahari M. replied to einsteinsboi's topic in Pub
Thanks for that! Loved the name 'Dictator' ! -
Excluding pages from the Foundation menu by using a checkbox field
Zahari M. replied to Zahari M.'s topic in Getting Started
Hi Horst! Thanks so much for the reply and looking into this! I've tried your code Horst and guess what... it works! Awesome stuff! Your one clever guy! Using Google... ich danke Ihnen sehr -
Hi kongondo Thanks for the link to that really useful thread! Zahari
-
Hi ShaltNot Not too sure if this will help you, but I was arrangin some files whilst setting up a site and I got the same error you did!! I was spending ages trying to figure out what the f*** was wrong with the files permission. It turns out I put config.php in the wrong place!!! In other words... the error could also mean ProcessWire can't find the file. So check to make sure that config.php is actually where its supposed to be !!! Ryan... if your reading this, maybe you could revise the error message to indicate that in addition to wrong permissions, you should check it's located in the right place. Cheers
-
Excluding pages from the Foundation menu by using a checkbox field
Zahari M. replied to Zahari M.'s topic in Getting Started
Hi Horst! Thank you so much for the welcome. And even more so for helping me out! Thanks so much Horst for pointing me to the area that needed looking at. Your code works great! But it's brought up 2 slight issues as a result.... But first, for the benefit of other beginners like me looking at this..... I did change it ever so slightly. I really wanted the default behaviour to be the opposite and that is by default pages are not added.... so I ended up calling my checkbox field addtonavbar and did this: if($item->addtonavbar == 0) { continue; // should be excluded, so we skip and went to the next } Of course Horst you would've inverted it this way too I'm most certain ! The two "catches" or issues that I discovered when testing this that you have to be mindful of.... First is that if you "hide" a parent page, you will automatically lose any wanted child pages in the nav bar, even if you had "checked" some of these child pages to be displayed using our approach above. Second, and a minor one at that, is that if you only wanted to display a particular parent, and have all it's children hidden, then our nav bar confusingly still renders a dropdown triangle... I'm happy with the progress thus far and can live with this as the nav bar wont be flooded with a huge number of items!! But if these two "catches" could be resolved, then we all would have an uber "complete & refined" Foundation top nav bar solution ! Thanks again so much Horst! Zahari -
Hi Guys. First Post! Greetings from Malaysia. I'm trying to move over from WordPress and am absolutely delighted to have found ProcessWire! As I'm a really slow learner, it's been taking me quite some time to understand the ProcessWire conventions. But bit by bit I'm getting there... OK... as the question asks, I would be really grateful if someone could help me out by telling me how we can go about excluding pages from the Foundation menu? I have downloaded and installed the Foundation template files for the standard Processwire site install. I have spent a long time trying to understand it and believe that the solution lies in editing renderTopNav that is located in _nav.php. function renderTopNav(PageArray $items, array $options = array(), $level = 0) { $defaults = array( 'tree' => 2, // number of levels it should recurse into the tree 'dividers' => true, 'repeat' => false, // whether to repeat items with children as first item in their children nav ); $options = array_merge($defaults, $options); $divider = $options['dividers'] ? "<li class='divider'></li>" : ""; $page = wire('page'); $out = ''; foreach($items as $item) { $numChildren = $item->numChildren(true); if($level+1 > $options['tree'] || $item->id == 1) $numChildren = 0; $class = ''; if($numChildren) $class .= "has-dropdown "; if($page->id == $item->id) $class .= "current "; if(($item->id > 1 && $page->parents->has($item)) || $page->id == $item->id) $class .= "active "; if($class) $class = " class='" . trim($class) . "'"; $out .= "$divider<li$class><a href='$item->url'>$item->title</a>"; if($numChildren) { $out .= "<ul class='dropdown'>"; if($options['repeat']) $out .= "$divider<li><a href='$item->url'>$item->title</a></li>"; $out .= renderTopNav($item->children, $options, $level+1); $out .= "</ul>"; } $out .= "</li>"; } return $out; } During a search, there was a thread here that discussed the various ways on how to exclude pages from the navigation. The only problem is that due to my limited skill set, it's just a bit beyond my abilities to adapt this into the function above! Could anyone help me out with how to modify the function so that we can exclude pages from the Foundation menu by way creating a checkbox field? Many thanks! Zahari