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?