Best Practice / Resources for Blade

Regarding your last two replies:

3 Likes

I didn’t know about the new controller file structure until I did a composer update and everything broke. But after I moved all the controllers to app/controllers it still does not work. I get this error:

Uncaught ReflectionException: Class App\\Controllers\\template-home does not exist in /app/wp-content/themes/asdf/vendor/soberwp/controller/controller.php

Full error below

[Mon Oct 30 16:05:49.409392 2017] [:error] [pid 1366] [client 172.17.0.1:43296] PHP Fatal error:  Uncaught ReflectionException: Class App\\Controllers\\template-home does not exist in /app/wp-content/themes/asdf/vendor/soberwp/controller/controller.php:19\nStack trace:\n#0 /app/wp-content/themes/asdf/vendor/soberwp/controller/controller.php(19): ReflectionClass->__construct('App\\\\Controllers...')\n#1 /app/wp/wp-includes/class-wp-hook.php(298): Sober\\Controller\\loader('')\n#2 /app/wp/wp-includes/class-wp-hook.php(323): WP_Hook->apply_filters(NULL, Array)\n#3 /app/wp/wp-includes/plugin.php(453): WP_Hook->do_action(Array)\n#4 /app/wp/wp-settings.php(448): do_action('init')\n#5 /app/wp-config.php(125): require_once('/app/wp/wp-sett...')\n#6 /app/wp/wp-load.php(42): require_once('/app/wp-config....')\n#7 /app/wp/wp-blog-header.php(13): require_once('/app/wp/wp-load...')\n#8 /app/index.php(4): require('/app/wp/wp-blog...')\n#9 {main}\n  thrown in /app/wp-content/themes/asdf/vendor/soberwp/controller/controller.php on line 19, referer: http://localhost:3000/about-us/management-team/```

@YarGnawh If you did a direct copy of the controllers, make sure to check your namespace and class names.

Your file should be app/controllers/template-home.php with something along this in the file:

<?php
namespace App;

use Sober\Controller\Controller;

class TemplateHome extends Controller
{
    //
}
1 Like

hey @Webstractions, thanks for the help. That’s exactly what I have

<?php

namespace App;

use Sober\Controller\Controller;

class TemplateHome extends Controller
{
	public function heroCarousel()
    {
        return get_field('hero_carousel');
    }
}

One thing I did find out is that, in my composer.json soberwp/controller was using dev-master. After changing it to ~9.0.0-beta.4 , everything started working again. So I guess it’s something in the changes after beta4 that is breaking it.


  "require": {
    "php": ">=7",
    "composer/installers": "~1.0",
    "illuminate/support": "~5.4",
    "roots/sage-lib": "~9.0.0-beta.4",
    "soberwp/controller": "~9.0.0-beta.4"
  },
1 Like

Yeppers. I forgot about that little nugget. Glad you found it.

I spoke too soon. There seems to be a new issue,

It appears that

<html @php(language_attributes())>

and many other @php() directives (not all) no longer works. When looking in the compiled files in cache, it outputs <?php without closing ?>

At the moment, the only solution I found is replacing @php() with @php .... @endphp.

I’m not sure if this is a bug or an update. If it’s an update, the composer create-project will need an update.

Weird. <html @php(language_attributes())> works for me.

That appears to be a ~5.5 issue. Sage is currently using ~5.4

I, and some others, have upped our composer.json requirement to 5.5 and have had no ill effects except for using the new if() method for creating blade directives. One additional thing I did is I have my own fork of sage-lib which is also using 5.5.

Just dawned on me, you don’t need to use the @php directive for functions. You can do this as well:

<html {{ language_attributes() }}>

and for functions that return a string that you want to echo

<span>{{{ get_the_date() }}}</span>

In the latter case, muscle memory usually prevails and I just <?= get_the_date(); ?> without even thinking about it.

4 Likes

Can you explain what’s being done with ACF Gallery here that couldn’t just be done with…

  function logo_gallery()
  {
    $logo_gallery = get_field('logo_gallery');

    return $logo_gallery;
  }

