{"id":19177836,"url":"https://github.com/trailblazer/trailblazer-cells","last_synced_at":"2025-05-07T20:42:35.825Z","repository":{"id":49239918,"uuid":"48414637","full_name":"trailblazer/trailblazer-cells","owner":"trailblazer","description":"Trailblazer's file structure for Cells.","archived":false,"fork":false,"pushed_at":"2023-01-25T15:09:53.000Z","size":29,"stargazers_count":26,"open_issues_count":2,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-07T20:42:30.945Z","etag":null,"topics":["cells"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trailblazer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-22T06:28:38.000Z","updated_at":"2024-04-21T11:43:51.000Z","dependencies_parsed_at":"2023-02-14T08:35:17.670Z","dependency_job_id":null,"html_url":"https://github.com/trailblazer/trailblazer-cells","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trailblazer%2Ftrailblazer-cells","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trailblazer%2Ftrailblazer-cells/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trailblazer%2Ftrailblazer-cells/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trailblazer%2Ftrailblazer-cells/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trailblazer","download_url":"https://codeload.github.com/trailblazer/trailblazer-cells/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252954127,"owners_count":21830893,"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":["cells"],"created_at":"2024-11-09T10:35:25.529Z","updated_at":"2025-05-07T20:42:35.789Z","avatar_url":"https://github.com/trailblazer.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Trailblazer::Cells\n\n_Trailblazer's file layout for Cells._\n\n## Overview\n\nTrailblazer cells are view components based on the [Cells](https://github.com/trailblazer/trailblazer-cells) gem, but following the Trailblazer naming conventions.\n\n### File Structure\n\n```\n├── app\n│    ├── concepts\n│    │   ├── blog_post\n│    │   │    ├── cell\n│    │   │    │   ├── edit.rb\n│    │   │    │   ├── item.rb\n│    │   │    │   ├── new.rb\n│    │   │    │   └── show.rb\n│    │   │    └── view\n│    │   │        ├── edit.erb\n│    │   │        ├── item.erb\n│    │   │        ├── new.erb\n│    │   │        └── show.erb\n│    │   │        └── author_list.erb\n```\n\n### Cell Class\n\n```ruby\n# app/concepts/blog_post/cell/edit.rb\nmodule BlogPost\n  module Cell\n    class Edit \u003c Trailblazer::Cell\n\n      # You can have helper methods.\n      def post_url\n        new_blog_post_path(model.id)\n      end\n\n      def summary\n        \"#{model.text[0..99]}...\"\n      end\n    end # New\n  end\nend\n```\n\n### Views\n\n```erb\n# app/concepts/blog_post/view/edit.erb\n\u003ch1\u003e\n  You're editing \u003c%= model.titel %\u003e\n\u003c/h1\u003e\n\n\u003cdiv class=\"summary\"\u003e\n  \u003c%= summary %\u003e\n\u003c/div\u003e\n\n\u003c%= render :edit_form %\u003e\n```\n\n```erb\n# app/concepts/blog_post/view/edit_form.erb\n\u003c%= simple_form_for model, url: post_url do %\u003e\n  ...\n\u003c% end %\u003e\n```\n\n### Rendering\n\n```ruby\n# app/controllers/blog_post_controller.rb\nclass BlogPostController \u003c ApplicationController\n  def edit\n    @blog_post = BlogPost.find(params[:id]) # do whatever you need here.\n\n    render cell(BlogPost::Cell::Edit, @blog_post)\n  end\nend\n\n```\n\n\n## View Prefixes\n\nIn Trailblazer, class structures such as the following are very common, let's say for a `post` concept, here are the class headers, and where the view directory gets resolved to.\n\n```ruby\nmodule Post\n  module Cell\n    class New \u003c Trailblazer::Cell         # =\u003e app/concepts/post/view\n    class Show \u003c Trailblazer::Cell        # =\u003e app/concepts/post/view\n      class SideBar \u003c Trailblazer::Cell   # =\u003e app/concepts/post/view\n```\n\n## Automatic `show`\n\nYou don't have to define a `show` method, `Trailblazer::Cell` will have one that looks as follows.\n\n```ruby\nclass Trailblazer::Cell\n  def show\n    render\n  end\n```\n\n## View Name\n\nWhen calling `render`, the view name is inferred from the class name.\n\n```ruby\nmodule Post\n  module Cell\n    class New \u003c Trailblazer::Cell         # =\u003e new.erb\n    class Show \u003c Trailblazer::Cell        # =\u003e show.erb\n      class SideBar \u003c Trailblazer::Cell   # =\u003e side_bar.erb\n```\n\nYou can still override using `render view: :name`.\n\n## Layout\n\nYou can pass a layout cell into every `Trailblazer::Cell` which will render the layout.\n\n```ruby\nPost::Cell::Show.new(post, layout: Gemgem::Cell::Layout).()\n```\n\nThe `:layout` option has to refer to a cell class. When invoked, the layout cell will receive the content of the actual cell under `:content`, resulting in a call as follows.\n\n```ruby\nGemgem::Cell::Layout.new(post,\n  content: Post::Cell::Show.new(post)\n)\n```\n\nThe layout cell's `show` view can sit in any directory, for example `gemgem/view/layout.rb`.\n\n```erb\n\u003chtml\u003e\nYay, I'm the layout!\n\n\u003c%= content %\u003e\n\u003c/html\u003e\n```\n\nIt's up to you what you do with the `:content` option. Here's the Trailblazer way.\n\n```ruby\nclass Gemgem::Cell::Layout \u003c Trailblazer::Cell\n  self.view_paths = [\"gemgem\"]\n  def content\n    @options[:content]\n  end\nend\n```\n\nCells with layout cells allow replacing a frameworks entire view stack, e.g. `ActionView`.\n\n## Namespaces\n\nIt works identical with namespaces.\n\n## View Paths\n\nSome projects do not use the `app/concept` view path. This can be changed as follows.\n\n```ruby\nTrailblazer::Cell.view_paths = [\"concepts\"]\n```\n\nNote that this will change for all cells, including bundled in gems. Introduce an `Application::Cell` if you don't like that.\n\n## Dependencies\n\nThis gem has only one dependency: `cells`. Note that it does *not need* `trailblazer`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrailblazer%2Ftrailblazer-cells","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrailblazer%2Ftrailblazer-cells","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrailblazer%2Ftrailblazer-cells/lists"}