Helios::Press

A Rails engine providing a WordPress-like block editor for blog posts. Supports text (ActionText), image stacks with configurable grid layouts, and video blocks (via helios-videos) with drag-to-reorder.

Installation

Add to your Gemfile:

gem "helios-press"
gem "helios-videos"  # Optional: enables video blocks

Then:

bundle install
bin/rails helios_press:install:migrations
bin/rails db:migrate

Prerequisites:

  • ActionText must be installed in your host app (bin/rails action_text:install)
  • ActiveStorage must be installed (bin/rails active_storage:install)

Configuration

Create config/initializers/helios_press.rb:

Helios::Press.configure do |config|
  # Parent controller for admin views (must provide authentication)
  config.admin_parent_controller = "Admin::BaseController"

  # Optional slug prefix for posts
  config.post_slug_prefix = nil  # e.g., "blog/" for /blog/my-post

  # API authentication (for external post ingestion)
  # Default: checks X-API-Key header against BLOG_INGEST_API_KEY env var
  config.api_authentication = ->(controller) {
    expected = ENV["BLOG_INGEST_API_KEY"]
    provided = controller.request.headers["X-API-Key"]
    unless expected.present? && ActiveSupport::SecurityUtils.secure_compare(expected, provided.to_s)
      controller.render json: { error: "unauthorized" }, status: :unauthorized
    end
  }
end

Routes

Mount the engine:

mount Helios::Press::Engine, at: "/helios_press"

This provides:

  • Admin UI: /helios_press/admin/posts - Full block editor
  • API: POST /helios_press/api/posts - Ingest posts from external sources
  • Public: Define your own catch-all route pointing to Helios::Press::PostsController#show

JavaScript Setup

Register the Stimulus controllers in your host app:

import {
  HeliosPressBlocksController,
  HeliosPressTextBlockController,
  HeliosPressImageBlockController
} from "helios-press"

application.register("helios-press-blocks", HeliosPressBlocksController)
application.register("helios-press-text-block", HeliosPressTextBlockController)
application.register("helios-press-image-block", HeliosPressImageBlockController)

// If using helios-videos:
import { HeliosVideoBlockController } from "helios-videos"
application.register("helios-video-block", HeliosVideoBlockController)

npm dependencies (add to your host app's package.json):

  • sortablejs
  • @hotwired/stimulus
  • @rails/activestorage
  • trix and @rails/actiontext

CSS

Include the block editor styles in your asset pipeline:

/* In your application CSS */
@import "helios/press/blocks";

Block Types

  • Text: Rich text editing via ActionText. Double-click to edit, Save/Cancel buttons.
  • Image Container: Drag images to add. Configurable grid (1-6 images per row). Reorder by dragging. Click captions to edit.
  • Video Container (requires helios-videos): Drag a video file to create. Direct upload to S3, automatic processing via Mux/Cloudflare.

API Ingestion

POST to /helios_press/api/posts with X-API-Key header:

{
  "external_id": "my-post-123",
  "title": "My Post Title",
  "slug": "my-post-title",
  "description": "Meta description",
  "keywords": "keyword1, keyword2",
  "body_html": "<p>Post content...</p>",
  "published": true
}

License

Proprietary. All rights reserved.