Skip to content

Commit

Permalink
Allow custom slug name for Posts and Post component (#394)
Browse files Browse the repository at this point in the history
Fixes an issue that prevents the use of anything but "slug" as the post slug property. This merge also contains abstraction of some URL helper methods for all blog components.

Credit to @GinoPane. Fixes #392.
  • Loading branch information
GinoPane authored and Ben Thomson committed May 19, 2019
1 parent 2a3d4ae commit 950fbd7
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 42 deletions.
67 changes: 67 additions & 0 deletions classes/ComponentAbstract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php namespace RainLab\Blog\Classes;

use Cms\Classes\Page;
use Cms\Classes\Theme;
use Cms\Classes\ComponentBase;

abstract class ComponentAbstract extends ComponentBase
{
/**
* Reference to the page name for linking to posts
*
* @var string
*/
public $postPage;

/**
* Reference to the page name for linking to categories
*
* @var string
*/
public $categoryPage;

/**
* @param string $componentName
* @param string $page
* @return ComponentBase|null
*/
protected function getComponent(string $componentName, string $page)
{
$component = null;

$page = Page::load(Theme::getActiveTheme(), $page);

if (!is_null($page)) {
$component = $page->getComponent($componentName);
}

return $component;
}

/**
* A helper function to get the real URL parameter name. For example, slug for posts
* can be injected as :post into URL. Real argument is necessary if you want to generate
* valid URLs for such pages
*
* @param ComponentBase|null $component
* @param string $name
*
* @return string|null
*/
protected function urlProperty(ComponentBase $component = null, string $name = '')
{
$property = null;

if ($component !== null && ($property = $component->property($name))) {
preg_match('/{{ :([^ ]+) }}/', $property, $matches);

if (isset($matches[1])) {
$property = $matches[1];
}
} else {
$property = $name;
}

return $property;
}
}
16 changes: 12 additions & 4 deletions components/Categories.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
use Db;
use Carbon\Carbon;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Classes\ComponentAbstract;
use RainLab\Blog\Models\Category as BlogCategory;

class Categories extends ComponentBase
class Categories extends ComponentAbstract
{
/**
* @var Collection A collection of categories to display
Expand Down Expand Up @@ -98,8 +98,16 @@ protected function loadCategories()

protected function linkCategories($categories)
{
return $categories->each(function ($category) {
$category->setUrl($this->categoryPage, $this->controller);
$blogPostsComponent = $this->getComponent('blogPosts', $this->categoryPage);

return $categories->each(function ($category) use ($blogPostsComponent) {
$category->setUrl(
$this->categoryPage,
$this->controller,
[
'slug' => $this->urlProperty($blogPostsComponent, 'categoryFilter')
]
);

if ($category->children) {
$this->linkCategories($category->children);
Expand Down
33 changes: 22 additions & 11 deletions components/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
use Event;
use BackendAuth;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Models\Post as BlogPost;
use RainLab\Blog\Classes\ComponentAbstract;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class Post extends ComponentBase
class Post extends ComponentAbstract
{
/**
* @var RainLab\Blog\Models\Post The post model used for display.
* @var BlogPost The post model used for display.
*/
public $post;

Expand Down Expand Up @@ -102,14 +102,18 @@ protected function loadPost()
}

/*
* Add a "url" helper attribute for linking to each category
*/
* Add a "url" helper attribute for linking to each category
*/
if ($post && $post->categories->count()) {
$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
$blogPostsComponent = $this->getComponent('blogPosts', $this->categoryPage);

$post->categories->each(function ($category) use ($blogPostsComponent) {
$category->setUrl($this->categoryPage, $this->controller, [
'slug' => $this->urlProperty($blogPostsComponent, 'categoryFilter')
]);
});
}

return $post;
}

Expand Down Expand Up @@ -137,10 +141,17 @@ protected function getPostSibling($direction = 1)

$postPage = $this->getPage()->getBaseFileName();

$post->setUrl($postPage, $this->controller);
$blogPostComponent = $this->getComponent('blogPost', $postPage);
$blogPostsComponent = $this->getComponent('blogPosts', $this->categoryPage);

$post->setUrl($postPage, $this->controller, [
'slug' => $this->urlProperty($blogPostComponent, 'slug')
]);

$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
$post->categories->each(function ($category) use ($blogPostsComponent) {
$category->setUrl($this->categoryPage, $this->controller, [
'slug' => $this->urlProperty($blogPostsComponent, 'categoryFilter')
]);
});

return $post;
Expand Down
48 changes: 36 additions & 12 deletions components/Posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,60 @@
use Redirect;
use BackendAuth;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use October\Rain\Database\Model;
use October\Rain\Database\Collection;
use RainLab\Blog\Models\Post as BlogPost;
use RainLab\Blog\Classes\ComponentAbstract;
use RainLab\Blog\Models\Category as BlogCategory;
use RainLab\Blog\Models\Settings as BlogSettings;

