Joss Posted February 17, 2013 Share Posted February 17, 2013 (edited) (Note, this might be aimed at the overworked Soma, simply because he has done posts on this before! - http://processwire.com/talk/topic/2519-nested-categories/?hl=segment#entry24077 ) I am trying to work URL segments into a function for getting posts belonging to categories in a tree. This is my current code (with some rubbish kicked out) function getPostsbyCategory() { $thisCategory = wire("page"); $posts = wire("pages")->find("post_category_select=$thisCategory, post_featured_category=0"); foreach ($posts as $post) { echo "<a href='{$post->url}'><h4>{$post->title}</h4></a>"; echo "</div>"; } } The actual posts are to be found at /content-management/posts/POST-NAME - so the post name is three down. The templates can vary. The categories are in the normal page hierarchical structure and all have the same template of "category" with URL segments on. I am assuming that I need to capture the url segment within the foreach, but I have confused myself as to how and what to do with it. My attempts have so far only thrown errors, so I wont even repeat those here. Any clues would be very nice! Joss Edited February 17, 2013 by Joss Link to comment Share on other sites More sharing options...
thomas Posted February 18, 2013 Share Posted February 18, 2013 I don't really understand what you are doing here, but then again, I'm no Soma If post_category_select is a page field holding the category page and $page is that category page, you won't need any url segments at all. If your category name is fed to $page by an urlSegment, try this: $posts = wire('pages'->find('post_category_select.name = '.$input->urlSegment1) If your foreach() should link to the actual posts, you won't need any urlSegments since the url() of the posts are already ready and correct. I'm making a lot of assumptions here so maybe it's all wrong ... Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Hi Thomas The problem is my URLs rather than finding the posts. Because the actual posts are stored out of the tree, my category URL is: domain.com/news/politics/ But my political post which is linked to the politics category is domain.com/content-management/posts/political-post So I want to end up with: domain.com/news/politics/political-post Joss Link to comment Share on other sites More sharing options...
thomas Posted February 18, 2013 Share Posted February 18, 2013 Ah, now I get it. Try this: foreach ($posts as $post) { echo "<a href='/news/politics/{$post->name}'><h4>{$post->title}</h4></a>"; echo "</div>"; } Or even: echo "<a href='{$page->url}{$post->name}'><h4>{$post->title}</h4></a>"; to make the category variable as well ... Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Thanks Thomas, unfortunately that does not work. Although it looks right, there isn't actually a post at /news/politics/political post. So it just does nothing because it has nothing to link to. That is why I need to use URL segments (I think). Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 try this on the categories template if($input->urlSegment1){ //get the post $post = $pages->get("/content-management/posts/$input->urlSegment1/"); echo $post->title; }else{ // code for the categories page } Link to comment Share on other sites More sharing options...
thomas Posted February 18, 2013 Share Posted February 18, 2013 How do you find the pages at /news/political/xoxox? To move the pages out of the tree, I guess you have a page somewhere that reads the urlSegment and then finds the approriate page in the tree (ie /content-management/posts/xoxoxo). THis would be your category page. Whatever this page needs is what you have to use as an url. So if your category page (/news/politics/) works like this to find an actual post: $post = $pages->get("name=$input->urlSegment1"); this code: <a href='/news/politics/{$post->name}'> *should* work. (make sure to use "name" not title, and watch the slashes) 1 Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Where I am getting confused is that I am starting with a FIND to get the array of posts that have this category as the one selected in post_category_select. I have an array variable called $posts and I am looping through that, as in my original post. That is all working fine and I am listing posts correctly. What I cant work out is how to translate what you guys are saying into my foreach loop so that it actually links to my post. This is probably me not understanding how the UrlSegments system is meant to work. Joss Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 What i posted doesn't have anything to do with the loop. You should use thomas's code to create the links, and my code to output the post in the modified urls. The loop (and all the other code) should go in the categories template on the part where I wrote "// code for the categories page"). Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Ah, okay, I am beginning to understand how this works now. I am suffering from reading too many posts about this and it has turned to mush. So.... I now return the post title on a blank page. Do I put all my post template code at that point, or do I use the post template in some other way? Thanks chaps! Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 your template should look something like this <?php include("header.php"); if($input->urlSegment1){ // code for the post page $post = $pages->get("/content-management/posts/$input->urlSegment1/"); if(!$post->id) throw new Wire404Exception(); // throw a 404 in case the page doesn't exist echo $post->render(); // you can put all the output code on the real post template }else{ // code for the categories page foreach ($posts as $post) { echo "<a href='{$post->name}'><h4>{$post->title}</h4></a>"; echo "</div>"; } } include("footer.php"); Edit: added the Wire404Exception() to the code and simplified the links 2 Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 I forgot about the existence of render() Thanks a million both of you. My boostrap/themable/ultra blog profile is now one step closer! 2 Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 Good You should throw a 404 in case the page doesn't exist. I will update my post above to include the necessary line. Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 You can also simplify the links to: <a href='{$post->name}'><h4>{$post->title}</h4></a> Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Hi Diogo I have just written this up on the wiki at the end of Ryan's URL Segments post. Can you pretend you don't know how it works and check if it makes sense? http://wiki.processwire.com/index.php/URL_Segments#Example_-_Using_URL_Segments_to_link_catgories_to_posts Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 The next trick, of course, is make the breadcrumbs work in the same way! Link to comment Share on other sites More sharing options...
ryan Posted February 18, 2013 Share Posted February 18, 2013 Joss, that example you put in there is comprehensive enough that it probably belongs on it's own page in the Wiki. Thanks for putting it together. It's a rather nice tutorial in its own right. Is it possible to move it to a dedicated page? Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Yeah sure - any ideas what I should call it? And any thoughts on a breadcrumb code that builds on this? It is the one, rather glaring hole in the solution Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 The breadcrumb is easy. if you don't do anything you already have the breadcrumb of the category page that will be something like home>categories, and you need to add the link of the category you are in, that in this case is exactly this page. echo "<ul id='breadcrumb'>"; foreach($page->parents as $parent) { echo "<li><a href='{$parent->url}'>{$parent->title}</a> > </li>"; } if($input->urlSegment1) echo "<li><a href='{$page->url}'>{$page->title}</a> > </li>"; // add this echo "</ul>"; Edit: I forgot the condition. Code is updated with it. Link to comment Share on other sites More sharing options...
ryan Posted February 18, 2013 Share Posted February 18, 2013 How about: "Using URL segments to disconnect presentation URL from structure URL" or just "Real-world URL segments example" I'm not sure breadcrumbs need to be here, as that gets into specific implementations and not every site uses breadcrumbs. An individual's solution would just be to make the breadcrumb generation code aware of URL segments. // $page lives in /products/ and we want to show it in /categories/[first-cat]/product/ if($page->template == 'product') { // we need to base our breadcrumbs off some other page $parent = $page->categories->first(); // where categories is a page reference field held by product pages $parents = $parent->parents->prepend($parent); } else { $parents = $page->parents(); } // generate breadcrumbs foreach($parents as $parent) { // ... } Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Hi Diogo Didn't work. The problem is that as soon as you hit the link, you jump over to the original path Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 I forgot to put the condition. Already updated the code, can you try again? Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 Ryan okay, that is a neat title for a wiki page! Do you mind if I shorten it a little?? As for the breadcrumbs, the trouble with that is that is assumes a specific template and I am trying to avoid that - as you said, it can become too specific to a particular site. The only reason I though about bread crumbs, is if you are doing this to make your site more logical, there is a very good chance you are using bread crumbs too. So the two do go kind of hand in hand. Link to comment Share on other sites More sharing options...
Joss Posted February 18, 2013 Author Share Posted February 18, 2013 HI Diogo, Still no luck. Remember I am rendering the output from having identified the post. So, I am assuming that once it is being shown in its own template, the post has no knowledge of where it comes from. On that basis, maybe it needs to take the category path with it so that can be added to the breadcrumb? Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2013 Share Posted February 18, 2013 Joss, where are you putting the breadcrumb code? it should be on the category template, not on the post template. So, in my code, $page refers to the specific category page ("politics" in your example). Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now