### Install ActiveCanvas and Run Migrations Source: https://context7.com/giovapanasiti/active_canvas/llms.txt After adding the gem, run the install generator, which will copy migrations, mount the engine, and configure the CSS framework. Then, migrate the database and start the server. ```bash bundle install bin/rails generate active_canvas:install # Interactive wizard: copies migrations, mounts engine, chooses CSS framework, configures AI keys bin/rails db:migrate bin/rails server # Admin available at http://localhost:3000/canvas/admin ``` -------------------------------- ### Clone and Setup Active Canvas Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Steps to clone the Active Canvas repository, install dependencies, migrate the database, and run tests for local development. ```bash git clone https://github.com/giovapanasiti/active_canvas.git cd active_canvas bundle install bin/rails db:migrate bin/rails test ``` -------------------------------- ### Install Migrations Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Copies engine migrations to the host application. ```APIDOC ## Rake Task: Install Migrations ### Description Copies engine migrations to the host application. ### Command ```bash bin/rails active_canvas:install:migrations ``` ``` -------------------------------- ### Start Active Canvas Development Server Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Command to start the Rails server for Active Canvas development and the URL to access the admin interface. ```bash bin/rails server ``` -------------------------------- ### Run ActiveCanvas Install Generator Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Execute the install generator to set up ActiveCanvas in your Rails application. This will run migrations, create initializer files, mount the engine, and prompt for CSS framework selection. ```bash bundle install bin/rails generate active_canvas:install ``` -------------------------------- ### Get AI Model Lists for Editor Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Facade service to retrieve model lists, falling back to defaults if the database is empty. ```ruby ActiveCanvas::AiModels.text_models # => Array of hashes (from DB or defaults) ActiveCanvas::AiModels.image_models # => Array of hashes ActiveCanvas::AiModels.vision_models # => Array of hashes ``` -------------------------------- ### Low-Level Setting Get/Set Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Perform low-level get and set operations for custom settings. Use `set` to store a value and `get` to retrieve it. ```ruby ActiveCanvas::Setting.set("my_custom_key", "my_value") ActiveCanvas::Setting.get("my_custom_key") # => "my_value" ``` -------------------------------- ### Install ActiveCanvas Migrations Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Run this Rake task to copy the engine's migrations to your host application, allowing you to manage them with your application's migration system. ```bash bin/rails active_canvas:install:migrations ``` -------------------------------- ### Configure Admin Authentication with Custom Logic Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Implement custom authentication logic for the admin interface using a lambda function. This example denies access to non-admin users. ```ruby ActiveCanvas.configure do |config| config.authenticate_admin = -> { unless current_user&.admin? redirect_to main_app.root_path, alert: "Access denied" end } end ``` -------------------------------- ### Full Active Canvas Configuration Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md A comprehensive example of Active Canvas configuration options, covering authentication, CSS framework, media uploads, editor settings, page versioning, and security. ```ruby # config/initializers/active_canvas.rb ActiveCanvas.configure do |config| # === Authentication === config.authenticate_admin = :authenticate_user! # method name, lambda, or :http_basic_auth config.authenticate_public = nil # nil = public access config.current_user_method = :current_user # for version tracking & AI features # === CSS Framework === config.css_framework = :tailwind # :tailwind, :bootstrap5, or :none # === Media Uploads === config.enable_uploads = true config.max_upload_size = 10.megabytes config.allow_svg_uploads = false config.storage_service = nil # Active Storage service name config.public_uploads = false # false = signed URLs # === Editor === config.enable_ai_features = true config.enable_code_editor = true config.enable_asset_manager = true config.autosave_interval = 60 # seconds (0 = disabled) # === Pages === config.max_versions_per_page = 50 # 0 = unlimited # === Security === config.sanitize_content = true config.ai_rate_limit_per_minute = 30 end ``` -------------------------------- ### Install ActiveCanvas Gem Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Add the ActiveCanvas gem to your Gemfile to include it in your Rails application. ```ruby gem "active_canvas" ``` -------------------------------- ### Page Scopes and Instance Methods Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Provides examples of using scopes to filter pages by status and accessing instance methods to retrieve rendered content or version information. Use `ActiveCanvas::Page.current_editor` to track edits for version history. ```ruby # Scopes ActiveCanvas::Page.published # => all published pages ActiveCanvas::Page.draft # => all draft pages # Instance methods page.rendered_content # => content.html_safe page.current_version_number # => integer (latest version number) page.show_header? # => true page.show_footer? # => true # Track who edited for version history ActiveCanvas::Page.current_editor = "admin@example.com" page.update!(content: "

Updated!

