Blog System Documentation
This document provides a comprehensive guide to the blog system in Heatwave, covering content creation, SEO features, quality checks, and available plugins.
Table of Contents
Section titled “Table of Contents”- Overview
- Date Semantics
- Content Structure
- SEO & Structured Data
- Liquid Tags (Plugins)
- Quality Checks
- Related Content
- Comments System
- Revision History
- Feeds & Distribution
- CRM Administration
Overview
Section titled “Overview”Blog posts (Post model) are a specialized type of Article that support:
- Rich content with Liquid templating
- Structured data extraction (FAQ, HowTo schemas)
- Author attribution with bio pages
- Comments and engagement tracking
- SEO optimization tools
- Revision history and content versioning
Post States
Section titled “Post States”| State | Description |
|---|---|
draft | Work in progress, not visible to public |
published | Live on the website |
scheduled | Will auto-publish at publish_on date |
archived | Removed from public view |
Date Semantics
Section titled “Date Semantics”The blog system uses three distinct date fields with specific meanings:
| Field | Purpose | Public Display |
|---|---|---|
published_at | Original publication date | Always shown in feeds/schema |
revised_at | Substantial content revision | Shown as “last updated” when present |
updated_at | Internal tracking (any edit) | Never shown publicly |
Display Rules
Section titled “Display Rules”-
Blog post page:
- If revised: “last updated [revised_at]”
- If not revised: “published on [published_at]”
- Note: Original publication date is preserved in JSON-LD/Atom for SEO but not shown visually
-
Blog listings: Show
revised_atif present, otherwisepublished_at -
Atom feed:
<published>: Alwayspublished_at<updated>:revised_atif present, otherwisepublished_at
-
JSON-LD BlogPosting:
datePublished: Alwayspublished_atdateModified:revised_atif present, otherwisepublished_at
-
Open Graph meta tags:
article:published_time: Always presentarticle:modified_time: Only present whenrevised_atis set
Setting Revision Date
Section titled “Setting Revision Date”In the CRM editor:
- Manual: Set the “Revised at” date picker
- Automatic: Check “Automatically update revised at” when saving (updates to current time)
Content Structure
Section titled “Content Structure”Core Fields
Section titled “Core Fields”| Field | Description | Character Limit |
|---|---|---|
subject | Main title (H1 on page) | 70 characters |
title | Page title (browser tab) | 65 characters |
description | Summary/excerpt | No limit (keep concise) |
solution | Main content body (HTML/Liquid) | No limit |
meta_description | SEO description override | 160 characters recommended |
meta_keywords | SEO keywords override | Optional |
Breadcrumbs
Section titled “Breadcrumbs”Breadcrumbs provide context for where the blog post fits in the site hierarchy.
Format options:
- Simple path:
/floor-heating - With custom title:
Radiant Floor Heating@/floor-heating
Rules:
- Must start with
/ - Auto-sorted by specificity (general → specific)
- First public tag used if no breadcrumb defined
Tags categorize blog posts. Public tags appear in the URL structure.
Public tags (appear in navigation):
company-news, countertop-heaters, design-trends, example-projects,general-information, heat-tape-for-pipes, indoor-heating, installation,led-mirrors, mirror-defoggers, outdoor-heating, press-industry-report,press-release, product-information, radiant-floor-heating, radiant-panels,remodeling, roof-and-gutter-deicing, troubleshooting, share-your-story,shower-kits, snow-melting, towel-warmers, trade-professionalsSEO & Structured Data
Section titled “SEO & Structured Data”Automatic Schemas
Section titled “Automatic Schemas”The system automatically generates:
-
BlogPosting (via
PostPresenter)- Title, description, author (Person with profile URL when available, else display name, else publisher org)
- Publisher (Organization),
inLanguage datePublishedanddateModifiedwordCount(integer, schema.org camelCase), article body, featured image
-
Breadcrumb (via
formatted_breadcrumbhelper)- One JSON-LD
BreadcrumbListper page. Blog show renders breadcrumb only inside_post.html.erb(a duplicate hidden breadcrumb was removed — it had caused two identical BreadcrumbList blocks).
- One JSON-LD
AI-Extracted Schemas
Section titled “AI-Extracted Schemas”The BlogSchemaExtractor service uses AI (GPT-4) to extract:
| Schema Type | When Extracted |
|---|---|
| FAQPage | Q&A content (unless embedded FAQ exists) |
| HowTo | Step-by-step instructions, tutorials |
Note: Article/BlogPosting schemas are NOT extracted (already handled).
Manual Schema Markup
Section titled “Manual Schema Markup”In the CRM “Advanced” tab, you can add custom JSON-LD:
[ { "@type": "FAQPage", "mainEntity": [...] }, { "@type": "HowTo", "name": "How to Install...", "step": [...] }]Meta Tags Generated
Section titled “Meta Tags Generated”<meta property="article:published_time" content="..."><meta property="article:modified_time" content="..."> <!-- Only if revised --><meta property="article:author" content="..."><meta property="article:section" content="..."><meta property="article:tag" content="..."><meta property="og:updated_time" content="..."> <!-- Only if revised -->Liquid Tags (Plugins)
Section titled “Liquid Tags (Plugins)”Available Liquid tags for blog content:
1. FAQ Tag
Section titled “1. FAQ Tag”Embeds FAQ with inline JSON-LD schema.
{% faq 1234 %}{% faq 1234,5678,9012 %}2. Video Tag
Section titled “2. Video Tag”Embeds a video player.
{% video 123 %}3. Cloudflare Video
Section titled “3. Cloudflare Video”Embeds Cloudflare Stream video.
{% cloudflare_video abc123def %}4. Image Tag
Section titled “4. Image Tag”Responsive image with proper sizing.
{% image 456 width:800 alt:"Description" %}5. Floor Heating Calculator
Section titled “5. Floor Heating Calculator”Interactive calculator widget.
{% floor_heating_calculator %}6. Snow Melting Calculator
Section titled “6. Snow Melting Calculator”Interactive snow melt calculator.
{% snow_melting_calculator %}7. Partial
Section titled “7. Partial”Include shared content partials.
{% partial "shared/cta_block" %}Quality Checks
Section titled “Quality Checks”Page Title Validation
Section titled “Page Title Validation”- Maximum 65 characters
- Displayed with check/ban icon in CRM
Content Processing Options
Section titled “Content Processing Options”| Option | Description |
|---|---|
| Sanitize URLs | Fixes broken links, adds https scheme |
| Sanitize HTML | Cleans inline styles, adds Bootstrap classes |
| Auto-update revised_at | Updates revision date on save |
Table of Contents
Section titled “Table of Contents”Enable has_toc to auto-generate navigation from headings:
- Default selector:
h2 - Custom selector via
toc_selectorfield
SEO Panel
Section titled “SEO Panel”The CRM shows an SEO overview panel with:
- Site visits (30 days)
- Ranking keywords count
- Health score (AI-generated)
- Quick links to locale-specific SiteMap details
Related Content
Section titled “Related Content”Manual Related Posts
Section titled “Manual Related Posts”Specify up to 4 related posts in the CRM editor.
Automatic Suggestions
Section titled “Automatic Suggestions”The system uses semantic embeddings to find similar content:
- Based on title, body, and product associations
- Product context from breadcrumbs
Comments System
Section titled “Comments System”Blog posts support moderated comments:
- Comments stored in
post_commentstable - Accessible via
post.post_comments - Count displayed in CRM
- Moderation interface at
/posts/:id/post_comments
Revision History
Section titled “Revision History”Published posts support content revisions:
- Automatic versioning on significant edits
- Preview any historical revision
- Restore to previous version (creates new revision)
- Change notes for audit trail
Access via CRM post show page “Revision History” panel.
Feeds & Distribution
Section titled “Feeds & Distribution”Atom Feed
Section titled “Atom Feed”Available at /posts.atom
- Paginated with
next/prevlinks - Entry includes full content
- Proper
publishedandupdatedtimestamps
Referral Tracking
Section titled “Referral Tracking”Each post auto-generates a Source for referral tracking:
- Short URL via Bitly
- Short URL with referral code
- Source analytics integration
Edge Cache
Section titled “Edge Cache”Posts integrate with Cloudflare edge caching:
- Auto-purge on publish/update
- Tag-based bulk purging available
- Purges related pages (index, tag pages)
CRM Administration
Section titled “CRM Administration”Post Editor Tabs
Section titled “Post Editor Tabs”| Tab | Contents |
|---|---|
| Summary | Title, author, dates, preview image |
| Content | Rich text editor (TinyMCE) |
| Tagging | Breadcrumbs, tags, meta fields |
| Related | Up to 4 related post links |
| Advanced | Content processing, TOC, schema markup, inline JS |
| Product Lines | Associated products for context |
Quick Actions
Section titled “Quick Actions”- Preview: View unpublished posts (token-based, 1-hour expiry)
- Publish/Unpublish: Change state
- Duplicate: Create copy as draft
- Extract Schema: Run AI schema extraction
- Purge Cache: Clear CDN cache
Bulk Operations
Section titled “Bulk Operations”- Tag-based cache purge:
Post.purge_all_posts_by_tag - Schema extraction worker:
BlogSchemaExtractionWorker - Auto extraction:
AutoBlogSchemaExtractionWorker
Best Practices
Section titled “Best Practices”Content Quality
Section titled “Content Quality”- Title: Keep under 65 characters for full display in search results
- Summary: Compelling excerpt that works as meta description
- Images: Always include a preview image for social sharing
- Breadcrumbs: Set appropriate context for SEO
SEO Optimization
Section titled “SEO Optimization”- Revision dates: Use for substantial updates, not typo fixes
- Schema markup: Let AI extract, manually add only if needed
- Related posts: Link to relevant content to reduce bounce
- Tags: Use public tags for proper categorization
Content Freshness
Section titled “Content Freshness”- Review and update evergreen content periodically
- Set
revised_atwhen making substantial updates - This signals freshness to search engines and users
Technical Reference
Section titled “Technical Reference”Model: Post < Article
Section titled “Model: Post < Article”Key associations:
belongs_to :preview_image, class_name: 'Image', optional: truebelongs_to :source, optional: truebelongs_to :original_author, class_name: 'Employee', optional: truehas_many :post_comments, dependent: :destroyhas_many :site_maps, as: :resourceKey methods:
post.effective_published_date # published_at || created_atpost.effective_revised_date # revised_at || published_atpost.primary_tag # First tagpost.main_public_tag # First public tagpost.content_for_embedding # Text for semantic searchRelated Services
Section titled “Related Services”| Service | Purpose |
|---|---|
BlogSchemaExtractor | AI-powered schema extraction |
PostPresenter | View presentation logic, JSON-LD generation |
BlogPreviewTokenService | Secure preview URLs |
Sitemap::SitemapGenerator | XML sitemap integration |
Last updated: January 2026