1

I've got a use case where I'd like to be able to not only upload an image for a blog entry's "featuredThumb" but also have the ability to upload a video. I was originally using animated GIFs but they are huge. So much like twitter I'm going to switch them for videos.

Currently, I have something that I'm sure you'll be very familiar with. I've got an asset field within my blog section that accepts an image and my template code looks like this:

{% for entry in craft.entries.section('blog').find() %}
    <article>
        <a href="{{ entry.url }}">
            <img src="{{ entry.featuredThumb.getUrl("someTransform") }}" alt="{{ entry.featuredThumb.title }}">
        </a>

        <h3>
            <a href="{{ entry.url }}">
                {{ entry.title }}
            </a>
        </h3>
    </article>
{% endfor %}

I'd like to be able to switch the image for a small HTML5 video. This poses a few problems, as numerous video formats are required for cross browser compatibility, along with an image as a poster / fallback.

My current solution is to switch the "featuredThumb" asset field, for a new matrix field that contains two block types:

  • Image

    • Asset field - Name: Image
  • Video

    • Asset field - Name: Videos (allows multiple files so the user uploads MP4, OGV, WebM)
    • Asset field - Name: Fallback Image

Then in my template update to:

{% for entry in craft.entries.section('blog').find() %}
    <article>
        <a href="{{ entry.url }}">
            {% for block in entry.featuredThumb %}
                {% switch block.type %}

                    {% case "image" %}

                        <img src="{{ block.image.first().url }}" alt="{{ block.image.first().title }}">

                    {% case "video" %}

                        <video width="320" height="180" autoplay loop>
                            {% for video in block.videos %}
                                <source src="{{ video.url }}" type="{{ video.getMimeType() }}">
                            {% endfor %}
                            <!-- Fallback image for browser without <video> support -->
                            <img src="{{ block.videos.fallbackImage.first().url }}" alt="{{ block.videos.fallbackImage.first().title }}">
                        </video>

                {% endswitch %}
            {% endfor %}
        </a>

        <h3>
            <a href="{{ entry.url }}">
                {{ entry.title }}
            </a>
        </h3>
    </article>
{% endfor %}

This is the best solution I'm able to come up with, but it seems a little over-engineered. I'd love to see other people's take on this.

Cheers,

Tom

2 Answers 2

1

Tom, we applied the same technique to several clients. We also tried having one asset input and only allowing images and videos. Then as we loop through the asset field we check for media type. However I think breaking it up like you have, is a better user experience so they know to add either video or image. We have also added a plain text field and allowed them to add Vimeo/YouTube embed code for the video.

2
  • Thanks @aran. It's always nice to know you're not the only one... I like this way too as I can limit images to 1 asset and videos to say 3. It's interesting you mention Vimeo/YouTube embed code. We purchased Dukt's Videos plugin. Well worth the €49 if you ask me!
    – Tom
    Mar 10, 2015 at 23:30
  • We have used that same plugin, it is definitely worth it for a client that uses Vimeo/YouTube heavily.
    – a-am
    Mar 11, 2015 at 15:26
1

what I did is instead of using a Matrix I simply use a Asset field type and Restrict allowed file types of only Image and Video in the field settings.

When you loop through the asset field in the entry do a switch on the element 'kind' to determine if it's a video or an image and output the tag accordingly.

Here's the sample code I wrote for my project where I populate a homepage slider called 'Swipey' with images or video.

  {% for block in entry.homepageslider %}

    {% for hero in block.heroimage %}

      {% set imgURL = hero.url %}
      <div class="swiper-slide">
        <div style="position:absolute; top:40px; left:40px; color:#ffffff; ">
          <div style="font-size:30px; line-height:.9em; text-align: left; margin:0; padding:0; "> {{ block.category }} </div>
          <div style="font-size:70px; line-height:.9em; text-align: left; margin:0; padding:0; "> {{ block.title }} </div>
        </div>

        {% switch hero.kind %}

          {% case "image" %}

            <a href="{{ block.url }}">
              <img src="{{  imgURL }}" />
            </a>

          {% case "video" %}
            <video width="100%" height="100%" preload= "true" loop = "loop" muted>
              <source src="{{  imgURL }}" type="video/mp4">
              Your browser does not support the video tag.
            </video>

        {% endswitch %}

      </div>

    {% endfor %}

  {% endfor %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.