Amitav Roy

Blog on web and travel

Laravel 4 Multiple segment route and Blog post page

Posted on July 2019

Laravel

In this tutorial, I will show how we would define a route with multiple segments in Laravel 4 so that we can use the URL alias of a Drupal node and then take the user to the individual node’s page. Also, we will see how we can override a view section’s content to set the page title to the blog’s title inside the head tag.

The route and why

Drupal gives us an option to create URL alias of the nodes instead of system URL such as node/1 or term/2 etc. We can use tokens to create a URL something like content/[node-title]/[section]/year-month-date/node-id which is what even I have done. It’s a very common practice for SEO purpose and to give the user a sense of where he is inside a site. So, what I have done it updated the model so that the URL alias is attached to the blog node object and then we will use that to link the title to accordingly.

Here is the modification that I have done in the model:

protected function getNodeAlias($nid)
{
  $alias = DB::table('url_alias')->select('alias')->where('source', '=', 'node/' . $nid)->lists('alias');
  return $alias[0];
}

You can view the full code here: Node model.

And then in the blog model, I attached it to the blog post object

$blogData = array(
  'content' => $blog,
  'tags' => parent::getNodeTerms($blog->nodeId),
  'url_alias' => parent::getNodeAlias($blog->nodeId),
);

You can view the full code here: Blog model.

And once I have done that, I can easily link the titles of the blog post to their individual page using the URL alias. But the real problem is when we define a route in Laravel 4 to catch the URL alias.

Here is an URL example: blog/140214/entertainment/another-question/12

Here except for blog, everything is dynamic and obviously I don’t want to something like:

Route::get(‘blog’/{date}/{section}/{title}/{nid}). Although it’s possible, but still I want this to be dynamic and so here is here how we tackle that make it completely dynamic:

Route::get('blog/{segments}', 'HomeController@singlePost')->where('segments', '(.*)');

Once I do that, inside the controller, I get the whole URL as an argument.

The view and updating the parent section inside a view

Once this is done, I called the getBlogs function inside the Blog model which already works as required. I pass one id and it will build the blog post for me.

public function singlePost($alias)
{
  $segments = explode('/', $alias);
  $nodeId = $segments[count($segments) - 1];
  $blog = new Blog();
  $thisBlogPost = $blog->getBlogs($nodeId);
  $this->layout->content = View::make('blog.blog-post')->with('post', $thisBlogPost);
}

Then I created a new view to show the single post and inside that, I have extended the head section of the HTML view which I am using as the master layout file and added the page title because that’s something which I will get inside the full blog post page as part of the node.

Here is the view code:

@layout('html')
@section('content')
<div class="col-md-8">
<h1 class="post-title">{{ $post['content']->nodeTitle }}</h1>
<div class="post content content-wrapper">
<div class="body">
      {{ $post['content']->nodeBody }}
    </div> 
  </div>
</div>
@stop
  
@section('pageHeadSection')
@parent
<title>{{ $post['content']->nodeTitle }}</title>
@stop

This way, now I can click on any of the titles of the blog posts and it will take me to the individual page.

You can also check out this branch for the full code base

You can view the full code here: Full tutorial code branch.