Confirmation on adding and accessing fields in blog posts

Howdy, I am doing a bit of a training exercise and was hoping to get some confirmation on one aspect of the blog feature, thanks for looking…

It seems that `

blog_post`

instances, “blog posts”, are architected by HubSpot to start as a very simple RTE/body area with very few additional built-in author fields: title, featured image, meta description, author field, tagging and so on. I assume it’s intended as a clean and simple way authors can focus on writing, which makes sense to me for sure. Yes DnD is an optional addition, but ideally they’re not doing crazy amounts of building in a blog post, but anyway…

Given a requirement for, say, even just one additional blog post field at a “page level” for a simple blog post, so far I have identified you can either:

  1. Use a custom module, with even just a simple single primitive-ish field if you want, like text.
    1. The custom module can be then be embedded within the

      `blog_post`

      template, thereby categorizing it as a “static module” when looking at the Content pane. In addition to the Content pane, the author can actually also see it within the body content and click it in the page which opens the Content pane for them. This is quite nice.

    2. The custom module could be drag-and-drop by the author. But given the requirement in my example is to have this field by default in the `

      blog_post`

      workflow, we can ignore this option for now.

  2. Alternatively, it appears you can also use the module HubL tag syntax within the `

blog_post`

template with `

export_to_template_context

` set to true.

  1. This puts the module instance in the Content pane inside a section called “Hidden Modules,” (really not my favourite name, but I get the reference to Visibility.) This time the author can only see the value if they physically click on the Content pane to edit it, there would not be anything for them to see and click on in-page. (Read: they have to know via training to set it, which I like less.)

Firstly, I would just like to confirm are these the two standard methods for adding a new/custom field to a blog_post template?

Now more importantly, working with “the loop”… so rendering the content in the `

blog_post

` template in those cases above is straight forward. However, rendering the content within a loop of items from, say, `

blog_recent_tag_posts

` inside a `

blog_listing

` might force our hand here…

From what I have tested thus far, [again, new and training so please correct me if..] the only method I’ve found to be able to access the content from the custom field methods above within the loop is via the `

export_to_template_context

` syntax option (2) above.

I’d like to pause here and ask, is this also correct, has anyone seen another method?

Finally, the documentation on this feature says:

export_to_template_context=True is not supported in custom modules, as it serves no real purpose for them. You do not need to use export_to_template_context to get the value of a module within a template, you can already access it.

While it’s true you can access content “on page” with any method, it does seem odd to me that I can’t access a custom modules’ instance values while running through the loop unless I use a specific method. Now, perhaps I’ve missed it in the docs, but I was hoping you could confirm this, or show an alternative if it’s possible. At then end of the day I like how the custom module is visible/click-able in the post [if you want it to be], but am not able to find information on how to access that method in a loop.

Thanks very much!

Allan

Hey @a-rogers,

welcome to HS development and great job on the analysis so far.

To answer your questions:

  1. Yes, the blog_listing and blog_post templates are a bit different when it comes to dnd. Modules added to the template will be displayed as “static” ones but there are several workarounds for this.
  2. To be honest, I’m using export_to_template_context only very rarely as modules with this setting are mostly used for template modification and I don’t want to provide a bunch of stuff to the user that he might not need. Therefore I’m creating just a bunch of custom modules for specific use-cases and let the user decide what he wants to use ← this is also a best practise / recommendation.
  3. You can access “the loop” inside custom modules and modify it to your needs - as mentioned, I’m using custom modules where ever I can.

For the fun part (workarounds):

Before the blog post had a dnd function, the only way how devs could modify the blog post layout was basically a custom module with an if-statement or for-loop (or a combination of both). The idea was to create a choice field with all the different layouts and options the client requested and let him use it.

This means that the custom module looked a bit like this

{% for element in module.blog_rows %}
 {% if element.layout == "image" %}
 <img src="{{element.image_element.image.src}}" alt="{{element.image_element.image.alt}}" class="custom-image">
 {% elif element.layout == "post_body" %}
 {{ element.post_body }}
 {% elif element.layout == "author_box" %}
 <div class="author-box-wrapper"></div>
 {% endif %}
{% endfor %}

The good thing about the for-loop is that you can rearrange the elements - giving you a somewhat dnd type of experience.

As of today - this still works.

This means that you can technically put the {{ content.post_body }} function into the custom module and replace it in the blog_post template with the custom module one.

Would I recommend it - not for most use cases because you will end up creating custom modules for the listing template as well.

It’s easier to create seperate custom modules with dedicated layouts and functionalities and just let the user ‘dnd’ it these days.

Also - if you got HubDB, the world is yours :slightly_smiling_face:

You can do A LOT, and I mean really A LOT with HubDB that isn’t documented.

You just have to be creative. Like creating an image gallery using just the rich-text of HubDB.

Just put all image paths into it, seperate it by comma and then in the template/module do it like

{% set hubdb_rows = ... %}
{% set images = hubdb_rows.images|split(",")

{% for image in images %}
 <img src="{{image}}" alt="this is an image in a loop">
{% endfor %}

or toggle whole sections on/off in a dynamic hubdb page template

When it comes to blogs, something I’ve done in the past was creating a custom module with HubDB for a way more advanced author display box.

Just stored all the required informations in HubDB rows and created an if statement that matched the Authorname to the authorname column and displayed all the infos from HubDB.

hope this helps

best,

Anton

Hi @a-rogers ,
Yes, these are the two standard methods for adding custom fields to blog posts:

  1. Custom modules (embedded in blog_post template as static modules)
  2. Module HubL tags with export_to_template_context=true

Unfortunately, there is no alternative method to access custom module data in loops without using export_to_template_context=true. The HubSpot documentation you referenced is correct - this is the intended behavior and limitation.

Given your requirement, use the export_to_template_context=true method since you need loop access. To improve the author experience, you can add clear labeling in your module names and consider adding help text within the module fields to guide content creators to the “Hidden Modules” section.