Phlex Rails

repository·main·Indexed 18 days ago

https://github.com/yippee-fun/phlex-rails

Phlex Rails integrates the Phlex view engine into Rails, allowing developers to build web views using pure Ruby instead of traditional template engines like ERB or Haml. It provides specialized classes for HTML and SVG rendering, access to Rails view helpers via HelperMacros, and support for Rails layouts, translations, and partials within Phlex components.

Tokens
3.8K
Snippets
15
Records
21
Agent score
62%

What's inside phlex-rails

  1. How Phlex::Rails::Layout works with Rails view contexts

    main

    The Phlex::Rails::Layout module provides an interface for rendering Phlex components as Rails layouts. When included in a class inheriting from Phlex::HTML, it enables the component to interact with the Rails view_context.

    Key behaviors:

    • Rendering: The render method handles the transition between Phlex and the Rails view flow. If a block yields a Symbol, the layout attempts to resolve that symbol using view_context.view_flow.get(symbol). Otherwise, it yields the block normally.
    • Virtual Paths: The module automatically generates a virtual_path based on the class name. It converts Ruby constant names (e.g., Admin::UserLayout) into Rails-style underscored paths (e.g., admin.user_layout). This is useful for mapping Phlex layouts to Rails view lookup conventions.
    • Helpers: It includes a suite of Rails-specific tag helpers such as CSPMetaTag, CSRFMetaTags, StylesheetLinkTag, and TurboRefresh tags, allowing you to use standard Rails asset and meta tags directly within your Phlex layout classes.
    class ApplicationLayout < Phlex::HTML
      include Phlex::Rails::Layout
    
      def template
        head do
          # Helpers included via Phlex::Rails::Layout
          csrf_meta_tags
          javascript_importmap_tags
        end
        body do
          yield
        end
      end
    end
  2. How component-scoped translation paths are resolved

    main

    When you use a scoped translation key (starting with .), the helper calculates a translation_path based on the component's class name.

    1. :: is replaced with .
    2. CamelCase is converted to snake_case (e.g., MyComponent becomes my_component).
    3. The resulting path is prepended to your key.

    Example: A component named Admin::UserDashboard will resolve .title to admin.user_dashboard.title.

  3. How Phlex::Rails::Buffered handles component output

    main

    In phlex-rails, Phlex::Rails::Buffered is a wrapper object used to manage how objects are rendered within a Phlex component. It acts as a proxy to an underlying @object, intercepting method calls to ensure that the output is correctly captured and passed through the component's rendering pipeline.

    When a method is called on a Buffered object:

    1. If a block is provided: The method is called on the underlying object, and the block is passed to @component.capture. The result is then wrapped in @component.raw to ensure it is treated as safe HTML/output.
    2. If no block is provided: The method is called on the underlying object, and the result is passed through @component.raw.

    This mechanism allows standard Ruby objects to behave as if they are part of the Phlex rendering flow, automatically handling content capture and raw output injection.

    # Conceptual usage within a component context
    # The Buffered object intercepts calls to ensure they are captured by the component
    # and marked as raw output.
    
    # If @object is a helper or another component:
    # @component.raw(@object.method_name) if no block
    # @component.raw(@object.method_name { |args| @component.capture(args) }) if block
  4. How Phlex::Rails::Builder handles method delegation

    main

    The Phlex::Rails::Builder is a proxy object used during the construction of Phlex components within a Rails environment. It wraps a target object (typically a Rails view context or a builder object) and intercepts method calls to facilitate seamless integration between Phlex and Rails-specific output types.

    When a method is called on the builder:

    1. With a block: The builder executes the method on the underlying object and yields a new Phlex::Rails::Builder instance to the block. This allows for nested Phlex component construction.
    2. Without a block: The builder simply delegates the method call to the underlying object.
    3. Output Handling: If the result of the method call is an ActiveSupport::SafeBuffer (common in Rails for HTML-safe strings), the builder automatically wraps the output using @component.raw(output) to ensure correct rendering within the Phlex component.
    # Conceptual usage pattern within a Phlex component
    # The builder ensures Rails-specific helpers return correctly to Phlex
    
    def construct
      # Inside a Phlex component, the builder might be used to wrap
      # Rails view helpers that return SafeBuffer strings.
      content.tag.div do
        # If 'link_to' returns a SafeBuffer, the Builder wraps it via @component.raw
        link_to "Home", root_path
      end
    end
  5. Access Rails view helpers in Phlex components

    main

    Phlex Rails integrates Rails view helpers into the Phlex rendering lifecycle. By using Phlex::HTML or Phlex::SVG, your components gain access to a wide array of Rails helpers via Phlex::Rails::HelperMacros.

    Commonly supported helpers include:

    • Asset helpers: asset_url, image_url, stylesheet_link_tag, javascript_include_tag.
    • Form/URL helpers: url_for, url_options, url_to_asset.
    • Meta tags: csrf_meta_tags, csp_meta_tag.
    • Content helpers: textarea_tag, url_field_tag.

    These helpers are automatically mapped to their corresponding Phlex classes via the Zeitwerk loader inflections.

  6. Install Phlex Rails via Rails generator

    main

    When adding phlex-rails to a Rails project, you can run the installation generator to set up the necessary configuration files and base classes. This generator performs three main actions:

    1. Creates a configuration initializer at config/initializers/phlex.rb.
    2. Creates a base component class at app/components/base.rb.
    3. Creates a base view class at app/views/base.rb.

    Run the following command in your terminal:

    rails generate phlex:install
  7. Resolve missing Rails helper errors in Phlex components

    main

    If you attempt to call a Rails view helper (e.g., link_to, image_tag) inside a Phlex component and it is not available, phlex-rails will raise a NoMethodError with a specific suggestion.

    To fix this, you must include the appropriate helper module from Phlex::Rails::Helpers in your component class. For example, if you are missing a helper that belongs to a specific module, the error message will tell you exactly which one to include.

    # Example of what the error suggests doing:
    class MyComponent < Phlex::SGML
      include Phlex::Rails::Helpers::SomeHelperModule
    
      def call
        # Now you can use helpers from SomeHelperModule
      end
    end
  8. Generate Rails-compatible virtual paths from Phlex classes

    main

    When using Phlex::Rails::Layout, you can determine the virtual_path of a layout class. This method transforms the Ruby class name into a lowercase, underscored string suitable for Rails view naming conventions.

    Transformation rules:

    1. :: is replaced with .
    2. CamelCase is converted to snake_case (e.g., UserLayout becomes user_layout)
    3. The entire string is downcased.
    # Example transformation
    class Admin::UserLayout < Phlex::HTML
      include Phlex::Rails::Layout
    end
    
    Admin::UserLayout.virtual_path # => "admin.user_layout"