Roots Discourse

Shortcodes that use Blade templates and get Controller data

blade
sage9

#1

I’m learning all kinds of things today.

Here’s how I got a shortcode to include and process a Blade template and receive Controller data if available. Maybe not the most wide appeal, but here’s the code:

app/lib/shortcodes.php

<?php
namespace App;

/**
 * Add the shortcodes
 */
add_action( 'init', function() {
  add_shortcode('resources', function() {

    // Start object caching or output
    ob_start();

    // Set the template we're going to use for the Shortcode
    $template = 'partials/shortcodes/shortcode-resources';

    // Set up template data
    $data = collect(get_body_class())->reduce(function ($data, $class) use ($template) {
        return apply_filters("sage/template/{$class}/data", $data, $template);
    }, []);

    // Echo the shortcode blade template
    echo Template($template, $data);

    // Return cached object
		return ob_get_clean();
  });
});

With the above, partials/shortcodes/shortcode-resources.blade.php will have all the template data and context it would have if it was part of the template it was called in.

Woo!


How can I return a view from an ajax call
Calling Controller (App.php) functions from setup.php (and other controllers)
Ajax: get partial blade template
The correct way to add shortcode
#2

I had occasion to reuse this code today, but needed to get data from a Taxonomy along with it. Here’s how I got the data and made it available in the Blade template:

<?php
namespace App;

/**
 * Add the shortcodes
 */
add_action( 'init', function() {
  add_shortcode('creator', function($atts, $content = null) {

    // Extract the shortcode attributes
    $atts = shortcode_atts( array(
      "slug"      => false,
    ), $atts );

    // Start object caching or output
    ob_start();

    // Set the template we're going to use for the Shortcode
    $template = 'partials/shortcodes/shortcode-creator';

    // Set up template data
    $data = collect(get_body_class())->reduce(function ($data, $class) use ($template) {
        return apply_filters("sage/template/{$class}/data", $data, $template);
    }, []);

/** **********************
* This is the new part
 ********************** **/

    // Get the term, by slug, and append it to the data array
    $data['creator'] = get_term_by('slug', $atts['slug'], 'creator');

/** **********************
* End new part
 ********************** **/

    // Echo the shortcode blade template
    echo Template($template, $data);

    // Return cached object
		return ob_get_clean();
  });
});

Then in shortcode-creator.blade.php:


<section class="row creator">
  <article class="col-md-8">
  <h3>
    {!! $creator->name !!}
    <div><small>{!! get_field('title', $creator) !!}</small></div>
  </h3>
    {{ $creator->description }}
  </article>
  <figure class="col-md-4">
    <img class="img-fluid" src="{{ get_field('creator_photo', $creator)['url'] }}">
  </figure>
</section>

This could all be made even simpler by calling my get_field()s in the shortcode definition, too.

Hope this is useful to someone!


#3

Shortcodes with Blade templates would be awesome, but seem like this is an old solution.

Can you explain how to do this in the current version?

Best regards.


#4

Does something about this method no longer work? Are you seeing an error? What indicates to you that this solution is no longer valid?


#5

Hi. Thank you for your quick answer.

I’m try to apply the solution and not working, so I searched for that Template() and I found this in the changelog of 9.0.0-alpha.1: “Remove Template class”.

I’m new in Roots stack, so maybe I missunderstooding the solution to use Blade templates in shortcodes.

Regards.


#6

The template function still exists and takes the same parameters so it should be as easy as using a loswercase t for template(). If that doesn’t work you can use the full namespace: \App\template().


#7

it should be as easy as using a loswercase t for template()

That’s it. It’s working. :slight_smile:

Very thank you!


#8

Yes still working for me as well.


#9

Hello,

I’m pretty new to Sage/Blade. Actually, this is my first post here.

Yesterday I used controller data (from ACF) in template file by following methods described here: https://github.com/soberwp/controller

I see your solution is quite different, so I’m a bit confused now. Am I missing something?

Best,
Damir


#10

This is an old topic and Controller has been updated since this discussion. If you’re looking for help you’ll have to provide us with the changes that you’ve made since we don’t have any insight into your theme.


#12

Curious if anyone else has experienced issues with Gutenberg and including shortcodes created in this fashion.

I have a shortcode that I"m rendering with the shortcode block in Gutenberg. When editing that page in the gutenberg editor, clicking on any block on that page yields this error:

I think it’s being caused by the below line (in the call to \App\template()) since if I remove this line and instead just return an empty div things work as expected (minus the shortcode rendering).

echo \App\template($template, $data);

Can anyone else reproduce this?

edit:
Also, I receive these error messages in the browser console ONLY when the call to \App\template() is active in the short code. Not sure if related to the core issue i’m observing or just a side effect.