# Components

Fundamentally, Components don't do anything you couldn't also accomplish with partials and Composers, but they provide system of interaction and a mental model that can be more intuitive. Like Composers and Blade templates, Components are an extension of the Laravel feature, so the Laravel documentation (opens new window) applies.

Generally a Component consists of:

  1. A Blade template in /resources/views/components/.
  2. A Composer-like class in /app/View/Components/.

The easiest way to create a component is with WP-CLI:

$ wp acorn make:component ExampleComponent

Sage also ships with some examples.

TIP

You can also create inline (opens new window) and anonymous (opens new window) components, which forgo the template or class respectively. These would need to be created manually (the WP-CLI command only creates "traditional" components).

# Usage

A Component in action in a Blade template will look something like this:

<x-example-component title="Example Component" :image-id="$image"/>

The template for that Component might look like this:

<div {{ $attributes }}>
    <h3>{!! $title !!}</h3>
    @if($imageElement)
        <figure>{!! $imageElement !!}</figure>
    @endif
</div>

In turn, the class might look like this:

namespace App\View\Components;

use Roots\Acorn\View\Component;

class ExampleComponent extends Component
{
    public $title;
    public $imageElement;

    protected $imageId;

    public function __construct($title, $imageId = null) {
        $this->title = $title;
        $this->imageId = $imageId;
        $this->imageElement = $this->getImage();
    }

    protected function getImage()
    {
        if (!is_numeric($this->imageId)) {
            return false;
        }
        
        return wp_get_attachment_image($this->imageId, 'medium_large');
    }
}

# Argument and attribute names

The names of the arguments in the definition of your Component's __construct() method must match the names of the attributes you use to pass data to your Component tag.

Note

Component constructor arguments should be specified using camelCase, while kebab-case should be used when referencing the argument names in your HTML attributes. Laravel documentation (opens new window)

In the above example

<x-example-component title="A Component"/>

will work, but

<x-example-component theTitle="A Component"/>

will throw an error.

The attributes used to pass data to your Component tag can be in any order, so long as the names are correct:

<x-example-component title="The Title" :image-id="$image"/>
<x-example-component :image-id="$image" title="The Title"/>

These are equivalent.

# Passing data

By default, anything passed to an attribute on a Component tag will be treated as a string. So if you do this:

<x-example-component title="$variable"/>

Your component will treat that as a string containing $variable, not whatever the contents of $variable is.

If you need to pass non-string data, just prefix your attribute with a colon, and its value will be evaluated as PHP:

<x-example-component :title="$variable"/>
<x-example-component :title="get_my_title()"/>
<x-example-component :title="TITLE_CONSTANT"/>

Note

Because your argument is now evaluated as PHP, you don't want to pass a simple string, or PHP will try and evaluate it:

<x-example-component :title="Uh oh"/>

This will throw an error when it tries to evaluate Uh oh as PHP.

# Data in views

The view for your Component (in the above example, /resources/views/components/example-component.blade.php) does not receive the arguments you pass to the Component tag; The data it has access to is limited to any public properties you've set on your class.

So remember to set those properties, or your view won't have the data you need!

# Other attributes

In the Component tag, you use attributes to pass data to your component, but you can also add other, arbitrary attributes as well. These attributes will be put in an "attribute bag" which you can then access in your Component view with the special $attributes variable. If you echo the variable it will print out each attribute and its value, which is very useful for things like passing CSS selectors to your Components:

<x-example-component title="Styled Component" 
    class="bg-color-red text-color-white"/>
<!-- yields... -->
<div class="bg-color-red text-color-white">
...

You can do many other things with attributes that are described in the Laravel documentation (opens new window).

Page authors:

code23-isaac
Branden
Ben
Sponsor us on GitHub to help us grow 🌱