View Composers were not intended to be mixed with View Components– and it’s not necessarily clear to me a situation where they should be.
Sage 10’s Composers are provided by Acorn as a means to replace Sage 9’s Controllers with a more appropriate implementation. It gives you a means to target views and their partials in an effective, non-hacky way (e.g. Sage 9 used body classes ).
View Components were recently introduced in Laravel 7 and came after our “Composer” concept. While it has a very familiar feel to a Composer, it does not allow you to target and send data to multiple views/partials – it will only pass it to the view rendered via the render()
method in the Component.
Are you building a card? A hero/header that accepts different background images, colors, subtitles, descriptions? Use a component.
Maybe you want to build a “Post” component that allows you to specify a couple styles such as card
, tile
, and when nothing is specified, it will default to entry
–
<?php
namespace App\View\Components;
use Roots\Acorn\View\Component;
class Post extends Component
{
/**
* The card type.
*
* @var string
*/
public $type = 'entry';
/**
* The current post.
*
* @var mixed
*/
public $post;
/**
* Create the component instance.
*
* @param string $type
* @param mixed $post
* @return void
*/
public function __construct($post = null, $type = null)
{
$this->post = $post ?? get_the_ID();
$this->type = $type ?? $this->type;
$this->withAttributes(['class' => get_post_class(false, $this->post)]);
}
/**
* The post title.
*
* @return string
*/
public function title()
{
return get_the_title($this->post);
}
/**
* The post excerpt.
*
* @return string
*/
public function excerpt()
{
return apply_filters('the_excerpt', get_the_excerpt($this->post));
}
/**
* The post content.
*
* @return string
*/
public function content()
{
return str_replace(
']]>',
']]>',
apply_filters('the_content', get_the_content())
);
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return $this->view('components.post.' . str_replace('.', '-', $this->type));
}
}
In the Post component we provide the $title
, $content
, and $excerpt
of the current (or specified) post to the views rendered by the component.
In its simplest form, <x-post />
would render components.posts.entry
passing it the details for the current post in the loop.
With our component constructor allowing type
and post
– we are also able to specify a post ID and/or type specifically:
<x-post type="card" post="13" />
If you need to pass a variable and/or function, you can prefix the key with :
<x-post :type="get_field('card_type')" />
Components become extremely powerful for getting specific jobs done.