Metafield-Driven Editorial Article Template (TSB Blog)
A long-form article template assembled entirely from article metafields — deck, takeaways, science callouts, references, FAQ, author credentials, related reading and in-content commerce — in a single section with no theme-editor settings, so an editor never touches the theme to publish a fully structured post.
A Shopify article is a title, one rich-text body, one image and tags; the theme editor can't add per-article fields. This template assembles a long-form skincare article from 27 article metafields — deck, key takeaways, science callouts, references, a native <details> FAQ, a full author credentials card and an in-content featured product — inside a section that exposes no editor settings at all, so every module is authored where the article is.
The Problem
Shopify's article editor gives you one rich-text body and nothing else. A title, a featured image, tags, an author name, a body. That is the whole model, and for a lifestyle post it is enough.
Three Ships' blog is not a lifestyle post. It is a science and education channel for a skincare brand, and a post has to carry the things that make a science article credible — who wrote it and what their credentials are, what the sources were, what the reader should take away, which questions the piece answers — and the thing that makes it commercial, which is the product the post exists to explain. Every one of those either had to be hand-typed into the body on every post, where it cannot be styled consistently, reused or read by anything as a distinct element, or it did not exist. Mostly it did not exist.
The Constraint
Shopify articles have no block model. A product page can be composed from theme blocks a merchandiser arranges; an article page cannot, because the theme editor has no way to expose per-article fields — a section setting is the same for every article that uses the template. Article metafields are the only structured storage the platform offers per article, and they have to be read at render time in Liquid.
That decided the shape. Anything that varies per post is a metafield; anything that is the same for every post is the section's own markup. And because the theme editor auto-generates a template's JSON when a template is created, the section had to work with a template file that carries no settings for it — which meant designing a section with nothing to configure. The page also had to stay JavaScript-free wherever the content mattered to a crawler.
What We Built
tsb-blog-post.liquid, a single section of roughly 2,500 lines, mounted as the only section in article.tsb-blog.json. The template's sections object contains one entry, {"type": "tsb-blog-post"}, with empty settings, because there are none to set.
The shell. A two-column article layout: main column and a sticky aside. The hero image is optional; when present it loads eager with fetchpriority="high" and an explicit height derived from aspect_ratio, so the largest element on the page reserves its box before the file arrives.
The editorial modules. Every one reads from the article's custom.* namespace and renders only when its field has a value. custom.introduction is the deck. custom.key_takeaways is a list rendered as a bulleted takeaways box. custom.science_snapshot, and the pair custom.seasonal_tip_label and custom.seasonal_tip_body, are callout boxes. custom.infographic_image is a figure. custom.references is the source list. custom.faq is a list of question-and-answer entries rendered as native <details> accordions, with metafield_tag rendering each answer, so the FAQ is expandable with no script and readable by anything that parses HTML. A related-reading module in the aside renders cards for referenced articles.
The author card. A full credentials block from custom.author_name, custom.author_credentials, custom.author_image, custom.author_bio, custom.author_url, custom.author_email, custom.author_linkedin, custom.author_twitter and custom.author_publications, the last a logo list of where the author has been published. Every field is independently optional.
Commerce, twice. An inline featured-product card renders from custom.featured_product, with its title resolved through a chain — custom.sticky_bar_title, then custom.short_product_title, then product.title — so the short merchandising titles written for the product page's sticky bar are reused in editorial. A second card in the sticky aside renders from custom.featured_product_sidebar, defaulting to the inline product, so one field can drive both placements.
Computed in Liquid. Reading time is the body's word count divided by two hundred, floored at one minute, computed server-side. An "Updated" badge renders only when created_at and updated_at differ by calendar date.
Native forms. The aside carries a {% form 'customer' %} newsletter capture tagged contact[tags]=newsletter, and Shopify's own comments — {% form 'new_comment' %} plus article.comments paginated ten at a time — render when blog.comments_enabled? is true.
Why This Way
Every editorial module is a metafield rather than a section block because the content lives on the article, not on the template. One template serves every post assigned to it, and an editor filling in metafields in the article admin never opens the theme editor. Native <details> for the FAQ and Liquid-computed read time keep the modules JavaScript-free, so the parts that matter for crawlers and answer engines are in the server-rendered HTML rather than assembled after load.
What we gave up is flexibility of layout. A section with no settings cannot be rearranged in the theme editor: the order of modules is fixed in the file, and an editor who wants the takeaways below the science snapshot on one post cannot have it without a code change. We accepted that because a science blog benefits from every post having the same shape, and a settings-heavy section would be configured per template, not per article. The other cost is a 27-field authoring surface: a post with three fields filled looks thinner than it would on a plain template. Every module guards its own absence, which keeps a thin post clean but does not make it rich.
Why Not an App
Blog-enhancement apps — author boxes, tables of contents, FAQ blocks, related-post widgets — hold their content in the app's database and render it into the article with a script after load. On an editorial page the critical path is the text, and a third-party script on it is a cost the page pays on every view.
This template reads first-party metafields in Liquid. The author card, the FAQ and the references are in the HTML the server sends, the content stays in Shopify's own data model beside the article it belongs to, and no vendor script sits between the reader and the words.
Implementation Notes
- The template file's
sectionsobject holds one entry,{"type": "tsb-blog-post"}, with empty settings. The section deliberately exposes no theme-editor settings, so all authoring happens in article metafields. - Featured-product title resolution chains
custom.sticky_bar_title,custom.short_product_titleandproduct.title, so a short title written once for the product page is reused in editorial. - The sidebar product falls back with
custom.featured_product_sidebar | default: featured_product, so one field drives both placements unless an editor overrides the aside. - Read time is
content | strip_html | split: ' ' | size, plus 199,divided_by: 200, clamped to a minimum of one — a ceiling division done with integer arithmetic, because Liquid has no ceiling filter. - The FAQ answers render through
metafield_tag, so a rich-text answer keeps its formatting inside the<details>element. - Comments and their pagination are Shopify-native —
new_commentform,article.commentspaginated by ten — rather than an app-hosted comment widget. - Desktop and mobile author meta render as two separate blocks,
.tsb-meta.desktopand.tsb-meta-mobile, toggled by CSS rather than reflowed.
Edge Cases
- Every metafield module is wrapped in a
!= blankor.valueguard, so a partially filled article renders cleanly with the modules it has and no empty boxes for the ones it does not. - The author name falls back to Shopify's
article.authorwhencustom.author_nameis unset; the image, credentials, URL and each social link are independently optional, so a partial credentials card still renders. - The "Updated" badge is suppressed when the created and updated dates fall on the same day, so a post edited an hour after publishing does not advertise a freshness it does not have.
- A related-reading reference to a deleted or unpublished article resolves to nothing and its card vanishes, rather than rendering a dead link or erroring.
- The hero image is optional; when present it loads eager with
fetchpriority="high"and an explicit height, so its absence or presence never shifts the layout below it. - The comments block renders only when
blog.comments_enabled?is true, and the list only whencomments_countis greater than zero; the moderation notice and theposted_successfully?state are both handled. - The newsletter form renders its own success and error states inline, so a submission never leaves the article.
Platform Primitives Used
metafields— 27 article metafields in thecustom.*namespace are the entire per-post data model.json-templates—article.tsb-blog.jsonmounts the section as its only entry, with no settings, and any article can be assigned to it from the admin.liquid-schema-settings— used in the negative: the section's schema exposes nothing, which is the design decision.customer-forms— the newsletter capture is a{% form 'customer' %}with a tag, not a vendor embed.liquid-pagination—article.commentspaginated ten at a time through Shopify's own comment model.
Where It Runs
The blog, on one article template: article.tsb-blog. An article uses it when an editor assigns that template in the admin. The code shows the template is wired and what it renders; it does not show how many articles are assigned to it, and this page does not claim a number.
What This Demonstrates
- Editorial blog and content hub — the primary capability: a metafield-assembled article template with an author credentials block, a FAQ, related reading and in-content commerce.
- Long-form content navigation — key takeaways, a sticky aside and a native
<details>FAQ that make a long science article navigable without a script.
How We Know
One Liquid section and one JSON template from the theme. Documented from the code; no client-side record of the decision survives. Two things the code cannot tell us, and this page therefore does not assert: how many articles are assigned to the template, and whether the 27 metafield definitions the section reads were created as part of this work or already existed. The template, its modules and its fallbacks are read from the section.
Related Builds
- Creator collab video listing driven by article metafields — a different storefront treating articles as records with metafields as the schema, for a video grid rather than a long-form page.
- Metafield-driven two-level FAQ accordion grafted into a help-center app's shell — another storefront's FAQ from metafields, where the accordion had to live inside a vendor's template.
- Metafield-driven breadcrumbs across product, collection, page, blog and article — the same instinct applied to hierarchy: what the platform does not model, a metafield carries.
- Configurable PDP block system on the Palo Alto theme (Recharge widget placement, size charts, siblings, quick view) — the same storefront's product page, where the block model this article template lacks is exactly what was available.
The Buy-vs-Build Question
A blog-enhancement app buys author boxes and FAQ blocks rendered by script from a vendor's database. Building the template bought every module in the server-rendered HTML and content that lives on the article, and cost a fixed layout and a long authoring form. Whether Shopify's blog can carry a real publication, or when an external CMS is the better answer, is the subject of the editorial hub and blog at scale decision page.
Provenance & Evidence
- Client: Three Ships — threeshipsbeauty.ca
- Surface: Blog
- Templates served: one —
article.tsb-blog - Complexity: High
- Attribution: Deploi-authored. The section, the template and the metafield conventions are ours. It runs inside Palo Alto 5.8.0 by Presidio Creative, a paid premium theme the client licenses; the article template is not the vendor's.
- Status: Live, verified 2026-09-06
- Evidence: One Liquid section and one JSON template from the theme
- Confidence: Moderate — documented from the code; no client-side record of the decision survives
- Primary capability: Editorial blog and content hub
Ready for a Blog That Reads Like a Publication?
You dream it. We build it. If your articles need authors, sources and answers your CMS can't hold, Contact us today and we'll show you what Shopify's article model can carry.