Roots Discourse

Sage 10 View Composer load assets within head

Hello,

I have the following simple View Composer in Sage 10:

<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use function Roots\asset;

class Download extends Composer
{
    /**
     * List of views served by this composer.
     *
     * @var array
     */
    protected static $views = [
        'single-download'
    ];

    /**
     * Compose the view before rendering.
     *
     * @param  \Illuminate\View\View $view
     * @return void
     */
    public function compose(\Illuminate\View\View $view)
    {
        $this->load_assets();
        
        parent::compose($view);
    }

    /**
     * Load assets
     * 
     * @return  void
     */
    private function load_assets()
    {
		// load css
		wp_register_style(
			'pages-product',
			asset('styles/pages/product.css')->uri(),
			[],
			MYTHEME_VERSION,
			false
		);
		wp_enqueue_style( 'pages-product' );
    }
}

which loads a CSS file for this particular partial (single-download.blade.php). The thing is that the CSS is loaded within the body and not within the head. This is to be expected since I do not use the action wp_enqueue_scripts.

When I try to use the above action it does not run at all, it appears the View Composer runs after that particular event. Is there any way to ensure the CSS file gets added at the head of the page? Is there a different approach in loading CSS/JS files per partial to ensure they are loaded at the start of the page load?

Up!

Any suggestions on this?

No, not in the way you describe. Sage hooks into the template_include hook to inject the results of blade rendering, which AFAIK is when the Composer would also be executed. (You can see what it does when it hooks in here.) In the WP documentation, it says the following about template_include:

This filter hook is executed immediately before WordPress includes the predetermined template file.

From that I would infer that when a partial is inserted it is “too late” to add a hook that relates to <head> generation. I tried a minimal example locally and found that this was the result. Until the partial is loaded I don’t believe that the system has any way to know what partials will be loaded, so I don’t think you could approach that in a different (automated) way.

Although it isn’t technically valid HTML to have <style> elements outside the head, IME it works in every browser, so you could just echo out your CSS at the beginning of your partial. Another alternative would be to print your <style> or <link> tag and then use runtime JS to move it to the <head>.

Thank you for the information.

I can also see that using a Service Provider does not help with the situation.

I am able to access wp_enqueue_scripts action where inside the callback I check whether I am in the correct view and then enqueue my CSS/JS. This though does not add the assets at the head but instead, adds them in the body.