{"id":28372287,"url":"https://github.com/comfy/comfy-demo","last_synced_at":"2025-07-01T09:06:44.797Z","repository":{"id":11496250,"uuid":"13972102","full_name":"comfy/comfy-demo","owner":"comfy","description":"A simple Rails app with CMS installed","archived":false,"fork":false,"pushed_at":"2023-01-19T11:15:36.000Z","size":972,"stargazers_count":19,"open_issues_count":37,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-29T13:56:24.176Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/comfy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-10-29T23:42:01.000Z","updated_at":"2023-09-30T17:04:35.000Z","dependencies_parsed_at":"2023-02-10T23:00:25.098Z","dependency_job_id":null,"html_url":"https://github.com/comfy/comfy-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/comfy/comfy-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comfy%2Fcomfy-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comfy%2Fcomfy-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comfy%2Fcomfy-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comfy%2Fcomfy-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/comfy","download_url":"https://codeload.github.com/comfy/comfy-demo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comfy%2Fcomfy-demo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261078496,"owners_count":23106476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-29T13:43:05.326Z","updated_at":"2025-07-01T09:06:44.774Z","avatar_url":"https://github.com/comfy.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Comfy Demo App\n\nThis is a simple demo app that has ComfortableMexicanSofa installed, configured\nand extended. You should be able to recreate everything by creating a fresh\nRails app and following these steps.\n\n[![Build Status](https://img.shields.io/travis/comfy/comfy-demo.svg?branch=master\u0026style=flat)](https://travis-ci.org/comfy/comfy-demo)\n[![Gitter](https://badges.gitter.im/comfy/comfortable-mexican-sofa.svg)](https://gitter.im/comfy/comfortable-mexican-sofa)\n\n### Step 1: Installation\n\n* Add required gems to [Gemfile](https://github.com/comfy/comfy-demo/blob/master/Gemfile#L59)\n* Run `rails active_storage:install` to pull in ActiveStorage migration\n* Run `rails action_text:install` to install ActiveText stuff\n* Run `rails webpacker:install` to install Webpack stuff\n* Run `rails g comfy:cms` to pull in CMS migration, routes and initializer\n* Run migrations: `rake db:migrate`\n* Start the server: `rails s`\n* Navigate to http://localhost:3000/admin\n* Log in with default credentials: u: `username`, p: `password`\n\n### Step 2: Hello World\n\nCreate a Site. Comfy is a multi-site capable CMS, but for now we only need to\nworry about one. Put \"Demo\" as a **Label** and **Indentifier** should\nauto-populate to \"demo\". Site will be created and you'll be redirected to\nthe Layout creation view.\n\nLet's create a *layout*. Set **Layout Name** to \"main\". **Identifier** should\nauto-populate. Leave **Content** populated with:\n\n```html\n{{cms::wysiwyg content}}\n```\n\nThis just indicates that pages using this layout will have a single text field\nvia Wysiwyg HTML editor. Don't worry about **Stylesheet** and **Javascript**\njust yet. After creating your first Layout navigate to **Pages** section via\nsidebar navigation.\n\nNow we'll create landing page. Set **Label** to \"Homepage\", populate some text\nlike \"Hello World\" in the **Content** field and hit **Create Page**.\n\nNow you have some content that's ready to be served. Navigate to\nhttp://localhost:3000/ and you should see your text.\n\n### Step 3: Basic Configuration\n\nOpen [/config/initializers/comfortable_mexican_sofa.rb](/config/initializers/comfortable_mexican_sofa.rb)\nand change default username and password. This initializer allows to configure\nthings that are relevant to your app. You may utilize authentication provided by\nDevice or whatever you may have in your app. This is the place to set this up.\n\n### Step 4: Hello World with Bootstrap 4\n\nWhile we can put entire html structure of the *page* inside *layout*, let's use\nRails layouts for it: [/app/views/layouts/application.html.erb](/app/views/layouts/application.html.erb)\n\nNow let's set our *layout's* **app_layout** to \"application\"\n\nSave it and you'll see that \"Hello World\" is inside Bootstrap container.\n\n### Step 5: @cms_site, @cms_layout and @cms_page\n\nWhen CMS is rendering content you should be able to access above instance\nvariables in the layout, helpers and partials.\n\nRight now let's set page html title like this:\n\n```erb\n\u003ctitle\u003e\u003c%= @cms_page.present? ? @cms_page.label : \"Demo App\" %\u003e\u003c/title\u003e\n```\n\n### Step 6: Layout nesting and more Content Tags\n\nLet's update *layout* content with something like this:\n\n```html\n\u003cdiv class=\"jumbotron\"\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003ch1\u003e{{ cms:text jumbotron-title }}\u003c/h1\u003e\n    \u003cp\u003e{{ cms:text jumbotron-text }}\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cmain class=\"container\"\u003e\n  {{ cms:wysiwyg content }}\n\u003c/main\u003e\n\u003chr/\u003e\n\u003cfooter class=\"container\"\u003e\n  {{ cms:snippet footer }}\n\u003c/footer\u003e\n```\n\nAll *pages* using this *layout* will have appropriate form fields rendered in\nthe admin view.\n\nWhat if we want to have a similar page markup, but with two columns? You can\nactually nest *layouts*. Think of `{{ cms:wywiwyg content }}` (or any format as\nlong as fragment is named \"content\") as a conventional `yield` in Rails layouts.\n\nNext step is to create a new *layout* that is a child of the existing one. Name\nit \"Two Columns\". Populate its **content** with something like this:\n\n```html\n\u003cdiv class=\"row\"\u003e\n  \u003cdiv class=\"col-md-6\"\u003e\n    \u003ch2\u003e{{ cms:text left-col-title }}\u003c/h2\u003e\n    \u003cp\u003e{{ cms:markdown left-col-text }}\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"col-md-6\"\u003e\n    \u003ch2\u003e{{ cms:text right-col-title }}\u003c/h2\u003e\n    \u003cp\u003e{{ cms:file demo-image, as: image }}\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n```\n\n*Pages* using this *layout* will have two column and also jumbotron from the\nparent *layout*\n\nNotice the `{{ cms:snippet footer }}`. Snippet is a reusable content that you\npopulate once and reuse everywhere. Good example would be copyright notice that\nneeds to be at the bottom of all pages. Just create a *snippet* called \"footer\"\nand populate content with \"\u0026copy; Copyright 2017\"\n\nSee [WIKI](https://github.com/comfy/comfortable-mexican-sofa/wiki/Docs:-Content-Tags)\nfor all available tags and how to use them.\n\n### Step 7: Non-renderable Page Fragments and view helpers\n\nThere's an option to skip the rendering for some tags. Good example would be\nmeta tags that need to be rendered in the Rails layout. Let's add one of those\ntags. You may place them anywhere in the *layout* content.\n\n```html\n{{ cms:text meta-description, render: false }}\n```\n\nNow you may access this via `cms_fragment_content` view helper:\n\n```html\n\u003cmeta name=\"description\" content=\"\u003c%= cms_fragment_content(\"meta-description\") %\u003e\"\u003e\n```\n\nThere are several CMS view helpers you may use in your app:\n\n* `cms_fragment_content` - Raw fragment content\n* `cms_fragment_render` - If fragment content contains more tags, you can expand them\n* `cms_snippet_content` - Raw snippet content\n* `cms_snippet_render` - Use render to expand content with tags\n\n**Note:** Add `helper Comfy::CmsHelper` to your `ApplicationController` if you\nopted out from auto-loading all view helpers everywhere.\n\n### Step 8: CMS Seed Data\n\nNow you know how to structure and populate content. However, during development\nit's not fun to populate content via admin forms and then doing database dumps and\nrestores. Never mind the complexity of it if you work in a team of people.\n\nCMS Seed Data allows you to create content in files that can get loaded into\ndatabase automatically.\n\nWhen you installed CMS you probably noticed that [/db/seeds](/db/cms_seeds)\ndirectory was created. It contains an example of how seed data files are structured.\n\nThose files will represent structure and content of your site. To import them into\ndatabase use rake task\n\n```\nrake 'comfy:cms_seeds:import[sample-site, demo]'\n```\n\nWhere first argument is the folder name where the seeds are, and the second\nargument is the **identifier** of the *site*. Be warned that data that is not\npresent in those files will be removed from the database.\n\nAlternativery, you can export everything from the database into a folder by\nrunning\n\n```\nrake 'comfy:cms_seeds:export[demo, sample-site]'\n```\n\nWhere first argument is the **identifier** of the *site*, and the second one is\nthe name of the seeds folder.\n\nDuring development it would be pretty annoying to run rake task everytime you\ndo a content change. This is why there's `config.enable_seeds` that is found\ninside initializer. Set it to `true` and restart server. Now with each request\nupdated seed data will be automatically pushed into database.\n\nThe only catch is that both folder name and *site's* **identifier** need to match.\nAlso don't push site to production with that enabled by mistake.\n\n*Note:* For demo purposes that setting is off. Enable it to play with seed data.\n\n### Step 9: Page Translations\n\nAfter importing CMS Seeds you probably noticed that Homepage has a French\ntranslation. The way you populate content there should be pretty obvious already.\nHow is it being served though? Process of serving localized content goes through\nsteps found here: [content_controller.rb](https://github.com/comfy/comfortable-mexican-sofa/blob/master/app/controllers/comfy/cms/content_controller.rb#L51)\n\nFor this demo app we have a simple control to switch locales\nin [application_controller.rb](/app/controllers/application_controller.rb)\n\nSo visiting http://localhost:3000?locale=fr should serve translated content\n\nYou can also modify content serving route to look something like this:\n\n```ruby\ncomfy_route :cms, path: \"/:locale/\"\n```\n\n### Step 10: Reusing Admin area for other CRUDS\n\nAre you starting a new project? You can reuse Comfy's admin area for your admin\nviews. All you need to do is inherit your controller from `Comfy::Admin::Cms::BaseController`.\n\nYou may use provided scaffold generator to quickly spin up CRUDS. For example:\n\n```\nrails g comfy:scaffold Shoe name:string color:string\n```\n\nYou'll get models, migration, controllers, views, and also model and controller\ntests. Fill in the missing bits and you'll have fully functional admin section.\n\n### Step 11: Custom CMS Content Tag\n\nYou can add your own CMS content tags. Here's an example of a simple one:\n[lorem_picsum.rb](/lib/cms_tags/lorem_picsum.rb)\n\nFor more inspiration check out existing [CMS content tags](https://github.com/comfy/comfortable-mexican-sofa/tree/master/lib/comfortable_mexican_sofa/content/tags)\n\n### Step 12: Comfy Blog\n\nThere's a blog engine that you can just drop in along with CMS:\n[ComfyBlog](https://github.com/comfy/comfy-blog)\nInstall it, restart app and you should be able to access it via http://localhost:3000/blog\n\nBlog posts behave similarly to CMS pages. You may want to override view template\nthat is responsible for rendering /blog view. It was moved into /app/views/comfy/blog/posts\nApplication layout that is used for that view can be changed via comfy_blog\ninitializer. `config.app_layout = 'comfy/blog/application'`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomfy%2Fcomfy-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomfy%2Fcomfy-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomfy%2Fcomfy-demo/lists"}