Displaying different types of content in the same views can introduce more logic than you might like. An easy refactor is to use polymorphism and Blade’s @include directive to remove conditionals and make the view easier to read.

Lets say you have an article. That article has one or more attachments and the attachment can be a downloadable file, embed code for something like YouTube or Vimeo, or a URL to another website. It is very likely that you have a different way of displaying each of these attachments. Maybe it is as simple as an icon that precedes some text or as complicated as introducing photos or accessing additional data to generate the view.

Lets stick with the simple example for this article and assume that we have slightly different, but simple layout for each type.

Since each of these attachments require their own html block to be displayed, you might reach for and if else conditional.

@foreach ($attachments as $attachment)
    <div class="attachment">
        <h4 class="title">{{ $attachment->title }}</h4>
        @if ($attachment->type == 'file')
            <p>
                <a href="{{ $attachment->file_path }}">
                    Download this file: {{ $attachment->name }}
                </a>
            </p>
        @elseif ($attachment->type == 'embed')
            <h4>Watch the Video</h4>
            <div class="embed-attachment">
                {{ $attachment->embed_code }}
            </div>
        @elseif ($attachment->type == 'url')
            <p>
                <a href="{{ $attachment->url }}">
                    Visit {{ $attachment->name }}
                </a>
            </p>
        @endif
    </div>
@endforeach

While this would work just fine, I personally try to eliminate conditionals wherever I can as long as the code needed to do so doesn’t introduce more complexity than the code I'm trying to eliminate. In this case, introducing a bit of polymorphism will help make the code more readable.

Step 1

First we'll extract the HTML to display each type of attachment into a partial. The partial name will contain the type of attachment. E.g. A downlodable file partial might be named be file-attachment.blade.php and an embeded media attachment might be embed-attachment.blade.php.

That would leave us with the following partials.

file-attachment.blade.php

<p>
    <a href="{{ $attachment->file_path }}">
        Download this file: {{ $attachment->name }}
    </a>
</p>

embed-attachment.blade.php

<h4>Watch the Video</h4>
<div class="embed-attachment">
    {{ $attachment->embed_code }}
</div>

url-attachment.blade.php

<p>
    <a href="{{ $attachment->url }}">
        Visit {{ $attachment->name }}
    </a>
</p>

Step 2

Now that we have individual partials containing the code we need to display each type, it's simply a matter of including the partial for the attachment type.

@foreach ($attachments as $attachment)
    <div class="attachment">
        <h4 class="title">{{ $attachment->title }}</h4>
        @include("{$attachment->type}-attachment")
    </div>
@endforeach

I personally find this technique very useful in some cases. Like anything, don’t reach for it by default but if the shoe fits…