Jump to content

Url Segments


Joss
 Share

Recommended Posts

(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 by Joss
Link to comment
Share on other sites

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

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

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

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

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

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)

  • Like 1
Link to comment
Share on other sites

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

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

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

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

  • Like 2
Link to comment
Share on other sites

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

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

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

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...