I am a freshly new jr fullstack dev and I am scared of Sage 9

When I first joined my company we were using Sage 8 and I did my first ever Wordpress site in it. I learned a lot about Wordpress during that project (I joined the company knowing very little baout Wordpress) but then we switched to Sage 9 literally just a month or so after that project was done. The switch to Sage 9 was in the works before I even joined but it wasn’t made official until a few months ago. Well I do not have a lot of backend practice besides that 1 project as I’m mostly used for Frontend tasks but because backend devs are very busy right now I’m getting paired with them to help them on backend and Sage 9 is VERY intimidating.

Controllers, classes, blade templating, the partial/content folders, my Atom text editor not being able to color blade Syntax so it’s grey and hard to read…

I have no choice but to man up and get better. We have the Sage 9 book and yes it is helpful, i’ve read almost all of it and took in some things but I am still very very crippled when it comes to Laravel. I feel like Sage 9 is very complicated and really miss Sage 8 but there’s no going back.

Does anyone have any advice? Is it as simple as just practice? Sage 9 scares me because there doesn’t seem to be a lot of resources for it. Are there other resources I can use to learn Sage9? I am shocked there aren’t any UDEMY/Lynda courses available for Sage… really surprised because that would make a lot of money.

1 Like

First, take a moment and breathe…

Sage can be simple — especially for a frontend developer — if you keep your focus on the right things. Here’s what I recommend focusing on and as well some tips.


Learning Blade should be a high priority. I find Blade helps me focus on the HTML and using the (processed) data — two very frontend skills. Here’s a few resources for learning Blade:


Here’s how the partials work:

  • In Sage, the Blade files live in resources/views/. Any reference to a Blade file from another Blade file is always an absolute reference based on this path.
  • Blade uses a dot notation for paths. This means that paths are notated like this:
    • Say we want to include a partial resources/views/partials/banner.blade.php:
      1. First we can drop the extension: .blade.php
      2. Then we can drop the view path: resources/views/
      3. Now we swap any slashes to dots: partials.banner
  • I believe you can use standard path notation (i.e. layouts/app), but you probably want to stick to dot notation for consistency.

Directives — all those @ symbols

Here’s a rundown of the directives that matter:

  • @extends – You’ll find this at the top of the WordPress template files (i.e. page-{slug}, post-{slug}, single, archive, etc. Sage follows the standard WordPress template hierarchy). It is used to extend the theme wrapper. Sage only ships with one of these: layouts.app. For the most part in Sage, this file is set and forget.

    • @yield – This is like a hook where the template that used @extends can include corresponding @sections. Out of the box, Sage’s layouts.app only yields a content section.
    • @section – Typically are just used in the hierarchy templates. Anything in here will be inserted into the layout we are extending at the corresponding @yield.
  • @include – your go-to for including other partials. You can optionally pass data to the partial in the second argument. The data needs to be an associative array so Blade knows what to name the variables on the other end.

    • Consider @include('partials.hero', $hero).

      $hero = [
          'title' => 'Sage can make frontend awesome',
          'subtitle' => 'Blade puts the focus on the content', 

      Inside partials.hero, Blade will give us the variables: $title and $subtitle.

      Alternatively, say you are working with a premade partial that expects to use $hero itself so it can use $hero['title] or $hero->title. Rather than rewriting the view and everywhere that included it, you can either pass the data like this:

      @include('partials.hero', ['hero' => $hero])
      // or 
      @include('partials.hero', compact('hero'))
      // compact() creates an associative array from the variable(s) 
      // in the current scope with the same name(s). You can do this 
      // with multiple values (e.g. compact('hero', 'villian'))

      I prefer the latter.

  • @if, @else and @isset – These conditional statements are useful for conditionally including bits of code. @isset is really helpful for fields or variables which are not required.

  • @foreach — These are great for looping through arrays (e.g. a list of staff members).

    @foreach($members as $member)
      <article class="c-staffMember">
          <span class="c-staffMember__name">{{ $member['name'] }}</span>
          <small class="c-staffMember__role">{{ $member['role'] }}</small>
        <div class="c-staffMember__bio">{!! $member['bio'] !!}</div>
        <!-- Use {!! !!} when you know the string has HTML -->


If you are struggling with Sage’s controllers, maybe ask one of the backend developers to wire them up for you. Here’s where you can find resources about controllers in Sage.


Atom does have syntax highlighting for Blade:


You both are amazing thank you so much I’m so glad I posted here

1 Like

I had luck understanding Controller better when I started explicitly removing logic from my templates.

For example, have you ever written this?

if(get_field('background_image')) {
  $backgroundimage = get_field('background-image');

if(get_field('featured_article') {
  $article_classes = "article-featured";

<article class="post-content <?=$article_classes?>" style="background-image: url(<?=$backgroundimage?>);">

With controllers you can get all that ugly PHP logic out of the template and just let the template be a template. Here’s how:

In the appropriate controller file (I’ll use App.php presuming this data will be needed globally):

public function backgroundimage() {

  // Check wether the `background_image` field has a value, if so, use it; if not, set a blank value
  $return = (get_field('background_image')) ? get_field('background_image') : '';

  // Always return
  return $return;

public function articleclasses() {
  // Check wether the `featured_article ` field is true. If not, return a blank value.
  $return = (get_field('featured_article')) ? 'featured-article' : '';

  // Always return
  return $return;

This creates two variables, named for the function names in the controller: $backgroundimage and $articleclasses which are available to every template:

And then in your blade file you can just do this:

<article class="post-content {{ $articleclasses }}" style="background-image: url({{ $backgroundimage }});">

Clean, easy to read, and keeps the setup of your data, and the display of that data, separate. It lets templates be templates.

This is an extremely simple example but hopefully helps outline what Controllers are for.


Thank you very much. Your example is great and very clear and it is super helpful. I feel like things are a lot less complicated or at the very least I have a much better understanding now than before I posted here.

1 Like

This topic was automatically closed after 42 days. New replies are no longer allowed.