Open ouun opened 4 years ago
Regarding Functions from parent theme in helpers.php are available via \Parent\my_test_function()
I was able to solve it:
In the functions.php
I oversaw that locate_template()
is used what checks for files by hierachy (Searches STYLESHEETPATH before TEMPLATEPATH). So as I still had a helpers.php
, setup.php
, ... in my child/app
folder, it loaded the child one and skipped the parent files in parent/app
even though they should get included as well (by default).
So this is fixable by renaming either the files. In my case I renamed parent/app
to parent/inc
so the locate_template()
function in the parents function.php
will recognize them.
So for now I am only confused what the best way is to autload the View Composers from the parent theme.
Cheers
Well, another issue solved. Quite easy and obvious when now thinking about it:
In the child theme config/view.php
you have to (of cause) add the composer Classes:
'composers' => [
// App\Composers\Alert::class,
Parent\Composers\Alert::class,
Parent\Composers\App::class,
Parent\Composers\Title::class,
],
Furthermore if you have custom ServiceProviders in the parent theme, you need to load them as well in /config/app.php
:
'providers' => [
Parent\Providers\ThemeServiceProvider::class,
// App\SomeService\SomeServiceServiceProvider::class,
],
So my currently only leftover is that it would be fantastic to get config values via \Roots\config()
that fallbaks to parent value if it is not overwritten in the child theme.
Putting this on hold until Sage 10 documentation is finished.
To chime in here from my debugging work, it looks like the current method for adding composers/components from outside the theme directory structure is no longer in config/app.php
or config/view.php
.
The way I've found to implement composers and components is to implement theme in your child theme's ServiceProvider. Specifically, you'll want to add them into the boot()
function as shown in the Laravel documentation for View Composers and manually registering package components. Both of these are a bit clunky, as shown below.
/** ...
* Inside your ThemeServiceProvider.php file
*/
use Roots\Acorn\ServiceProvider;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View;
...
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot() {
// Boot your view composers here.
// Note that you have to redefine the 'view' in order for it to use this composer on the correct view partials
View::composer('view.name', \ParentApp\View\Composers\ViewName::class);
// Boot your components here.
Blade::component('alert', \ParentApp\View\ComposersComponents\Alert::class);
}
This is obviously not great because you have to define your view names, and import all your classes manually. Shouldn't we be able to boot the parent theme's ServiceProvider and bring in all those Composers/Components? Someone with more Laravel/PHP experience may be able to help with that. I have a feeling that if we want a child theme/app to work, we'll need to create a child theme fork.
In the mean time, I hope this helps the poor souls looking to make this work.
Does anyone have a working example of a Sage 10 parent / child theme for a noob like myself? :)
@gitgudcameron you can have a look at this comment: https://github.com/ouun/stage/issues/204#issuecomment-764809660
Thanks @evankford I was struggling with how to convert a Sage9 child-theme to Sage10 (after parent theme upgrade).
I'm not 100% familiar with Blade/View/Composers yet but following your example I managed to get it working.
In child theme composer file I put
"autoload": {
"psr-4": {
"App\\": "./../sage/app",
"Child\\": "app/"
}
},
To load the parent theme.
I don't think it makes sense to load all components in boot so I don't mind defining each line. For example to use parents theme App I put
View::composer('*', \App\View\Composers\App::class);
And child theme also uses "site messages" in layouts/app.blade.php
.
View::composer('site.messages', \App\View\Composers\Site\Messages::class);
However for all the components I found "componentNamespace" in Laravel documentation which is nice so in the boot function I also put
Blade::componentNamespace('\\App\\View\\Components', 'sage');
and can use the parent themes components in the child theme like so <x-sage::page-section>...</x-sage::page-section>
Hope this helps anyone else making a child theme!
edit
Oh yeah... all the child themes View/Composers are namespaced like so namespace Child\View\Composers;
Please let me know If I need to open a new issue for this on github?
Is there any proper guide for setting up the child theme with sage 10? I am using sage 10 as my main theme on WordPress and for customizations, I have to create the child theme. I tried following the above discussion to create the child theme and it does not work. Changing the parent theme's namespace to Parent (from App) breaks the connection between composers and views, data does not go to the views.
Child theme is activated.
getting this error
Undefined variable $heroBackground
in section-page-header.blade.php
$heroBackground is defined in the Parent\View\Composers\App.php
in the child App.php I have the following code
<?php
namespace App\View\Composers;
use Roots\Acorn\View\Composer;
class App extends Composer
{
}
And in the child theme's App\Providers\ThemeServiceProvider
<?php
namespace App\Providers;
use Roots\Acorn\ServiceProvider;
class ThemeServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//this outputs the correct data from the parent function
dd((new \Parent\View\Composers\App())->getColorScheme());
}
}
Any hint about where to go from this point will be much appreciated.
@waqas-raza-dh
Any hint about where to go from this point will be much appreciated.
If I understand from my troubles with this, it's likely that the child theme is not loading the parent's view composer for section-page-header.blade.php.
Usually, that would be a SectionPageHeader.php
class file in the App/View/Composers folder/namespace.
I'm sure there's a more elegant way to autoload all the parent's composer classes, but I add the ones I need to the boot function in the child's ThemeServiceProvider
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
View::composer('index', \Parent\View\Composers\Index::class);
View::composer('partials.footer', \Parent\View\Composers\Footer::class);
... Whatever else you have here
Surely you could programmatically fetch all parent classes, or maybe I'm doing something wrong and they're supposed to be autoloaded, but this works for me.
@evankford thank you for clearing things out for me. So, in my Parent view composer App\View\Composers
I am passing some common data to all the views so I am able to get the variables like {{$var}} in my parent blade files.
But when I activate my child theme and load the parent view composer in the boot method
View::composer('*', \App\View\Composers\App::class);
it does not make any difference, and I still get the error that variable does not exist.
@waqas-raza-dh Without knowing more, it's hard to say why that's not loading. I would check:
@evankford I was able to fix the issue. The issue was within the child stylesheet. So, composer files are loading perfectly now and all the data is also coming through. Is there any correct way of importing parent theme's styles and scripts. Currently I am importing the parent theme's style in my child theme like below
@import "../parent-theme/resources/styles/app.scss";
and when i run the build some css does not load.
Hello everybody! Tell me please is there any detailed guide on how to create child theme for Sage 10 properly? Can you give me the URL of such tutorial if it exists? Is this approach recommended at all?
Hey everyone! I would like to push this discussion further ahead and hopefully, we will come up with a solution that we can incorporate into Acorn and add some official documentation about child themes. I think @ouun has a good starting point here https://github.com/ouun/stage/blob/master/app/Providers/StageServiceProvider.php#L56. I would love to just call attachParentComposers()
or even detect the child theme and automatically attach them. What do you guys think, can we make this work a little bit more smooth?
@Dathix I think it's a great idea! I want to take part in this task, but I don't have enough skills to do it. I wounder what Sage core team members think about child theme support in future.
Description
Related to this discussion: https://discourse.roots.io/t/sage-10-as-parent-child-themes/ It would be fantastic to get some feedback ftom @Log1x and @QWp6t
Steps to reproduce
1. Parent Theme:
1.1 Make a new Sage 10 Theme with custom Namespace "Parent" in folder 'parent' 1.2 Add some View Composers variables such as "siteName" and reference it in a blade file 1.3 Add a function
my_test_function()
tohelpers.php
1.4 Activate the theme, it should be working and the variable$siteName
is outputted correctly2. Child Theme
1.1 Make a new Sage 10 Theme and leave the Namespace as "App" in folder
child
1.2 AddTemplate: parent
tostyle.css
1.3 Remove all blade files from./resources/views/
1.4 Use\Parent\my_test_function()
e.g. in a child View Composer 1.5 Autoload parent theme Class in composer.php:1.5 Activate the child theme
Expected behavior: [What you expect to happen]
\Parent\my_test_function()
\Roots\config()
is loading parent theme value, if child theme value is not setActual behavior: [What actually happens]
Undefined variable: siteName
errors, the View Composers from the parent theme are missing\Parent\my_test_function()
\Roots\config('app.debug')
is not set in child theme as function not checks against parent valueReproduces how often: [What percentage of the time does it reproduce?]
In the current setup 100%. More tests required.
Versions
Sage 10.0.0-alpha
Additional information
It would be fantastic to get a very short summary how child/parent themes should be set-up with Sage 10.