A Checkbox Named Cacheable

Every now and then, there comes a time in a CMS developer's life when the sin of taking default settings for granted takes its toll. 
 
There. I phrased that carefully so it would make a list of quotable quotes some day. Now, let me get to it.
 
Like many developers out there, I am a huge fan of content-driven solutioning. Yes, it is easy to overdo, but the fear of overdoing it should never hold us back. Why, you ask? Because underdoing content-driven solutions is just plain stupid, in my ought-to-be-humbler opinion.
 
With that in mind, I immediately latched on to the idea of pulling content markup into the theme using the CMS API. (This is ideal for secondary navigation links and such.) I prefer this approach to the embedded portlet approach - keeps my theme code a bit more maintainable, more straighforward to debug for the next guy. 
 
Here's an example snippet from the theme that pulls the markup for a content item having a url title of "top-nav-links".
 
#set ($journalArticleLocalService = $serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleService"))
#set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, "top-nav-links"))
#set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay))
$contentMarkup
 
And I've been doing this for a long time. All seemed well.
 
...until a few days back.
 
I found myself alone in a room with this one bit of fussy content that no matter how many times I edited it, the updated markup did not show in my theme. I would have to go in and try combinations of regenerating my search indexes and deleting prior versions of my content and re-saving my template. And then, eventually, for no clear reason, the update would show up. Flaky!
 
Anyway, here is what I had to do to make this madness stop. In my template, I unchecked this box named Cacheable
 
 
That tooltip says it all!
 
Take a look at the velocity code snippet I pasted above. It basically calls into the CMS API to find the content item by its title,
#set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, "top-nav-links"))
and then retrieves the content markup with another API call,
#set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay))
and finally, includes the markup in the theme.
$contentMarkup
 
So, a Cacheable template is not good here. Uncheck and reap the benefits. You may want to consider any performance implications of not caching your template. In fact, if this content rarely changes, then keep it cacheable. But all philosophy and performance considerations aside, the feature functions as designed.
 
And one more tidbit. If you have this sort of code distributed all over your theme, i.e. you are pulling more than one or two content items into your theme: consider using a velocity macro. For example, drop this into your init_custom.vm where you initialize theme variables.
 
#*
This file allows you to override and define new Velocity variables.
*#
#set ($headerScript = $theme.getSetting("header-scripts"))
#set ($bodyScript = $theme.getSetting("body-scripts"))
#set ($journalArticleLocalService = $serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleService"))
 #macro ( includeContent $contentTitle )
 #set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, $contentTitle))
 #set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay))
 $contentMarkup
#end
 
One last thing. I had to recreate my content item to get this to take effect. Not sure if that is a bug or not. It is possible the Cacheable setting itself is cached. Regardless, the content updates are showing up reliably now in my navigation bar.
 
And that, is that.