") # A PageVersion is automatically created with before/after diff # Programmatic content update with version attribution ActiveCanvas::Page.current_editor = current_user.email page.update!(content: new_html, content_css: new_css) ``` -------------------------------- ### Settings API - Update AI Settings Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Updates AI-related settings, such as the OpenAI API key. The API key is skipped if blank or starts with '****'. ```APIDOC ## PATCH /canvas/admin/settings/update_ai ### Description Updates AI-related settings, such as the OpenAI API key. The API key is skipped if blank or starts with '****'. ### Method `PATCH` ### Endpoint `/canvas/admin/settings/update_ai` ### Parameters #### Request Body - **ai_openai_api_key** (String) - The OpenAI API key. ### Request Example ```json { "ai_openai_api_key": "sk-..." } ``` ``` -------------------------------- ### Sync AI Models with Rails Command Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md After configuring API keys, run this command to sync available AI models with your ActiveCanvas setup. This can also be done via the admin UI. ```bash bin/rails active_canvas:sync_models ``` -------------------------------- ### Extend Active Canvas Models Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Example of extending the `ActiveCanvas::Page` model to add custom validations and methods, such as an `excerpt` method. ```ruby ActiveCanvas::Page.class_eval do validates :content, presence: true def excerpt content.to_s.truncate(200) end end ``` -------------------------------- ### Update AI Settings Source: https://context7.com/giovapanasiti/active_canvas/llms.txt This endpoint allows for updating AI-related settings, such as API keys. The `ai_openai_api_key` is skipped if it's blank or starts with '****', ensuring sensitive information is not inadvertently exposed. ```json # PATCH /canvas/admin/settings/update_ai # { # "ai_openai_api_key": "sk-...", # skipped if blank or starts with "****" # } ``` -------------------------------- ### Retrieve Media URL Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Get the URL for a media record. The URL is signed by default but can be public if `config.public_uploads` is true. `public_url` provides the direct public URL for cloud storage. ```ruby # Retrieve URL (signed by default, public if config.public_uploads = true) media.url # => "/rails/active_storage/blobs/redirect/..." or signed URL media.public_url # => direct public URL for cloud storage ``` -------------------------------- ### Create and Publish a Page Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Demonstrates creating a new page with various attributes, including content, SEO metadata, and Open Graph tags. Ensure a PageType is created first. Content is automatically sanitized on save. ```ruby # Create a page type first landing = ActiveCanvas::PageType.find_or_create_by!(key: "landing") { |t| t.name = "Landing Page" } blog = ActiveCanvas::PageType.find_or_create_by!(key: "blog") { |t| t.name = "Blog Post" } # Create and publish a page page = ActiveCanvas::Page.create!( title: "Welcome to Our Site", slug: "welcome", # auto-parameterized; auto-set if blank page_type: landing, published: true, content: "

Hello!

