How to add Featured Video functionality to a blog

HubSpot Moderator

I came across a case recently where it was suggested I document some of the methods we used (cc @mnonnamaker who also did a lot of work here). Maybe this will help people building something similar in the future. The goal here was to build a module for a blog that enables the blog post author to use a featured video instead of a featured image on the post. And in the case where they were using a featured image, to have a separate field for custom alt text for the featured image.

 

You'll need to create a module and add it to the blog template. It should have fields for a featured video and also for custom alt text.

 

Then in the blog post template you'll need to loop through the module data. These are stored in the content.widgets dictionary. So if you loop through like this:

 

 

{% for module in content.widgets %}
  {# in each loop iteration, module will represent the data for a different module on the post #}
{% endfor %}

 

 

...you can access each module in a loop iteration. You can look for a specific module by using something that identifies that module. So for example, each module will have an ID stored in module_id . So if we're looking to see if our featured video field has been filled out, let's first look for the module by its ID:

 

 

{% if module.module_id == "XXXX" && !module.deleted_at %}
  {# we've now found the module we're looking for, so let's search for the field we want #}
{% endif %} {# end if module.module_id == "XXXX" #}

 

 

I've also added a check ^here to make sure you're only finding a non-deleted version of our module. Otherwise whatever you're trying to do might print multiple times. And after we've found our module, we need to search for the field. Then we can print our field to the page with something like: {{ module.body.featured_video }} . And then also we can add an else statement for when we don't find a value in our field:

 

{% if module.module_id == "XXXX" && !module.deleted_at %}

  {% if module.body.featured_video %}

    {{ module.body.featured_video }}

  {# else if our module doesn't have a featured video value #}
  {% else %}

    {# print an img tag #}
    {# if the module has a featured_image_alt value, use that for the alt text. if not, use content.featured_image_alt_text #}
    <img src="{{ content.post_list_summary_featured_image }}" class="hs-featured-image" alt="{% if module.body.featured_image_alt %}{{ module.body.featured_image_alt }}{% else %}{{ content.featured_image_alt_text }}{% endif %}">
  
  {% endif %} {# end if module.body.featured_video #}

{# endif #} {# end if module.module_id == "XXXX" #}

So in total our code would look like this:

 

{# loop through the modules #}
{% for module in content.widgets %}

  {# look for our specific module, and also the non-deleted version of it #}
  {% if module.module_id == "XXXX" && !module.deleted_at %}
    
    {# we've now found the module we're looking for, so let's search for the field we want #}
    {% if module.body.featured_video %}

      {# print that value #}
      {{ module.body.featured_video }}

    {# else if our module doesn't have a featured video value #}
    {% else %}

      {# print an img tag #}
      {# if the module has a featured_image_alt value, use that for the alt text. if not, use content.featured_image_alt_text #}
      <img src="{{ content.post_list_summary_featured_image }}" class="hs-featured-image" alt="{% if module.body.featured_image_alt %}{{ module.body.featured_image_alt }}{% else %}{{ content.featured_image_alt_text|escape }}{% endif %}">
    
    {% endif %} {# end if module.body.featured_video #}

  {# endif #} {# end if module.module_id == "XXXX" #}

{% endfor %} {# end for module in content.widgets #}

I hope that's helpful to someone. Feel free to leave comments with any questions.

 

 - Leland

Leland Scanlan

HubSpot Developer Support
5 Replies 5
Esteemed Advisor

@lscanlan ,

 

This is awesome. I did not know you could access module data that way in the template and that has a ton of applications. Thanks for sharing.

- Jonathan Sumner
Reply
0 Upvotes
HubSpot Moderator

Thanks Jonathan! I figured it could give us something helpful to reference, and then others could build off it. Glad you found it useful.

Leland Scanlan

HubSpot Developer Support
Reply
0 Upvotes
Occasional Contributor

Nice, but how did you get the module fields value?

 

In the dict object I get there is just a body object, from which I can get only field names (field_type is an obj like:

field_types={color_field=color, boolean_field=boolean}

). Actual values of fields seem just a dirty dream.


Nice to know:
- Content.widgets seems to be updated only at page publish (making debugging a pain) 
- There are typos in your code (sometimes you forget .body to target right element)

Is there ANY link to ANY documentation about this?

Reply
0 Upvotes
HubSpot Moderator

Hi @Tirabuchi,

 

Could you let me know where you're seeing typos? For what it's worth, I did just notice that I mixed up some of my delimiters. I just went back in and fixed what I found, so thanks for pointing it out. But if you could let me know if I'm still missing something, that's really helpful.

 

And yes, the page's content model updates when you publish a page. So if for example you're working on a blog, and if you're trying to get values from a blog post into a listing page, you'd need to update the blog post. But if you're working on just a page or just a blog post, those values will pull through to the preview.

 

As for where to get the module field values, they should be showing up in that same body. So they'd be accessible as {{ module.body.field_name }} . I think the default values from a module may not be accessible, so you'd need to update the module's fields for them to be exposed here. But once you do, you should see them coming through. If you're not I'm happy to take a look at a specific example.

 

As for documentation, I don't know if we have a doc on accessing module field values like this, so I'll bring it up to see if we can get it added. But if you haven't seen it yet, I'd suggest reading our doc here: https://designers.hubspot.com/docs/hubl/how-to-use-developer-info-on-cos-pages. It basically shows you how to find all the values that are exposed on that page. It's not exactly what you're looking for, but you might find it helpful.

 

Leland Scanlan

HubSpot Developer Support
Reply
0 Upvotes
Highlighted
Occasional Contributor

Hello @lscanlan,

Thank you for the reply.
I didn't think that default content would have not been evaluated, idk if I should feel dumb or it is actually a strange behaviour.
Yes, I missed out the "developer info" button completely (everything I did to pass data through modules is by Js and JQuery. I still don't know which process is better though, both seem to have upsides and downsides), I think a link in the documentation (ie. in https://designers.hubspot.com/docs/hubl/hubl-supported-variables , in {{content}} description) would be pretty useful.

Regarding the typos, (I made a fast check) in the code recap:

module.module_id

should be

module.body.module_id

Anyways, now that I checked full JSON I have a much clearer idea, thank you. I'll do some testing (between speed of scripts, reliability of JSON data and scalability in the marketplace for both) and try to understand which is better.

Reply
0 Upvotes