1

I'm currently trying to figure out how to allow a content manager to change the order in which elements appear within recent post link lists. Essentially, the concept involves them picking the index in a sorting array that will hold that element's type as a string, which will later be iterated over with output logic determining where each piece gets placed. Unfortunately, one of the drawbacks of using HubL is the lack of debugging or error reporting so I can't see where my syntax is failing. I was wondering if anyone in InternetLand has had any similar experience with this.

Here's the HubL:

<div class="theme-recent-posts">
  {% if widget.title_name %}
    <div class="theme-recent-posts-title">
      <{{ widget.title_tag }}><span>{{ widget.title_name }}</span></{{ widget.title_tag }}>
    </div>
  {% endif %}
  {% set posts = blog_recent_posts(widget.select_blog, widget.max_links) %}
  {% for post in posts %}
    {% set item_objects = [] %}
    {% if widget.show_images == "true" %}
      {% set item_objects[widget.sort_images] = "image" %}
    {% endif %}
    {% if widget.show_titles == "true" %}
      {% set item_objects[widget.sort_titles] = "title" %}
    {% endif %}
    {% if widget.show_dates == "true" %}
      {% set item_objects[widget.sort_dates] = "date" %}
    {% endif %}
    {% if widget.show_authors == "true" %}
      {% set item_objects[widget.sort_authors] = "author" %}
    {% endif %}
    <div class="theme-recent-posts-item">
      <a href="{{ post.absolute_url }}">
        {% for object in item_objects %}
          {% if object == "image" %}
            <span class="theme-recent-posts-item-image"><img src="{{ post.featured_image }}" alt="{{ post.name }}" /></span>
          {% endif %}
          {% if object == "title" %}
            <span class="theme-recent-posts-item-title">{{ post.name }}</span>
          {% endif %}
          {% if object == "date" %}
            <span class="theme-recent-posts-item-date">{{ post.created }}</span>
          {% endif %}
          {% if object == "author" %}
            <span class="theme-recent-posts-item-author">{{ post.author_name }}</span>
          {% endif %}
        {% endfor %}
      </a>
    </div>
  {% endfor %}
</div>

Output currently results in:

<div class="theme-recent-posts">
  <div class="theme-recent-posts-title">
    <h2><span>Recent Posts</span></h2>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-3"></a>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-2"></a>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-1"></a>
  </div>
</div>

Assume the default values wired up in the widget panel:

widget.show_images = true
widget.show_images = true
widget.show_images = true
widget.show_images = true
widget.sort_images = 0
widget.sort_titles = 1
widget.sort_dates = 2
widget.sort_authors = 3

The output should essentially be this:

<div class="theme-recent-posts">
  <div class="theme-recent-posts-title">
    <h2><span>Recent Posts</span></h2>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-3">
      <span class="theme-recent-posts-item-image"><img src="path/to/image-3.ext" alt="Post Name 3" /></span>
      <span class="theme-recent-posts-item-title">Post Name 3</span>
      <span class="theme-recent-posts-item-date">1234567890</span>
      <span class="theme-recent-posts-item-author">FirstName LastName</span>
    </a>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-2">
      <span class="theme-recent-posts-item-image"><img src="path/to/image-2.ext" alt="Post Name 2" /></span>
      <span class="theme-recent-posts-item-title">Post Name 2</span>
      <span class="theme-recent-posts-item-date">1234567890</span>
      <span class="theme-recent-posts-item-author">FirstName LastName</span>
    </a>
  </div>
  <div class="theme-recent-posts-item">
    <a href="//website/path/post-name-1">
      <span class="theme-recent-posts-item-image"><img src="path/to/image-1.ext" alt="Post Name 1" /></span>
      <span class="theme-recent-posts-item-title">Post Name 1</span>
      <span class="theme-recent-posts-item-date">1234567890</span>
      <span class="theme-recent-posts-item-author">FirstName LastName</span>
    </a>
  </div>
</div>

I'm going to tag Jinja in this post, because HubL is based on Jinja, though it's not a direct translation.

If someone with enough reputation is reading this, I would greatly appreciate the addition of the HubL language tag, as it currently does not exist to select (even though HubSpot was).

Update

Twig is also a close cousin to HubL, and so I looked up how to update elements in an array there, and came up with this answer:

Setting element of array from Twig

{% set item_objects = item_objects|merge({widget.sort_images:"image"}) %}

Implementation did not work as expected. Output remains unchanged.

Community
  • 1
  • 1
MLK.DEV
  • 453
  • 7
  • 31
  • Circling back around to this, not sure if I mentioned it or not, but HubL handles for-loops with their own local scope, which means you cannot update a variable defined outside the loop, from inside the loop. Bummer! – MLK.DEV Jan 05 '16 at 22:10

1 Answers1

0

While this is not an answer to the question I asked, it is an alternate solution, so I provide it as a work around until a real solution is determined.

<div class="theme-recent-posts">

  {% if widget.title_name %}
    <div class="theme-recent-posts-title">
      <{{ widget.title_tag }}><span>{{ widget.title_name }}</span></{{ widget.title_tag }}>
    </div>
  {% endif %}

  {% set object_order = [0, 1, 2, 3] %}
  {% set posts = blog_recent_posts(widget.select_blog, widget.max_links) %}

  {% for post in posts %}
    <div class="theme-recent-posts-item">
      <a href="{{ post.absolute_url }}">
        {% for order in object_order %}
          {% if widget.show_images == "true" and widget.sort_images == order %}
            <span class="theme-recent-posts-item-image"><img src="{{ post.featured_image }}" alt="{{ post.name }}" /></span>
          {% endif %}
          {% if widget.show_titles == "true" and widget.sort_titles == order %}
            <span class="theme-recent-posts-item-title">{{ post.name }}</span>
          {% endif %}
          {% if widget.show_dates == "true" and widget.sort_dates == order %}
            <span class="theme-recent-posts-item-date">{{ post.created }}</span>
          {% endif %}
          {% if widget.show_authors == "true" and widget.sort_authors == order %}
            <span class="theme-recent-posts-item-author">{{ post.author_name }}</span>
          {% endif %}
        {% endfor %}
      </a>
    </div>
  {% endfor %}

</div>

This gives me the flexibility I was looking for and the code is actually lightened quite a bit from the original proposed method. The idea is to use the object_order list as a mask for the for order in object_order loop. This gets the job done, and while I know it's hacky, it has a touch of elegance to it.

MLK.DEV
  • 453
  • 7
  • 31