Hi there. The filter makes the results available to the blade template via that $data variable. That was the way to do it back when I made that post.

I’m pretty sure it predates the Controller plugin, so keep in mind that things have changed a bit and I’m not fully up to speed.

That said, the function is just filtering the $data variable, which is a global variable available to templates.

So it:

  • Takes $data as it’s input,
  • Checks to see if there’s images available and,
    • if yes, adds them to the $data variable with the key images so, $data['images']).
  • Returns the filtered $data variable to the script.

Meanwhile, back at the template, the contents of the variable $images is now available to the template, via $data.

Does that make sense?

Oh right. So your original method was adding the ACF Gallery to an existing variable, where my method is just creating a new variable to store the same information?

I couldn’t get yours working because of ā€˜unexpected add_filter’ errors, so perhaps things have changed with the introduction of the controller…

1 Like

Exactly! If I remember correctly it’s now handled by the Controller, so no need for the filter.

Did you get it sorted? Looking at the Controller docs it’d be something like:

<?php

namespace App;

use Sober\Controller\Controller;

class Single extends Controller
{
    public function logo_gallery()
    {
        return get_field('logo_gallery');
    }
}
1 Like

Oh yeah, the code I posted above was working :smiley:

Another ā€˜best practice’ question. How do you go about querying the $post if it’s not set yet in app.php. Say I want to get the featured image, I’ve had to add $post = get_post(); like this, but I have no idea if I’m doing this right…

    public function featured_image()
    {
        $post = get_post();
        $featured_image = get_the_post_thumbnail($post->ID, 'large', array('class' => 'img-fluid'));

        return $featured_image;
    }

I think you need to use a static method for that.

Not sure about that, adding static broke it, but I can make that one function a line shorter at least…

    public function featured_image()
    {
        $featured_image = get_the_post_thumbnail(get_post()->ID, 'large', array('class' => 'img-fluid'));

        return $featured_image;
    }

Side note, if anyone’s got a working example of an ACF Relationship field with permalink and featured image I’d love to see it. Got me absolutely beat atm.

This works, but again I’m not sure if this is in the spirit of what Blade was intended for…

  function services_featured()
  {
    $services_featured = get_field('services_featured');

    return $services_featured;
  }
      @if($services_featured)
      <div class="card-deck">
        @foreach($services_featured as $p)
          <div class="card">
            {!! get_the_post_thumbnail($p->ID, 'card-hdr',  array('class' => 'card-hdr-img')) !!}
            <div class="card-body">              
              <h2><a href="{{ get_the_permalink($p->ID) }}">{{ get_the_title($p->ID) }}</a></h2>
            </div>
          </div>
        @endforeach
      </div>
      @endif

@Simeon Something like this.

function services_featured()
{
    $fields = get_field('services_featured');
    $services_featured = [];
    foreach($fields as $field)
    {
        $service = [];
        $service['thumbnail'] = get_the_post_thumbnail( $field->ID, 'card-hdr',  ['class' => 'card-hdr-img'] );
        $service['permalink'] = get_the_permalink($field->ID);
        $service['title'] = get_the_title($field->ID);
        $services_featured[] = $service;
    }
    return $services_featured;
}
@if($services_featured)
      <div class="card-deck">
        @foreach($services_featured as $p)
          <div class="card">
            {!! $p['thumbnail'] !!}
            <div class="card-body">              
              <h2><a href="{{ $p['permalink'] }}">{{ $p['title'] }}</a></h2>
            </div>
          </div>
        @endforeach
      </div>
 @endif
5 Likes

Yeah that’s more like what I had in mind but couldn’t get there. Thanks!!!

@Simeon, I have it working as a static function inside app/controllers/app.php, inside the App class. I modified it a bit:

public static function featured_image($class)
{
    $featured_image = get_the_post_thumbnail(get_post()->ID, 'large', array('class' => $class));
    return $featured_image;
}
1 Like

Have you been able to work out a more eloquent solution?