", show_header: true, show_footer: true, # SEO meta_title: "Welcome | My Site", meta_description: "The best place on the internet.", canonical_url: "https://example.com/canvas/welcome", meta_robots: "index,follow", # Open Graph og_title: "Welcome to Our Site", og_description: "The best place.", og_image: "https://example.com/og.png", # Twitter Card twitter_card: "summary_large_image", # JSON-LD structured_data: '{"@context":"https://schema.org","@type":"WebPage","name":"Welcome"}' ) ``` -------------------------------- ### Create Custom Page Types Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Shows how to ensure default page types exist and how to create custom ones with specific keys and names. Custom types automatically generate a key from the name if not provided. ```ruby # Ensure defaults exist default_type = ActiveCanvas::PageType.default # finds or creates key: "page" # Create custom types ActiveCanvas::PageType.create!(name: "Blog Post") # key auto-set to "blog_post" ActiveCanvas::PageType.create!(name: "Case Study", key: "case_study") # List all pages of a type case_study_type = ActiveCanvas::PageType.find_by(key: "case_study") case_study_type.pages.published.order(created_at: :desc) ``` -------------------------------- ### Configure AI API Keys in Initializer Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Set up your AI API keys within the `config/initializers/active_canvas.rb` file. You can use environment variables or Rails credentials. Ensure these keys are correctly configured for AI features to function. ```ruby # config/initializers/active_canvas.rb Rails.application.config.after_initialize do # Via environment variables ActiveCanvas::Setting.ai_openai_api_key = ENV["OPENAI_API_KEY"] ActiveCanvas::Setting.ai_anthropic_api_key = ENV["ANTHROPIC_API_KEY"] ActiveCanvas::Setting.ai_openrouter_api_key = ENV["OPENROUTER_API_KEY"] # Or via Rails credentials credentials = Rails.application.credentials.active_canvas || {} ActiveCanvas::Setting.ai_openai_api_key = credentials[:openai_api_key] end ``` -------------------------------- ### Admin Pages API - Get Editor Data Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Retrieves the editor data for a specific page, including its content, CSS, JavaScript, and component structure. ```APIDOC ## GET /canvas/admin/pages/:id/editor.json ### Description Retrieves the editor data for a specific page, including its content, CSS, JavaScript, and component structure. ### Method `GET` ### Endpoint `/canvas/admin/pages/:id/editor.json` ### Response - **content** (String) - The HTML content of the page. - **content_css** (String) - Custom CSS for the page content. - **content_js** (String) - Custom JavaScript for the page content. - **content_components** (String) - JSON string representing page components. ### Response Example ```json { "content": "...", "content_css": "...", "content_js": "...", "content_components": "..." } ``` ``` -------------------------------- ### Access Page Version History Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Demonstrates how to access and iterate through a page's version history, including details like version number, editor, timestamp, changes, and size differences. It also shows how to inspect a specific version's diff. ```ruby page = ActiveCanvas::Page.find(1) # Access version history (most recent first) page.versions.recent.limit(10).each do |v| puts "v#{v.version_number} by #{v.changed_by} at #{v.created_at}" puts v.changes_description # => "Changed: content, CSS" puts v.size_difference_formatted # => "+1234 bytes" or "-200 bytes" puts v.content_changed? # => true/false puts v.css_changed? # => true/false end # Inspect a specific version's diff version = page.versions.find_by(version_number: 3) puts version.content_diff # unified-style line diff # Rollback by applying a previous version's content old_version = page.versions.find_by(version_number: 2) ActiveCanvas::Page.current_editor = "rollback_script" page.update!(content: old_version.content_after, content_css: old_version.css_after) ``` -------------------------------- ### Query ActiveCanvas Pages from Host Application Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Demonstrates how to query `ActiveCanvas::Page` records from within a host application's controller, enabling hybrid content management scenarios. ```ruby class BlogController < ApplicationController def index @posts = ActiveCanvas::Page .published .includes(:page_type) .where(active_canvas_page_types: { key: "blog" }) .order(created_at: :desc) .page(params[:page]) end end ``` -------------------------------- ### Configure Admin Authentication with HTTP Basic Auth Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Set up HTTP Basic Authentication for the admin interface, including specifying the username and password from Rails credentials. ```ruby ActiveCanvas.configure do |config| config.authenticate_admin = :http_basic_auth config.http_basic_user = "admin" config.http_basic_password = Rails.application.credentials.active_canvas_password end ``` -------------------------------- ### Settings API - Update Global CSS Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Updates the global CSS settings for the application. ```APIDOC ## PATCH /canvas/admin/settings/update_global_css ### Description Updates the global CSS settings for the application. ### Method `PATCH` ### Endpoint `/canvas/admin/settings/update_global_css` ### Parameters #### Request Body - **global_css** (String) - The CSS string to apply globally. ### Request Example ```json { "global_css": "body { font-family: 'Inter'; }" } ``` ### Response #### Success Response (200) - **success** (Boolean) - Indicates if the update was successful. - **message** (String) - A confirmation message. ### Response Example ```json { "success": true, "message": "Global CSS saved." } ``` ``` -------------------------------- ### Generate Image with AI Service Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Create an image using `AiService.generate_image`. The generated image is saved to the media library and a `Media` record is returned. Specify the prompt and model. ```ruby # --- Image generation (saves to Media library, returns Media record) --- media = AiService.generate_image( prompt: "A futuristic cityscape at sunset, digital art style", model: "dall-e-3" # nil = Setting.ai_default_image_model ) puts media.url # usable image URL stored in Active Storage ``` -------------------------------- ### Manage Encrypted API Keys and Settings Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Illustrates how to set and retrieve API keys and other runtime settings using the `ActiveCanvas::Setting` model. API keys are automatically encrypted at rest. Use `*_configured?` and `masked_*` methods to check and display keys securely. ```ruby # AI API Keys (encrypted at rest) ActiveCanvas::Setting.ai_openai_api_key = ENV["OPENAI_API_KEY"] ActiveCanvas::Setting.ai_anthropic_api_key = ENV["ANTHROPIC_API_KEY"] ActiveCanvas::Setting.ai_openrouter_api_key = ENV["OPENROUTER_API_KEY"] # Check configuration without exposing the value ActiveCanvas::Setting.api_key_configured?("ai_openai_api_key") # => true/false ActiveCanvas::Setting.masked_api_key("ai_openai_api_key") # => "****Ab1C" # Default AI models ActiveCanvas::Setting.ai_default_text_model = "gpt-4o" ActiveCanvas::Setting.ai_default_image_model = "dall-e-3" ActiveCanvas::Setting.ai_default_vision_model = "gpt-4o" ``` -------------------------------- ### Set CSS Framework Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Specify the CSS framework to be used. This can be 'tailwind', 'bootstrap5', or 'custom'. This setting overrides the default configuration at runtime. ```ruby ActiveCanvas::Setting.css_framework = "tailwind" # "tailwind" | "bootstrap5" | "custom" ``` -------------------------------- ### Query Media Scopes Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Utilize scopes like `images`, `recent`, and `limit` for efficient querying of media assets, particularly for paginated display in an asset manager. ```ruby # Scopes ActiveCanvas::Media.images.recent.limit(20) # paginated in the editor asset manager ``` -------------------------------- ### Sync AI Models from Providers Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Import or update AI model records from configured providers using RubyLLM. This populates the database for model selection in the editor. ```ruby count = ActiveCanvas::AiModel.refresh_from_ruby_llm! # => 47 (number of models imported/updated) ``` -------------------------------- ### ActiveCanvas Settings Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Configuration options for AI features, CSS framework, global assets, homepage, and Tailwind theme. ```APIDOC ## ActiveCanvas Settings ### AI Feature Toggles - `ActiveCanvas::Setting.ai_text_enabled` - `ActiveCanvas::Setting.ai_image_enabled` - `ActiveCanvas::Setting.ai_screenshot_enabled` ### CSS Framework - `ActiveCanvas::Setting.css_framework = "tailwind"` (Options: "tailwind", "bootstrap5", "custom") ### Global CSS/JS - `ActiveCanvas::Setting.global_css = "..."` - `ActiveCanvas::Setting.global_js = "..."` ### Homepage - `ActiveCanvas::Setting.homepage_page_id = ` - `ActiveCanvas::Setting.homepage` ### Tailwind Theme Customization - `ActiveCanvas::Setting.tailwind_config = { ... }` - `ActiveCanvas::Setting.tailwind_config_js` ### Low-level Get/Set - `ActiveCanvas::Setting.set("key", "value")` - `ActiveCanvas::Setting.get("key")` ``` -------------------------------- ### Check AI Configuration Status Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Verify if any AI providers are configured and check feature enablement. ```ruby ActiveCanvas::AiConfiguration.configured? ActiveCanvas::AiConfiguration.configured_providers ActiveCanvas::AiConfiguration.text_enabled? ActiveCanvas::AiConfiguration.image_enabled? ActiveCanvas::AiConfiguration.screenshot_enabled? ``` -------------------------------- ### ActiveCanvas::AiModels Service Source: https://context7.com/giovapanasiti/active_canvas/llms.txt A facade that provides lists of AI models for the editor, with fallback to default models when the database is empty. ```APIDOC ## ActiveCanvas::AiModels Service Facade that returns model lists for the editor, falling back to hardcoded defaults when the database is empty. ```ruby ActiveCanvas::AiModels.text_models # => Array of hashes (from DB or defaults) ActiveCanvas::AiModels.image_models # => Array of hashes ActiveCanvas::AiModels.vision_models # => Array of hashes ActiveCanvas::AiModels.models_synced? # => true/false ActiveCanvas::AiModels.last_synced_at # => Time or nil ActiveCanvas::AiModels.refresh! # triggers AiModel.refresh_from_ruby_llm! # Default fallback models (used when DB is empty): # Text: gpt-4o, gpt-4o-mini, claude-sonnet-4-20250514, claude-3-5-haiku-20241022 # Image: dall-e-3, gpt-image-1 # Vision: gpt-4o, gpt-4o-mini, claude-sonnet-4-20250514 ``` ``` -------------------------------- ### List Synced AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Lists all active AI models that have been synced into the database, categorized by type (Text/Chat, Image). ```bash bin/rails active_canvas:list_models ``` -------------------------------- ### Upload Media File Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Create a new media record and attach a file using Active Storage. This typically occurs via the admin UI or a REST endpoint. The file type is validated, dangerous MIME types are blocked, and size limits are enforced. ```ruby media = ActiveCanvas::Media.new(filename: "hero.png") media.file.attach( io: File.open("/path/to/hero.png"), filename: "hero.png", content_type: "image/png" ) media.save! ``` -------------------------------- ### AI Model Instance Helpers Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Access details and properties of individual AI model records. ```ruby model = ActiveCanvas::AiModel.find_by(model_id: "gpt-4o") model.display_name # => "GPT-4o" model.supports_vision? # => true model.price_info # => "$5.0/M in / $15.0/M out" model.as_json_for_editor # => { id: "gpt-4o", name: "GPT-4o", provider: "openai", type: "chat", # input_modalities: ["text","image"], output_modalities: ["text"], # supports_functions: true, context_window: 128000, max_tokens: 16384 } ``` -------------------------------- ### Configure RubyLLM Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Force re-configuration of RubyLLM, typically called automatically before AI requests. ```ruby ActiveCanvas::AiConfiguration.configure_ruby_llm! ``` -------------------------------- ### ActiveCanvas::AiConfiguration Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Manages API keys and configures RubyLLM for AI operations. It provides methods to check configuration status and feature enablement. ```APIDOC ## ActiveCanvas::AiConfiguration Reads API keys from `Setting` and configures RubyLLM. Used internally before every AI call. ```ruby # Check if any provider is configured ActiveCanvas::AiConfiguration.configured? # => true/false # Which providers have keys set ActiveCanvas::AiConfiguration.configured_providers # => ["openai", "anthropic"] # Feature-level checks (configured AND feature toggle enabled) ActiveCanvas::AiConfiguration.text_enabled? # => true/false ActiveCanvas::AiConfiguration.image_enabled? # => true/false ActiveCanvas::AiConfiguration.screenshot_enabled? # => true/false # Force reconfigure RubyLLM (called automatically before each AI request) ActiveCanvas::AiConfiguration.configure_ruby_llm! ``` ``` -------------------------------- ### Configure Admin Parent Controller Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Set a custom parent controller for the admin interface if you are using a different controller hierarchy. ```ruby ActiveCanvas.configure do |config| config.admin_parent_controller = "Admin::ApplicationController" end ``` -------------------------------- ### Inject Global CSS and JavaScript Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Define global CSS styles and JavaScript code to be injected on every public page. This is useful for site-wide styling and behavior. ```ruby ActiveCanvas::Setting.global_css = "body { font-family: 'Inter', sans-serif; }" ActiveCanvas::Setting.global_js = "console.log('ActiveCanvas site loaded');" ``` -------------------------------- ### Settings API - Update Global JavaScript Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Updates the global JavaScript settings for the application. ```APIDOC ## PATCH /canvas/admin/settings/update_global_js ### Description Updates the global JavaScript settings for the application. ### Method `PATCH` ### Endpoint `/canvas/admin/settings/update_global_js` ### Parameters #### Request Body - **global_js** (String) - The JavaScript string to apply globally. ### Request Example ```json { "global_js": "window.analytics = {};" } ``` ### Response #### Success Response (200) - **success** (Boolean) - Indicates if the update was successful. - **message** (String) - A confirmation message. ### Response Example ```json { "success": true, "message": "Global JavaScript saved." } ``` ``` -------------------------------- ### Media JSON Representation for Editor Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Generate a JSON representation of a media record suitable for use in an editor interface. Includes ID, source URL, name, type, width, and height. ```ruby # Editor JSON representation media.as_json_for_editor # => { id: 1, src: "/rails/...", name: "hero.png", type: "image/png", # width: 1920, height: 1080 } ``` -------------------------------- ### ActiveCanvas::AiModel Model Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Represents a persisted catalog of AI models synced from providers. It tracks model capabilities, pricing, and context window, used to populate editor dropdowns. ```APIDOC ## ActiveCanvas::AiModel Model Persisted catalog of AI models synced from providers via RubyLLM. Tracks modalities (text input, image input, text output, image output), pricing, and context window. The editor uses these records to populate model selector dropdowns. ```ruby # Sync from all configured providers count = ActiveCanvas::AiModel.refresh_from_ruby_llm! # => 47 (number of models imported/updated) # Convenience scopes ActiveCanvas::AiModel.active.text_models.order(:name) ActiveCanvas::AiModel.active.image_models ActiveCanvas::AiModel.active.vision_models # text+image input, text output ActiveCanvas::AiModel.active.for_provider("openai") # Instance helpers model = ActiveCanvas::AiModel.find_by(model_id: "gpt-4o") model.display_name # => "GPT-4o" model.supports_vision? # => true model.price_info # => "$5.0/M in / $15.0/M out" model.as_json_for_editor # => { id: "gpt-4o", name: "GPT-4o", provider: "openai", type: "chat", # input_modalities: ["text","image"], output_modalities: ["text"], # supports_functions: true, context_window: 128000, max_tokens: 16384 } # Toggle model availability (shown/hidden in editor dropdowns) model.update!(active: false) # Rake task equivalents # bin/rails active_canvas:sync_models — full sync from all configured providers # bin/rails active_canvas:list_models — print models to stdout ``` ``` -------------------------------- ### Page CRUD Operations (HTML) Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Standard RESTful routes for managing pages, including index, new, create, show, edit, update, and delete. The index action provides media statistics, and the update action allows modification of various page attributes. ```ruby # Page CRUD (HTML-only): # GET /canvas/admin/pages -> index with media stats # GET /canvas/admin/pages/new # POST /canvas/admin/pages -> create # GET /canvas/admin/pages/:id # GET /canvas/admin/pages/:id/edit # PATCH /canvas/admin/pages/:id -> update (title, slug, SEO, publish status, etc.) # DELETE /canvas/admin/pages/:id # GET /canvas/admin/pages/:id/versions -> version history list # Permitted params for PATCH/POST: # title, slug, content, page_type_id, published, show_header, show_footer, # meta_title, meta_description, canonical_url, meta_robots, # og_title, og_description, og_image, # twitter_card, twitter_title, twitter_description, twitter_image, # structured_data ``` -------------------------------- ### Manage ActiveCanvas Partials Source: https://context7.com/giovapanasiti/active_canvas/llms.txt This code demonstrates how to ensure default partials exist, retrieve active header and footer, update their content programmatically, and manage their active status. The `update!` method automatically recompiles Tailwind CSS if `tailwindcss-ruby` is available. ```ruby # Ensure both partials exist (called by the engine initializer) ActiveCanvas::Partial.ensure_defaults! # Retrieve header = ActiveCanvas::Partial.active_header # header with active: true footer = ActiveCanvas::Partial.active_footer # Update content programmatically header.update!(content: "") # Tailwind CSS is compiled automatically after_save if tailwindcss-ruby is available # Rendered output header.rendered_content # => content.html_safe header.full_css # => compiled_css + "\n" + content_css # Activate / deactivate header.update!(active: false) # header won't render on public pages # Admin routes for editing partials: # GET /canvas/admin/partials -> index # GET /canvas/admin/partials/:id/editor -> visual GrapeJS editor # PATCH /canvas/admin/partials/:id/save_editor -> save editor content ``` -------------------------------- ### ActiveCanvas::Media Model Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Handles media uploads, storage, and retrieval, including URL generation and editor integration. ```APIDOC ## ActiveCanvas::Media Model ### Upload File ```ruby media = ActiveCanvas::Media.new(filename: "hero.png") media.file.attach( io: File.open("/path/to/hero.png"), filename: "hero.png", content_type: "image/png" ) media.save! ``` ### Retrieve URL - `media.url` (Signed by default) - `media.public_url` (Direct public URL) ### Editor JSON Representation - `media.as_json_for_editor` ### Scopes - `ActiveCanvas::Media.images.recent.limit(20)` ### REST API #### List Media `GET /canvas/admin/media.json?page=1&per_page=20` Response: ```json { "data": [...as_json_for_editor...], "meta": { "current_page": 1, "per_page": 20, "total_count": 100, "total_pages": 5 } } ``` #### Upload Media `POST /canvas/admin/media` (multipart) Request Body: ```json { "media": { "file": "", "filename": "photo.jpg" } } ``` Response (201): ```json { "id": 1, "src": "...", "name": "photo.jpg", "type": "image/jpeg", "width": 1920, "height": 1080 } ``` #### Delete Media `DELETE /canvas/admin/media/:id` Response (204): No Content ``` -------------------------------- ### Query Active AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Retrieve AI models based on their status, provider, and modality. Useful for populating editor dropdowns. ```ruby ActiveCanvas::AiModel.active.text_models.order(:name) ActiveCanvas::AiModel.active.image_models ActiveCanvas::AiModel.active.vision_models # text+image input, text output ActiveCanvas::AiModel.active.for_provider("openai") ``` -------------------------------- ### Configure Tailwind Theme Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Define the Tailwind theme, including colors and fonts, via `Setting.tailwind_config`. These settings are used during compilation. ```ruby ActiveCanvas::Setting.tailwind_config = { theme: { extend: { colors: { brand: "#6366f1" }, fontFamily: { sans: ["Inter"] } } } } # brand color and Inter font will be injected as @theme variables during compilation ``` -------------------------------- ### Active Canvas Rake Tasks Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md List of available Rake tasks for Active Canvas, including syncing and listing AI models. ```bash bin/rails active_canvas:sync_models # Sync AI models from configured providers bin/rails active_canvas:list_models # List all synced AI models ``` -------------------------------- ### List AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Lists all active synced AI models, categorized by type (Text/Chat, Image, Vision). ```APIDOC ## Rake Task: List AI Models ### Description Lists all active synced AI models, categorized by type. ### Command ```bash bin/rails active_canvas:list_models ``` ### Output Example ``` === Text/Chat Models === anthropic Claude 3.5 Haiku anthropic Claude Sonnet 4 [vision] openai GPT-4o [vision] ... === Image Models === openai DALL-E 3 openai GPT Image 1 Total: 34 models ``` ``` -------------------------------- ### Configure ActiveCanvas Settings Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Centralize ActiveCanvas configurations in `config/initializers/active_canvas.rb`. This block controls authentication methods, CSS framework, media upload settings, editor features, versioning limits, and AI security parameters. ```ruby # config/initializers/active_canvas.rb ActiveCanvas.configure do |config| # === Authentication === # Option A: Devise method name config.authenticate_admin = :authenticate_user! # Option B: Custom lambda with admin check config.authenticate_admin = -> { redirect_to main_app.root_path, alert: "Access denied" unless current_user&.admin? } # Option C: Inherit from existing admin controller config.admin_parent_controller = "Admin::ApplicationController" # Option D: HTTP Basic Auth (good for staging) config.authenticate_admin = :http_basic_auth config.http_basic_user = "admin" config.http_basic_password = Rails.application.credentials.active_canvas_password # Public pages: nil = no auth required config.authenticate_public = nil config.current_user_method = :current_user # for version tracking & AI features # === CSS Framework === config.css_framework = :tailwind # :tailwind | :bootstrap5 | :none # === Media Uploads === config.enable_uploads = true config.max_upload_size = 10.megabytes config.allow_svg_uploads = false # disabled by default (XSS risk) config.storage_service = :amazon # nil = default Active Storage service config.public_uploads = false # false = signed URLs with 1h expiry # === Editor === config.enable_ai_features = true config.enable_code_editor = true config.enable_asset_manager = true config.autosave_interval = 60 # seconds; 0 = disabled # === Versioning === config.max_versions_per_page = 50 # 0 = unlimited # === Security === config.sanitize_content = true config.ai_rate_limit_per_minute = 30 config.ai_stream_timeout = 5.minutes config.ai_stream_idle_timeout = 30.seconds config.ai_max_response_size = 1.megabyte end ``` -------------------------------- ### Mount ActiveCanvas Engine in Routes Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Mount the ActiveCanvas engine in your application's `config/routes.rb` file to define its base path. The engine automatically handles all its sub-routes. ```ruby # config/routes.rb Rails.application.routes.draw do # Default mount path mount ActiveCanvas::Engine => "/canvas" # Alternative mount paths # mount ActiveCanvas::Engine => "/cms" # mount ActiveCanvas::Engine => "/blog" # mount ActiveCanvas::Engine => "/" end # Routes provided by the engine: # GET /canvas/admin -> admin pages index # GET /canvas/admin/pages -> list all pages # GET /canvas/admin/pages/new -> new page form # GET /canvas/admin/pages/:id/editor -> GrapeJS visual editor # GET /canvas/admin/media -> media library # GET /canvas/admin/settings -> settings (general, styles, AI, models tabs) # POST /canvas/admin/ai/chat -> SSE streaming text generation # POST /canvas/admin/ai/image -> image generation # POST /canvas/admin/ai/screenshot_to_code -> screenshot → HTML # GET /canvas/admin/ai/models -> list configured AI models # GET /canvas/admin/ai/status -> AI configuration status # GET /canvas/:slug -> public page by slug ``` -------------------------------- ### Convert Screenshot to Code with AI Service Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Transform base64-encoded image data into HTML code using `AiService.screenshot_to_code`. This method accepts image data, an optional model, and additional prompts for customization. ```ruby # --- Screenshot to code --- # image_data = Base64-encoded data URL: "data:image/png;base64,xFFFF" html = AiService.screenshot_to_code( image_data: "data:image/png;base64,iVBORw0KGgo...", model: "gpt-4o", # nil = Setting.ai_default_vision_model additional_prompt: "Use Bootstrap 5 grid system" ) puts html # => "
...
" ``` -------------------------------- ### Generate Text with AI Service Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Stream text content using the `AiService.generate_text` method. This is typically called from an SSE controller. Specify the prompt, model, and optional context. The content is streamed in chunks. ```ruby # --- Text generation (streaming, called from the SSE controller) --- AiService.generate_text( prompt: "Create a hero section for a SaaS product called CloudSync", model: "gpt-4o", # nil = Setting.ai_default_text_model context: "Generate a complete page section or component." ) do |chunk| puts chunk.content # streamed partial HTML end ``` -------------------------------- ### ActiveCanvas::Partial Model Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Manages singleton header and footer records that are edited visually and auto-compile Tailwind CSS. Public pages render the active header/footer unless explicitly hidden. ```APIDOC ## ActiveCanvas::Partial Model ### Description Manages singleton header and footer records that are edited visually and auto-compile Tailwind CSS. Public pages render the active header/footer unless explicitly hidden. ### Methods #### `ensure_defaults!` Ensures that default header and footer partials exist. This is called by the engine initializer. ```ruby ActiveCanvas::Partial.ensure_defaults! ``` #### `active_header` Retrieves the currently active header partial. ```ruby header = ActiveCanvas::Partial.active_header ``` #### `active_footer` Retrieves the currently active footer partial. ```ruby footer = ActiveCanvas::Partial.active_footer ``` #### `update!(attributes)` Updates the content of a partial programmatically. Tailwind CSS is compiled automatically after save if `tailwindcss-ruby` is available. ```ruby header.update!(content: "") ``` #### `rendered_content` Returns the rendered HTML content of the partial. ```ruby header.rendered_content # => content.html_safe ``` #### `full_css` Returns the compiled CSS for the partial, including any custom CSS. ```ruby header.full_css # => compiled_css + "\n" + content_css ``` #### `update!(active: false)` Deactivates a partial, so it won't render on public pages. ```ruby header.update!(active: false) ``` ### Admin Routes - `GET /canvas/admin/partials` - `GET /canvas/admin/partials/:id/editor` - `PATCH /canvas/admin/partials/:id/save_editor` ``` -------------------------------- ### Bulk Toggle AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Perform bulk actions (like deactivation) on AI models based on scope and provider. This is useful for managing multiple models efficiently. ```http POST /canvas/admin/settings/bulk_toggle_ai_models { "action_type": "deactivate", "scope": "chat", "provider": "openai" } ``` -------------------------------- ### Mount Active Canvas Engine Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Mount the Active Canvas engine in your application's routes file, specifying the desired mount path. ```ruby # config/routes.rb mount ActiveCanvas::Engine => "/pages" # or "/cms", "/blog", "/" ``` -------------------------------- ### Retrieve Page Editor Content (JSON) Source: https://context7.com/giovapanasiti/active_canvas/llms.txt This endpoint fetches the current content, CSS, JavaScript, and component data for a specific page, typically used to load the GrapeJS editor with existing page information. ```json # GET /canvas/admin/pages/:id/editor.json # => { "content": "...", "content_css": "...", "content_js": "...", "content_components": "..." } ``` -------------------------------- ### Override Active Canvas Views Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md Instructions on how to override default Active Canvas views by copying them into your application's view directory. ```text app/views/active_canvas/pages/show.html.erb app/views/active_canvas/admin/pages/index.html.erb app/views/layouts/active_canvas/admin/application.html.erb ``` -------------------------------- ### Update Global CSS Setting Source: https://context7.com/giovapanasiti/active_canvas/llms.txt This JSON endpoint allows for updating the global CSS configuration for the application. It's used to apply site-wide styles that are not tied to specific pages or components. ```json # PATCH /canvas/admin/settings/update_global_css (JSON) # { "global_css": "body { font-family: 'Inter'; }" } # => { "success": true, "message": "Global CSS saved." } ``` -------------------------------- ### Compile Tailwind CSS for HTML Content Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Compile raw HTML content using Tailwind CSS v4. The output is minified CSS. Requires the `tailwindcss-ruby` gem. ```ruby css = ActiveCanvas::TailwindCompiler.compile( "

