Contextual components in PHP

Caution! This article was published over a year ago, and hasn't been updated since. Situation, software and support of the topic below could have changed in the meantime.

Colloq's approach

In the article "Better Design System Component Semantics" Holger Bartel presents the technical approach of colloq.io to work with components/partials - but also to give them a semantic context.

He shows this with the example of a card component for conference speakers. This is output in at least two places:

a) In a list of multiple speakers
b) On a single speaker page

So we're dealing with a li element in case a), and e.g. a div element in case b). He solves this by using a partial function ($this->partial()) and passing the contextual data like this (for the sake of readability I changed his examples to PHP's short syntax for array and echo):

// View looping through a collection of speakers
<?= $this->partial('Components/SpeakerCard/Default', [
    'speaker' => $speaker, // The speaker data itself
    'element' => 'li' // Context li
]) ?>

// Partial file 'Components/SpeakerCard/Default'
<?php if ( !isset( $element ) ) $element = 'li'; ?>

<<?= $this->escape( $element ) ?> class="speaker-card">
    <p>SpeakerCard content here</p>
</<?= $this->escape( $element ) ?>>

Laravel Blade

If you are planning a similar approach in a Laravel app, the @include directive is available in the blade template system. Code above would look like this:

// View looping through a collection of speakers
@include('speaker.card', [
    'speaker' => $speaker,
    'element' => 'li'
])

// Partial file 'resources/views/speaker/card.blade.php'
// (example file name and path within resources/views)
<{{{ $element ?: 'div' }}} class="speaker-card">
    <p>SpeakerCard content here</p>
</{{{ $element ?: 'div' }}}>

ProcessWire's wireRenderFile()

My favorite CMS/F ProcessWire has the wireRenderFile() function (see introduction blog post). In ProcessWire you would solve the problem as follows:

// View looping through a collection of speakers
<?php echo wireRenderFile('partials/speaker/card',  [
    'speaker' => $speaker,
    'element => 'li'
]);

// Partial file 'site/templates/partials/speaker/card.php'
// (example file name and path within site/templates)
<<?= $element ?: 'div' ?> class="speaker-card">
    <p>SpeakerCard content here</p>
</<?= $element ?: 'div' ?>>