Roots Discourse

Sage 10 - how to return blade templates from setup.php for custom shortcodes?

I am trying to add a shortcode, I was using the following in setup.php and it was working in Sage 9

add_shortcode('my_shortcode', function ($atts = [], $content = null, $tag = '') {
    $atts = array_change_key_case((array) $atts, CASE_LOWER);
    $post_atts = shortcode_atts(['title' => 'my-title'], $atts, $tag);
    return template('partials.my-blade-file', ['atts' => $post_atts]);
});

Sage 10 doesn’t seem to have the template method to return so I have tried a lot of things and either returns empty or breaks the site completely. This seemed to be the equivalent from some answers on here but it breaks the site with server error 503.

return \Roots\view('partials.my-blade-file')->render();

The following pulls in the right file and it renders but it doesn’t compile the blade template

add_shortcode('my_shortcode', function ($atts = [], $content = null, $tag = '') {
    $template = get_template_directory() . '/resources/views/partials/my-blade-file.blade.php';
    ob_start();
    include($template);
    return ob_get_clean();
});

Any suggestion on how to get this to work?

In Sage 10 Roots\view is responsible for rendering:

    view('subfolder/some-template-file', [ // no file extension (`blade.php`)
        'some_parameter' => 'test123',
    ])->render();

The path to the template file is relative to the resources/views directory of the Sage 10 theme directory.
The constructor results in a View object whose render method returns the rendered template.

Tip: Add use function Roots\view; at the beginning of the PHP file so you can just use view(...) instead explicitly typing out the Roots namespace.

I have tried this and it just kills the site. So this is my actual code, see any issues?

use function Roots\view;

add_shortcode('slick_carousel_testimonials', function ($atts = [], $content = null, $tag = '') {
    return view('partials/components/slick-carousel-testimonials', [])->render();
});

This is what I get whenever I return that view method

Why is there a HTTP 503? Well, on that system error reporting is disabled, as it is a production system I assume. You should always do the theme development on a development or at least staging system and not directly on production.

I guess the error comes from a missing variable expected in the template file. Or maybe a namespacing issue? You can also check the server error logs in order to find out what exactly the reason is.

It is actually a local development server in debug mode within the bedrock framework, I still get the same error whatever is in the template.

What do you get with

var_dump(  view('partials/components/slick-carousel-testimonials', [])  );

as a quick debugging measure?

A whole lot of text including the rest of the page content, its quite long but this is a few lines unless you’re looking for something specific?

object(Illuminate\View\View)#1577 (5) { [“factory”:protected]=> object(Illuminate\View\Factory)#636 (20) { [“engines”:protected]=> object(Illuminate\View\Engines\EngineResolver)#629 (2) { [“resolvers”:protected]=> array(3) { [“file”]=> object(Closure)#628 (1) { [“this”]=> object(Roots\Acorn\View\ViewServiceProvider)#305 (3) { [“app”:protected]=> object(Roots\Acorn\Application)#329

Have you checked your server error logs, or sage.log? Something should be reporting a stack trace for that 503.

For proper developing you really need to have a way to see the PHP errors, warnings and even notices.

As for now you can use try ... catch to get the error printed:

use function Roots\view;

try {
  $output = view('partials/components/slick-carousel-testimonials', [])->render();
} catch ($e) {
  var_dump($e);
}

I don’t see a sage.log but in apache error logs I get - Failed to read FastCGI header

It still fails with the 503 error and doesn’t catch, if I substitute the view method with a random exception then the catch works as it should.

try {
    return view('partials.components.slick-carousel-testimonials')->render();
    // throw new \Exception('some error');
} catch (Exception $e) {
    var_dump($e->getMessage());
}

What’s in the partial you’re trying to return?

Well at the moment just some basic html, nothing special, I can make it just <div>hello world</div> and will get the same result.

I think the issue is or is in combination with Advanced Custom Fields, I used the shortcode in an ACF field and by compiling the blade template myself with this method. https://wyattblogs.com/posts/how-to-compile-a-string-using-laravel-blade

function bladeCompile($template, $data = []): string
{
    $filename = uniqid('blade_');

    $path = get_template_directory() . DIRECTORY_SEPARATOR . 'public/tmp';

    View::addLocation($path);

    $filepath = $path . DIRECTORY_SEPARATOR . "$filename.blade.php";

    if (!file_exists($path)) {
        mkdir($path, 0777, true);
    }

    file_put_contents($filepath, trim($template));

    $rendered = (View::make($filename, $data))->render();

    unlink($filepath);

    return $rendered;
}
 
add_shortcode('slick_carousel_testimonials', function ($atts = [], $content = null, $tag = '') {

    $templatePath = get_template_directory() . '/resources/views/partials/components/slick-carousel-testimonials.blade.php';

    return bladeCompile(file_get_contents($templatePath), []);

});

I realised it was creating over 700 tmp files of the blade view.

The shortcode works when not in the ACF I have set up so I will have to see whats going on there, maybe there’s something weird in my loop, but it was working as is in Sage 9.

Ok it turns out its a line I added in the App class in the beginning of the project when I was trying to get ACF to work in the first place, but I don’t need it.

https://discourse.roots.io/t/solution-how-to-get-acf-fields-on-templates-in-sage10/18086`

public function with()
{
    return [
        'fields' => collect($this->fields())->toArray()
    ];
}

if I remove this entry from the array then all renders fine!

Thanks for the help

Btw, you should strive for enabling logging/error reporting on your development server.
And I recommend using an editor with syntax highlighting and linting or an IDE (I currently use VSCode that is free and quite fast). This helps to catch most issues while writing the code.

I do do this and use VSCode, this didn’t seem to give any clear errors to the actual problem though in this case.