Hello

", identifier: "my-snippet" # used in log messages only ) # => "*, :before, :after{...} .flex{display:flex} .items-center{...} ..." (minified) ``` -------------------------------- ### Recompile Tailwind CSS Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Queues pages for Tailwind CSS recompilation. This is useful after updating the Tailwind configuration. ```APIDOC ## POST /canvas/admin/settings/recompile_tailwind ### Description Queues pages for Tailwind CSS recompilation. ### Method POST ### Endpoint /canvas/admin/settings/recompile_tailwind ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **count** (integer) - The number of pages queued for compilation. - **message** (string) - A message confirming the compilation queue. #### Response Example ```json { "success": true, "count": 12, "message": "Queued 12 pages for compilation." } ``` ``` -------------------------------- ### Sync AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Synchronizes AI models from all configured providers into the database. This operation can be performed via the API or a Rake task. ```APIDOC ## POST /canvas/admin/settings/sync_ai_models ### Description Synchronizes AI models from all configured providers into the database. ### Method POST ### Endpoint /canvas/admin/settings/sync_ai_models ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **count** (integer) - The number of models synced. - **message** (string) - A message confirming the sync operation. #### Response Example ```json { "success": true, "count": 47, "message": "Synced 47 models." } ``` ``` ```APIDOC ## Rake Task: Sync AI Models ### Description Sync AI models from all configured providers into the DB using a Rake task. ### Command ```bash bin/rails active_canvas:sync_models ``` ### Output Example ``` Configured providers: openai, anthropic Syncing models... Done! Synced 47 models. Breakdown: Text models: 31 Image models: 3 Vision models: 13 ``` ``` -------------------------------- ### Set Homepage Page ID Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Assign a specific page ID to be used as the homepage. The homepage setting retrieves a published ActiveCanvas::Page object. ```ruby ActiveCanvas::Setting.homepage_page_id = 5 ActiveCanvas::Setting.homepage # => ActiveCanvas::Page (published) ``` -------------------------------- ### Bulk Toggle AI Models Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Performs a bulk action (activate or deactivate) on AI models based on specified criteria. ```APIDOC ## POST /canvas/admin/settings/bulk_toggle_ai_models ### Description Performs a bulk action (activate or deactivate) on AI models based on specified criteria. ### Method POST ### Endpoint /canvas/admin/settings/bulk_toggle_ai_models ### Parameters #### Request Body - **action_type** (string) - Required - The action to perform (e.g., "deactivate", "activate"). - **scope** (string) - Optional - The scope of models to affect (e.g., "chat"). - **provider** (string) - Optional - The AI model provider (e.g., "openai"). ### Request Example ```json { "action_type": "deactivate", "scope": "chat", "provider": "openai" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **count** (integer) - The number of models affected by the bulk action. - **message** (string) - A message confirming the bulk action. #### Response Example ```json { "success": true, "count": 12, "message": "Deactivated 12 models." } ``` ``` -------------------------------- ### Add ActiveCanvas Gem to Gemfile Source: https://context7.com/giovapanasiti/active_canvas/llms.txt Include the ActiveCanvas gem and optionally the tailwindcss-ruby gem for runtime Tailwind CSS compilation in your Gemfile. ```ruby # Gemfile gem "active_canvas" gem "tailwindcss-ruby", ">= 4.0" # optional — enables runtime Tailwind compilation ```