I have made a blogging application in Laravel 8.
The application supports themes. The active theme sis set in the settings table and the parent controller reads it from there:
class FrontendController extends Controller
{
protected $data;
protected $site_settings;
protected $theme_directory;
protected $site_name;
protected $tagline;
protected $owner_name;
protected $owner_email;
protected $twitter;
protected $facebook;
protected $instagram;
protected $is_cookieconsent;
protected $is_infinitescroll;
protected $pages;
protected $articles;
protected $article_categories;
protected $article_tags;
protected $authors;
public function __construct()
{
$this->site_settings = Settings::first();
$this->theme_directory = $this->site_settings['theme_directory'] ?? null;
$this->site_name = $this->site_settings['site_name'] ?? null;
$this->tagline = $this->site_settings['tagline'] ?? null;
$this->owner_name = $this->site_settings['owner_name'] ?? null;
$this->owner_email = $this->site_settings['owner_email'] ?? null;
$this->twitter = $this->site_settings['twitter'] ?? null;
$this->facebook = $this->site_settings['facebook'] ?? null;
$this->instagram = $this->site_settings['instagram'] ?? null;
$this->is_cookieconsent = $this->site_settings['is_cookieconsent'] ?? null;
$this->is_infinitescroll = $this->site_settings['is_infinitescroll'] ?? null;
// Most recent articles
$this->articles = Article::visible()->limit(5)->get();
// Article categories. Get only categories with articles
$this->article_categories = ArticleCategory::has('articles')->get();
// Pages
$this->pages = Page::all();
// Article tags
$this->article_tags = Tag::all();
// Authors
$this->authors = User::withCount('articles')
->having('articles_count', '>', 0)
->orderByDesc('articles_count')
->get();
$this->data = [
'theme_directory' => $this->theme_directory,
'site_name' => $this->site_name,
'tagline' => $this->tagline,
'owner_name' => $this->owner_name,
'owner_email' => $this->owner_email,
'twitter' => $this->twitter,
'facebook' => $this->facebook,
'instagram' => $this->instagram,
'is_cookieconsent' => $this->is_cookieconsent,
'is_infinitescroll' => $this->is_infinitescroll,
'pages' => $this->pages,
'articles' => $this->articles,
'categories' => $this->article_categories,
'tags' => $this->article_tags,
'authors' => $this->authors,
];
}
}
The ArticlesController, PagesController, etc, extend the above controller.
I have a custom 404 template for every theme. The path to it would be `resources\views\themes' .$theme_directory . '\templates404円.blade.php'.
For example, I show the custom 404 template fot a missing tag like this:
public function tag($tag_id)
{
$tag = Tag::firstWhere('id', $tag_id);
if ($tag) {
$articles = Article::visible()
->whereHas('tags', function (Builder $query) use ($tag) {
$query->where('id', $tag->id);
})
->paginate($this->per_page);
return view(
'themes/' . $this->theme_directory . '/templates/index',
array_merge($this->data, [
'tag' => $tag,
'articles' => $articles
])
);
}
return redirect('/404');
}
But if I want to show it for a missig aricle in a similar way, I fail because I use
$article = Article::visible()->where('slug', $slug)->firstOrFail();
if(!$article) {
return redirect('/404');
};
I fond a hack to solve this problem:
$article = Article::visible()->where('slug', $slug)->first();
if(!$article) {
return redirect('/404');
};
But using firstOrFail() is a standard for good reason, so I would rather keep it.
Questions:
- How can I keep
$article = Article::visible()->where('slug', $slug)->firstOrFail()and use the custom 404 template? - Is there a "global" solution for showing every theme's 404.blade.php, for all cases that apply?
-
1You can customise how Laravel handles and renders exceptionsPeppermintology– Peppermintology2025年10月25日 10:18:40 +00:00Commented 13 hours ago