Lowercase + dashes for param() helper URI

Hey there,

as the title says, I’m using the param() helper filtering by tags, and everything works as planned.

Now, the respective URI looks like this:

http://127.0.0.1:8000/blog/tag:3D Design, but I want it to look like this:

http://127.0.0.1:8000/blog/tag:3d-design.

Any ideas? Input welcome.

PS: Bonus points for http://127.0.0.1:8000/tag/3d-design - especially being more SEO-friendly (I guess)

  1. You can use str::slug():
$string = "3D Design";
$param = str::slug($string);

Of course, you have to make sure to use the same method for filtering.

  1. That can be done with a route that does the filtering (but then instead of using the param helper, your filter button/select would call the URL and the route return the data for the page.

exactly, and last time I tried using a route I either ended up in a loop or a blank page …

Hm, and therefore you don’t want to use routes anymore? But if you want to do your filtering with a URL instead of a parameter, I don’t see what would be the alternative? Always willing to help if you get stuck.

Well, I’d love to use routes, but obviously I’m not experienced / too sleepy to get them :slight_smile:

I don’t know your code, but let’s assume we use the Starterkit’s blog controller as a starting point (leaving out the pagination etc.)

So, this is the blog controller:

<?php

return function($site, $pages, $page, $args) {


  if(isset($args['results'])):
    $articles = $args['results'];
  else:
    $articles = $page->children()
                     ->visible();

  endif;

  return compact('articles');

};

(Notice that we use a fourth argument $args that, if it exists, gets additional data from the route)

This is the route:

c::set('routes', array(
  array(
    'pattern' => 'tag/(:any)',
    'action' => function ($tag) {
      $p = page('blog');

      $children = $p->children()->visible();
      // filter articles by tag using the filter with callback method
      $results = $children->filter(function($child) use($tag){
        // convert each tag item using the str::slug method
        $tags = array_map(function($tag) {
          return str::slug($tag);
        }, $child->tags()->split());
        // check if the given tag is in the modified tags array
        return in_array($tag, $tags);
        });

      $data = [
        'results' => $results
      ];

      return array('blog', $data);
      }
  )
));

According to your post above, you want to remove the blog part from the URL when calling your tags. If that was a mistake, you have to add it to the route. I actually think, the route should still contain the blog part, otherwise it’s rather confusing for the user.

Make sure that you use the new tag URL in your tag links. You can use a page model for this.

Will try that, thank you so far!

@S1SYPHOS Did you get it to work?

1 Like