igaster / laravel-theme

Theme support for Laravel
MIT License
520 stars 113 forks source link

Blade '@extend' viewsPath inheritence #9

Closed kristopherchun closed 9 years ago

kristopherchun commented 9 years ago

I wanted to use blade @extend for my templating, however I needed a way to get the template based on the selected theme. This works for me, if it finds the file under the themes /resources/views/ folder, it will use it, if not, it will fall back to the default theme. I am still new to this, so this may not be the best way to do this, but is this a feature you can add/improve?

Config:

/config/themes.php

       'default' => [
            'extends'       => null,
            'views-path'    => 'themes/default',
        ],

        'theme1' => [
            'extends'       => 'default',
            'views-path'    => 'themes/theme1',
        ],


Usage:

/resources/views/themes/{themename}/layouts/master.blade.php

<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    @yield('content')
</div>
</body>
</html>
/resources/views/themes/{themename}/templates/homepage.blade.php

@extends(Theme::viewsPath('layouts/master'))

@section('content')
   This is the body content of homepage.
@endsection


Code Modifications:

/vendor/igaster/laravel-theme/src/Themes.php

public function viewsPath($url){
     if (Config::get('themes.enabled', true))
        return $this->activeTheme->viewsPath($url);
     else
        return $url;
}
/vendor/igaster/laravel-theme/src/Theme.php

public function viewsPath($url){
        $fullUrl = (empty($this->viewsPath) ? '' : '/').$this->viewsPath.'/'.ltrim($url, '/');

        if (file_exists($fullPath = base_path('/resources/views/'.$fullUrl).'.blade.php'))
            return $fullUrl;

        if ($this->getParent())
            return $this->getParent()->viewsPath($url);

        //view not found
        $action = \Config::get('themes.view_not_found','LOG_ERROR');

        if ($action == 'THROW_EXCEPTION')
            throw new themeException("view not found [$url]");
        elseif($action == 'LOG_ERROR')
            \Log::warning("view not found [$url] in Theme [".\Theme::get()."]");
    }
igaster commented 9 years ago

Actually this is the setup I follow in my projects.

Just use @extends('layouts/master') instead of @extends(Theme::viewsPath('layouts/master')) and it will pick the master.blade.php from your actice theme. If not found then it will fall-back to parent (default) theme. Same goes with @include.

Please confirm that it solves your problem. Thank you for your proposals...

kristopherchun commented 9 years ago

I see. I can't believe I didn't try that first. Yes that worked! Thank you! Great package!