class Posts extends ComponentBase
class Posts extends ComponentAbstract
{
/**
* A collection of posts to display
*
* @var Collection
*/
public $posts;

/**
* Parameter to use for the page number
*
* @var string
*/
public $pageParam;

/**
* If the post list should be filtered by a category, the model to use.
* If the post list should be filtered by a category, the model to use
*
* @var Model
*/
public $category;

/**
* Message to display when there are no messages.
* Message to display when there are no messages
*
* @var string
*/
public $noPostsMessage;

/**
* Reference to the page name for linking to posts.
* Reference to the page name for linking to posts
*
* @var string
*/
public $postPage;

/**
* Reference to the page name for linking to categories.
* Reference to the page name for linking to categories
*
* @var string
*/
public $categoryPage;

/**
* If the post list should be ordered by another attribute.
* If the post list should be ordered by another attribute
*
* @var string
*/
public $sortOrder;
Expand Down Expand Up @@ -210,11 +219,26 @@ protected function listPosts()
/*
* Add a "url" helper attribute for linking to each post and category
*/
$posts->each(function($post) {
$post->setUrl($this->postPage, $this->controller);

$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
$blogPostComponent = $this->getComponent('blogPost', $this->postPage);
$blogPostsComponent = $this->getComponent('blogPosts', $this->categoryPage);

$posts->each(function ($post) use ($blogPostComponent, $blogPostsComponent) {
$post->setUrl(
$this->postPage,
$this->controller,
[
'slug' => $this->urlProperty($blogPostComponent, 'slug')
]
);

$post->categories->each(function ($category) use ($blogPostsComponent) {
$category->setUrl(
$this->categoryPage,
$this->controller,
[
'slug' => $this->urlProperty($blogPostsComponent, 'categoryFilter')
]
);
});
});

Expand Down
12 changes: 8 additions & 4 deletions components/RssFeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
use Lang;
use Response;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Models\Post as BlogPost;
use RainLab\Blog\Classes\ComponentAbstract;
use RainLab\Blog\Models\Category as BlogCategory;

class RssFeed extends ComponentBase
class RssFeed extends ComponentAbstract
{
/**
* A collection of posts to display
Expand Down Expand Up @@ -137,8 +137,12 @@ protected function listPosts()
/*
* Add a "url" helper attribute for linking to each post and category
*/
$posts->each(function($post) {
$post->setUrl($this->postPage, $this->controller);
$blogPostComponent = $this->getComponent('blogPost', $this->postPage);

$posts->each(function ($post) use ($blogPostComponent) {
$post->setUrl($this->postPage, $this->controller, [
'slug' => $this->urlProperty($blogPostComponent, 'slug')
]);
});

return $posts;
Expand Down
10 changes: 7 additions & 3 deletions models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,18 @@ public function getNestedPostCount()

/**
* Sets the "url" attribute with a URL to this object
*
* @param string $pageName
* @param Cms\Classes\Controller $controller
* @param array $urlParams A mapping of overrides for default URL parameter names
*
* @return string
*/
public function setUrl($pageName, $controller)
public function setUrl($pageName, $controller, array $urlParams = array())
{
$params = [
'id' => $this->id,
'slug' => $this->slug
array_get($urlParams, 'id', 'id') => $this->id,
array_get($urlParams, 'slug', 'slug') => $this->slug,
];

return $this->url = $controller->pageUrl($pageName, $params, false);
Expand Down
23 changes: 15 additions & 8 deletions models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
use Markdown;
use BackendAuth;
use ValidationException;
use RainLab\Blog\Classes\TagProcessor;
use Backend\Models\User;
use Carbon\Carbon;
use Cms\Classes\Page as CmsPage;
use Cms\Classes\Theme;
use Cms\Classes\Controller;
use RainLab\Blog\Classes\TagProcessor;

/**
* Class Post
*/
class Post extends Model
{
use \October\Rain\Database\Traits\Validation;
Expand Down Expand Up @@ -141,22 +145,25 @@ public function beforeSave()
/**
* Sets the "url" attribute with a URL to this object.
* @param string $pageName
* @param Cms\Classes\Controller $controller
* @param Controller $controller
* @param array $urlParams A mapping of possible overrides of default URL parameter names
*
* @return string
*/
public function setUrl($pageName, $controller)
public function setUrl($pageName, $controller, array $urlParams = array())
{
$params = [
'id' => $this->id,
'slug' => $this->slug
array_get($urlParams, 'id', 'id') => $this->id,
array_get($urlParams, 'slug', 'slug') => $this->slug,
];

$params['category'] = $this->categories->count() ? $this->categories->first()->slug : null;

// Expose published year, month and day as URL parameters.
if ($this->published) {
$params['year'] = $this->published_at->format('Y');
$params['month'] = $this->published_at->format('m');
$params['day'] = $this->published_at->format('d');
$params[array_get($urlParams, 'year', 'year')] = $this->published_at->format('Y');
$params[array_get($urlParams, 'month', 'month')] = $this->published_at->format('m');
$params[array_get($urlParams, 'day', 'day')] = $this->published_at->format('d');
}

return $this->url = $controller->pageUrl($pageName, $params);
Expand Down

0 comments on commit 950fbd7

Please sign in to comment.