### Example Test Using Basic Render Helper Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/testing.md An example demonstrating how to use the basic `render` helper to render a component and assert its HTML output. ```ruby output = render Components::Hello.new assert_equal "

Hello

", output ``` -------------------------------- ### Component with Text Content Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Example of a HelloWorld component that uses the div method to render text content. ```ruby class HelloWorld < Component def view_template div { div("Hello, World!") } end end ``` -------------------------------- ### Component with Attributes Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Example of a HelloWorld component that uses the div method with class attributes. ```ruby class HelloWorld < Component def view_template div(class: "outer") { div("Hello, World!", class: "inner") } end end ``` -------------------------------- ### View Example with Layout Composition Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/layouts.md A Phlex view that renders a layout component, passing content via a block. This demonstrates layout composition in Phlex. ```ruby class Views::Articles::Index < Views::Base def initialize(articles:) @articles = articles end def view_template Layout(title: "Articles") do h1 { "Articles" } ul do @articles.each do |article| li { article.title } end end end end end ``` -------------------------------- ### Example Phlex View Generator Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md Demonstrates the structure of a generated view class, namespaced under `Views` and inheriting from `Views::Base`. ```ruby # frozen_string_literal: true class Views::Articles::Index < Views::Base def view_template h1 { "Articles" } end end ``` -------------------------------- ### Example Phlex Component Generator Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md Illustrates a generated component class, namespaced under `Components` and inheriting from `Components::Base`. ```ruby # frozen_string_literal: true class Components::Button < Components::Base def view_template button { "Click me" } end end ``` -------------------------------- ### Rendering Nav with Child Components Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This example demonstrates rendering a navigation component using separate `NavItem` and `NavDivider` components. This approach offers more structure but can lead to defining components for elements that are only used within a specific parent. ```ruby render Nav do render NavItem.new("/") { strong { "Home" } } render NavItem.new("/about") { "About" } render NavDivider render NavItem.new("/contact") { "Contact" } end ``` -------------------------------- ### Run Phlex Install Generator Source: https://github.com/yippee-fun/phlex.fun/blob/main/introduction/getting-started.md Execute the install generator to configure Phlex components in your Rails application. ```bash bundle exec rails generate phlex:install ``` -------------------------------- ### Controller Example Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/layouts.md A controller action that renders a Phlex view. Set `layout false` in `ApplicationController` to disable Rails' built-in layout system. ```ruby class ArticlesController < ApplicationController layout false def index render Views::Articles::Index.new( articles: Article.all.limit(10) ) end end ``` -------------------------------- ### Rendering a Component with Content Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This example shows how to render the `Card` component and pass a content block to it. The content block will be rendered where `yield` is called within the `Card` component's `view_template`. ```ruby render Card.new("Hello") do p { "Hello, World" } end ``` -------------------------------- ### Render a Renderable Property in Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md This example shows how to create a Phlex component that accepts and renders another renderable object passed as a property. It demonstrates the core polymorphic behavior of the `render` method. ```ruby class Example < Phlex::HTML def initialize(renderable:) @renderable = renderable end def view_template render @renderable end end ``` -------------------------------- ### Example Nested HTML Output Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md This is the expected HTML output when the `HelloWorld` component is rendered, demonstrating the nested structure of the `outer` div, `card` div, and `inner` div. ```html
Hello, World!
``` -------------------------------- ### Define a Button Method in Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/compare/slim.md This snippet shows how to define a simple button helper method within Phlex. It's a starting point for creating reusable UI elements. ```ruby def MyButton(...) button(class: "my button classes", ...) end ``` -------------------------------- ### Define Literal Properties for Initializers Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Example of using Literal Properties to automatically escape reserved keywords in initializers. ```ruby prop :class, String prop :if, Proc ``` -------------------------------- ### Implement Conditional Rendering with #render? Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md Use the #render? method to conditionally render a component. If #render? returns false, the component will not be rendered. This example shows a notification badge that only renders if there are notifications. ```ruby class NotificationsBadge < Phlex::HTML def initialize(notifications:) @notifications = notifications end def view_template span(class: "badge badge-primary") { @notifications.size } end def render? @notifications.size > 0 end end NotificationsBadge.new(notifications: ["You are awesome!"]).call # => "1" NotificationsBadge.new(notifications: []).call # => "" ``` -------------------------------- ### Extracting Template Logic into a Method Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/snippets.md This example demonstrates how to extract a section of a Phlex component's template into a private method. This improves readability and reduces nesting. Public methods can be called from parent components. ```ruby class Sidebar < Phlex::HTML def view_template render_intro render_links render_footer end private def render_intro h2 "Welcome to the site!" p "This is the sidebar." end def render_links # ... end def render_footer # ... end end ``` -------------------------------- ### Accessing Site, Theme, and Page Data with useData() Source: https://github.com/yippee-fun/phlex.fun/blob/main/api-examples.md Import and use the `useData()` hook to access theme, page, and frontmatter data within a Vue component or script setup block in Markdown. This is useful for dynamically displaying content based on site configuration or page metadata. ```javascript ## Results ### Theme Data
{{ theme }}
### Page Data
{{ page }}
### Page Frontmatter
{{ frontmatter }}
``` ```javascript ## Results ### Theme Data
{{ theme }}
### Page Data
{{ page }}
### Page Frontmatter
{{ frontmatter }}
``` -------------------------------- ### Instantiate and Render HelloWorld Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Creates an instance of HelloWorld and calls its render method, printing the resulting HTML. ```ruby puts HelloWorld.new.call ``` -------------------------------- ### Initialize Component with Multiple Reserved Keyword Arguments using `grab` Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Demonstrates using `grab` to retrieve multiple keyword arguments that are reserved words. ```ruby def initialize(class:, if:,) @class, @if = grab(class:, :if) end ``` -------------------------------- ### Table Component Rendering with and without Kits Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/kits.md Compares the syntax for rendering a `Table` component with and without using Phlex UI Kits. Kits offer a more concise syntax. ```ruby Table(@people) do |t| t.column("Name", &:name) t.column("Age", &:age) end ``` ```ruby render Table.new(@people) do |t| t.column("Name", &:name) t.column("Age", &:age) end ``` -------------------------------- ### Phlex Initializer Configuration Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md This snippet shows the configuration for the Phlex initializer file, setting up namespaces and autoloading for views and components. ```ruby # frozen_string_literal: true module Views end module Components extend Phlex::Kit end Rails.autoloaders.main.push_dir( "#{Rails.root}/app/views", namespace: Views ) Rails.autoloaders.main.push_dir( "#{Rails.root}/app/components", namespace: Components ) ``` -------------------------------- ### ERB Example of Unsafe Href Attribute Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/structural-safety.md Highlights a potential security vulnerability in ERB where user data in an `href` attribute is not properly escaped, unlike Phlex's approach. ```erb ``` -------------------------------- ### Define a Phlex UI Kit Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/kits.md Create a Kit by defining a module that extends `Phlex::Kit`. Any module within its namespace also becomes a Kit. ```ruby module Components extend Phlex::Kit end ``` -------------------------------- ### Initialize Card Component with `mix` Helper Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Use the `mix` helper to accept arbitrary attributes and merge them with default attributes. ```ruby class Card < Phlex::HTML def initialize(**attributes) @attributes = attributes end def view_template div(**mix({ class: "card" }, @attributes)) do # ... end end end ``` -------------------------------- ### Initialize Component with Reserved Keyword Argument using `grab` Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Use the `grab` helper to safely access keyword arguments that are also reserved Ruby words. ```ruby def initialize(class:) @class = grab(class:) # ✅ end ``` -------------------------------- ### Instantiate a Phlex Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md Create an instance of a Phlex component, passing any required properties to its initializer. ```ruby component = MyComponent.new(name: "World") ``` -------------------------------- ### Array and Set Attribute Values Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/attributes.md Demonstrates how arrays and sets are compacted and joined with spaces for attribute values like 'class'. ```ruby a( class: [ ("button"), ("active" if is_active), ("disabled" if is_disabled) ] ) { "Click me" } ``` -------------------------------- ### Initialize Component Buffer Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Initializes a component with an empty buffer, which will store HTML elements. ```ruby class Component def initialize @buffer = [] end end ``` -------------------------------- ### Basic Render Helper for Components Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/testing.md A simple `render` helper that takes a Phlex component instance and returns its HTML output by calling the component's `call` method. ```ruby def render(component) component.call end ``` -------------------------------- ### Create a Card Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Define a `Card` component that inherits from `Component` and uses the `div` helper to structure its content, demonstrating basic component creation. ```ruby class Card < Component def view_template(&) div(class: "card", &) end end ``` -------------------------------- ### Attribute Keys: Symbols vs. Strings Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/attributes.md Demonstrates how Phlex converts Ruby Symbols to HTML attribute names with dashes and how to use String keys to preserve underscores. ```ruby h1(data_controller: "hello") { "Hello!" } h1("data_controller" => "hello") { "Hello!" } ``` ```html

Hello!

Hello!

``` -------------------------------- ### Initialize Card Component with Manual Attributes Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Manually expose and handle specific attributes like ID and data for component customization. ```ruby class Card < Phlex::HTML def initialize(id: nil, data: {}) @id = id @data = data end def view_template div(id: @id, data: @data) do # ... end end end ``` -------------------------------- ### Render a Component using its Kit Helper Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/kits.md Render a component defined in a Kit by calling the generated helper method directly, passing arguments and a block. ```ruby class Example < Phlex::HTML def view_template Components::Card("Hello, World!") do p { "This is a card." } end end end ``` -------------------------------- ### Create Nested HelloWorld Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Defines a HelloWorld component that inherits from Component and renders nested divs. ```ruby class HelloWorld < Component def view_template div { div } end end ``` -------------------------------- ### Complete Table Component Implementation Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This is the full implementation of the `Table` component, combining initialization, column definition, vanishing the initial block, and rendering both headers and body rows. ```ruby class Table < Phlex::HTML def initialize(rows) @rows = rows @columns = [] end def view_template(&) vanish(&) table do thead do @columns.each do |column| th { column[:header] } end end tbody do @rows.each do |row| tr do @columns.each do |column| td { column[:content].call(row) } end end end end end end def column(header, &content) @columns << { header:, content: } nil end end ``` -------------------------------- ### Rendering Different Component and View Types in Rails Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/testing.md Demonstrates using the Rails-integrated `render` helper to render various types of components and views, including Phlex, ViewComponent, ERB partials, and ERB views. ```ruby # Phlex render SomePhlexComponent.new # ViewComponent render SomeViewComponent.new # ERB Partial render "some_partial" # ERB View render template: "some_view_template", layout: "some_layout" ``` -------------------------------- ### Render Card Component with Arbitrary Attributes Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Demonstrates how to pass arbitrary attributes to the Card component when rendering. ```ruby render Card.new(id: "my-card") render Card.new(data: { controller: "fancy-card" }) render Card.new(class: "purple-card") ``` -------------------------------- ### Define a Phlex Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md Define a basic Phlex component with an initializer and a view template. The `initialize` method accepts properties, and `view_template` defines the HTML structure. ```ruby class MyComponent < Phlex::HTML def initialize(name:) @name = name end def view_template h1 { "Hello, #{@name}" } end end ``` -------------------------------- ### Render Component Class Directly (No Arguments) Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md If a component does not require any initialization arguments, you can render its class directly. Phlex will automatically instantiate it by calling `new` without arguments. ```ruby class Views::Articles::Index < Phlex::HTML def initialize(articles:) @articles = articles end def view_template render Components::Sidebar @articles.each do |article| render Components::Article.new(article:) end end end ``` -------------------------------- ### Complete Component Class Implementation Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Presents the final, concise 33-line `Component` class, integrating all previously discussed features including `call`, `div`, `plain`, and `render` methods. ```Ruby class Component def call(buffer = []) @buffer = buffer view_template { yield(self) if block_given? } @buffer.join end def div(content = nil, **attributes) @buffer << "" if content @buffer << content elsif block_given? yield end @buffer << "" end def plain(content) @buffer << content end def render(component, &) component.call(@buffer, &) end end ``` -------------------------------- ### Render Component Without Block or Arguments Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/kits.md To render a component without a block or other arguments when using the Kit helper syntax, use empty parentheses. ```ruby Header() ``` -------------------------------- ### Using Rails Output and Value Helpers Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/helpers.md Combines an output helper (`link_to`) and a value helper (`article_path`) in a single call. ```ruby link_to "Article", article_path(@article) ``` -------------------------------- ### Complete Basic Component Class Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md A complete basic Component class including initialization, rendering, and buffer management. ```ruby class Component def initialize @buffer = [] end def call view_template @buffer.join end def div @buffer << "
" yield if block_given? @buffer << "
" end end ``` -------------------------------- ### Include a Kit for Namespace-less Rendering Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/kits.md Include a Kit module into your component to make all its component helper methods available without the namespace prefix. ```ruby class Example < Phlex::HTML include Components def view_template Card("Hello, World!") do p { "This is a card." } end end end ``` -------------------------------- ### Render a Phlex View in a Rails Controller Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/views.md In your Rails controller, instantiate and render the Phlex view. Pass any necessary data as arguments to the view's initializer. ```ruby class ArticlesController < ApplicationController def index render Views::Articles::Index.new( articles: Article.all ) end end ``` -------------------------------- ### Call Component and Join Buffer Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Renders the component's view template and joins the buffer into a single string for output. ```ruby def call view_template @buffer.join end ``` -------------------------------- ### Outputting Plain Text with `plain` Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/text.md Use the `plain` method to render literal strings as text within your Phlex views. This is the most direct way to output non-HTML content. ```ruby plain "Hello, world!" ``` -------------------------------- ### Render Nested Card Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Update the `HelloWorld` component to render the `Card` component, passing content to it via a block, showcasing component nesting. ```ruby class HelloWorld < Component def view_template div(class: "outer") { render Card.new do div("Hello, World!", class: "inner") end } end end ``` -------------------------------- ### Configure Phlex FIFOCacheStore Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/caching.md Implement a custom cache store by defining the `cache_store` method to return an instance of `Phlex::FIFOCacheStore`, ensuring it's stored in a constant to maintain cache state. ```ruby class Components::Base CACHE = Phlex::FIFOCacheStore.new( max_bytesize: 20_000_000 # 20MB ) def cache_store CACHE end end ``` -------------------------------- ### Original `classes` and `tokens` Implementation in Phlex v2 Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md These are the original implementations for `classes` and `tokens` helpers that were removed in Phlex v2. They can be copied back if needed for backward compatibility. ```ruby def classes(*tokens, **conditional_tokens) tokens = self.tokens(*tokens, **conditional_tokens) if tokens.empty? {} else { class: tokens } end end def tokens(*tokens, **conditional_tokens) conditional_tokens.each do |condition, token| truthy = case condition when Symbol then send(condition) when Proc then condition.call else raise ArgumentError, "The class condition must be a Symbol or a Proc." end if truthy case token when Hash then __append_token__(tokens, token[:then]) else __append_token__(tokens, token) end else case token when Hash then __append_token__(tokens, token[:else]) end end end tokens = tokens.select(&:itself).join(" ") tokens.strip! tokens.gsub!(/\s+/, " ") tokens end private def __append_token__(tokens, token) case token when nil then nil when String then tokens << token when Symbol then tokens << token.name when Array then tokens.concat(token) else raise ArgumentError, "Conditional classes must be Symbols, Strings, or Arrays of Symbols or Strings." end end ``` -------------------------------- ### Style Attribute with Hash Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/attributes.md Demonstrates the special handling of the 'style' attribute, converting a hash into a CSS string. ```ruby h1(style: { color: "red", font_size: "16px" }) { "Hello!" } ``` ```html

Hello!

``` -------------------------------- ### Rendering Nav Component from ERB Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md Demonstrates rendering a Phlex Nav component from ERB, utilizing yielded blocks for each item and a divider. ```erb <%= render Nav do |nav| %> <% nav.item("/") do %> Home <% end %> <% nav.item("/about") do %> About <% end %> <% nav.divider %> <% nav.item("/contact") do %> Contact <% end %> <% end %> ``` -------------------------------- ### Rendering Table Component with Block Arguments from ERB Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md Shows how to render a Phlex Table component from ERB, passing a block with arguments for column definitions. ```erb <%= render Table.new(@people) do |t| t.column("Name", &:name) t.column("Age", &:age) end %> ``` -------------------------------- ### Render a Phlex Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md Render a Phlex component instance to an HTML string using its `call` method. This is the standard interface for rendering components, often integrated into frameworks. ```ruby component = MyComponent.new(name: "World") html_output = component.call ``` -------------------------------- ### Configure Phlex to Use Rails Cache Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/caching.md Integrate Phlex with Rails by configuring the `cache_store` method to return `Rails.cache`, leveraging Rails' caching infrastructure. ```ruby class Components::Base def cache_store Rails.cache end end ``` -------------------------------- ### Rendering Nav with Serialized Data Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This snippet shows a basic way to render a navigation component by passing an array of data. It is less flexible for complex styling or structure. ```ruby render Nav.new( ["Home", "/"], ["About", "/about"], ["Contact", "/contact"] ) ``` -------------------------------- ### New Way to Render Rails Partials in Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md This demonstrates the current, required method for rendering Rails partials in Phlex using the `partial` method. This approach is necessary for supporting plain string rendering and is also usable outside of Phlex. ```ruby render partial("foo") ``` -------------------------------- ### Implementing Nav Component with Yielding Methods Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This Ruby class defines a `Nav` component that implements the custom yielding interface. It includes `view_template`, `item`, and `divider` methods to handle rendering navigation elements and their associated content. ```ruby class Nav < Phlex::HTML def view_template(&) nav(class: "special-nav", &) end def item(href, &) a(class: "special-nav-item", href: href, &) end def divider span(class: "special-nav-divider") end end ``` -------------------------------- ### View Template Using Vanish Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This view template uses `vanish` to yield the block and discard any immediate output. This is crucial for collecting column definitions without rendering intermediate HTML. ```ruby def view_template(&) vanish(&) end ``` -------------------------------- ### Handling User Settings with Splatted Attributes Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/structural-safety.md Demonstrates how Phlex validates attribute keys when splatting user settings. It raises an error if unsafe characters are found, encouraging code fixes rather than escaping. ```ruby div(**@user.settings) ``` -------------------------------- ### Define a Button Component Class in Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/compare/slim.md This snippet demonstrates how to create a more sophisticated button component as a Ruby class in Phlex. It includes initialization with parameters and a view template method for rendering. ```ruby class Components::MyButton < Components::Base def initialize(style:, color:) @style = style @color = color end def view_template(&) button(class: [@style, @color], &) end end ``` -------------------------------- ### Define a Phlex Kit with Nested Components Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md This Ruby code demonstrates how to define a Phlex Kit named 'Components' and a nested module 'Articles' within it. Components defined under 'Articles' will be automatically associated with this kit, simplifying their rendering. ```ruby module Components extend Phlex::Kit module Articles # this is automatically upgraded to a kit class List < Phlex::HTML # this is available on the `Components::Articles` kit end end end ``` -------------------------------- ### Outputting Raw HTML with Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/raw.md Use the `raw` method to output unescaped HTML. Ensure the string is marked as safe using the `safe` method before passing it to `raw`. This is useful when integrating with other gems that generate HTML. ```ruby raw safe( Commonmarker.to_html(@markdown) ) ``` -------------------------------- ### Render Plain Text within Nested Components Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Demonstrates updating a component to use the `plain` method for rendering text content within a nested component structure. This shows how to integrate plain text output into the view template. ```Ruby class HelloWorld < Component def view_template div(class: "outer") { render Card.new do plain "Hello, World!" end } end end ``` -------------------------------- ### Table Component with Column-Based Interface Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This snippet demonstrates a more abstract table interface where columns are defined, and the component automatically generates headers and rows. It's ideal for cleaner data presentation. ```ruby render Table.new(@people) do |t| t.column("Name") { |person| person.name } t.column("Age") { |person| person.age } end ``` -------------------------------- ### Cache Template Fragments with Keys Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/caching.md Use the `cache` method with positional arguments as cache keys to conditionally render template fragments. The block executes only on a cache miss. ```ruby def view_template cache(@user, @article) do h1 { @article.title } end end ``` -------------------------------- ### Rendered HTML Output with Card Title Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Shows the final HTML output generated by the `HelloWorld` component after implementing the `card.title` interface, demonstrating the correct rendering of the nested card title. ```HTML
Hello, World!
``` -------------------------------- ### Table Component Initializer Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md Initializes the table component with a collection of rows and an empty array to store column definitions. This sets up the component to receive column configurations. ```ruby def initialize(rows) @rows = rows @columns = [] end ``` -------------------------------- ### Registering Custom Value and Output Helpers Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/helpers.md Shows how to register custom Rails view helpers as value helpers (not pushed to buffer) or output helpers (pushed to buffer). ```ruby class Components::Base < Phlex::HTML # Register a Rails helper that returns a value that shouldn’t be pushed to the output buffer. # e.g. if you want to use it like `div { format_release_date(book.date) }` register_value_helper :format_release_date # Register a Rails helper that returns safe HTML to be pushed to the output buffer. register_output_helper :pagy_nav end ``` -------------------------------- ### Call Component Methods from Parent Block Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Updates the `HelloWorld` component to render a card title by yielding the `Card` instance from the `render` method's block. This allows calling component-specific methods like `card.title`. ```Ruby class HelloWorld < Component def view_template div(class: "outer") { render Card.new do |card| card.title "Hello, World!" end } end end ``` -------------------------------- ### Including the Routes Adapter in Base Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/helpers.md Includes the `Routes` adapter in a base Phlex component to make all Rails route helpers available. ```ruby class Components::Base < Phlex::HTML include Phlex::Rails::Helpers::Routes end ``` -------------------------------- ### Recreate DeferredRender functionality Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md The `DeferredRender` class has been removed. This module can be used to recreate its effect, allowing actions to be performed before the template is rendered. ```ruby module DeferredRender def before_template(&) vanish(&) super end end ``` -------------------------------- ### Basic Attribute Caching with Hash Keys Source: https://github.com/yippee-fun/phlex.fun/blob/main/design/attribute-caching.md This snippet demonstrates a basic approach to caching attribute strings using the attributes hash itself as the cache key. It's a straightforward method for reusing previously computed attribute strings. ```ruby CACHE[attributes_hash] ||= calculate_attributes(attributes_hash) ``` -------------------------------- ### Generate a Phlex View Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/views.md Use the phlex-rails generator to create a new view file. By convention, view names should correspond to controller and action names. ```bash bundle exec rails g phlex:view Articles::Index ``` -------------------------------- ### Render Phlex Component from Rails Controller Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/rendering.md Render a Phlex component directly from a Rails controller action using the `render` method. This allows Rails to provide a view context, enabling access to Rails helpers. ```ruby def index render Views::Articles::Index.new( articles: Article.all ) end ``` -------------------------------- ### Combining HTML and Plain Text in Blocks Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/text.md Mix HTML rendering methods (like `strong`) with the `plain` method within a block to achieve mixed formatting. Phlex will render HTML tags directly and output any plain text returned or explicitly rendered. ```ruby h1 do strong { "Hello" } plain " World" end ``` -------------------------------- ### Combine Attributes with `mix` Helper Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/helpers.md Illustrates how `mix` merges attributes, treating values like token lists for combining classes or controllers. ```ruby mix({ class: "default classes" }, { class!: "only-use-this-class" }) #=> { class: "only-use-this-class" } ``` -------------------------------- ### Rendering Table Component with Nested ERB Blocks from ERB Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md Illustrates rendering a Phlex Table component from ERB, using nested ERB blocks for more complex column content. ```erb <%= render Table.new(@people) do |t| %> <% t.column("Name") do |person| %> <%= person.name %> <% end %> <% t.column("Age") do |person| %> <%= person.age %> <% end %> <% end %> ``` -------------------------------- ### Add phlex-rails Gem Source: https://github.com/yippee-fun/phlex.fun/blob/main/introduction/getting-started.md Add the phlex-rails gem to your project's Gemfile using Bundler. ```bash bundle add phlex-rails ``` -------------------------------- ### Wrapping Form Builder for Literal Properties Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/helpers.md Demonstrates how to wrap a Rails FormBuilder in `Phlex::Rails::Builder` when defining properties for components that use Literal. ```ruby class Components::FormGroup < Components::Base extend Literal::Properties prop :form, Phlex::Rails::Builder(ActionView::Helpers::FormBuilder) end ``` -------------------------------- ### Base Phlex View for Compositional Layouts Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/layouts.md A base Phlex view that includes necessary modules and defines a `PageInfo` data structure. It uses `around_template` to render a specified layout component, passing page information. ```ruby class Views::Base < Phlex::HTML include Components PageInfo = Data.define(:title) def around_template render layout.new(page_info) do super end end def page_info PageInfo.new( title: page_title ) end end ``` -------------------------------- ### Base Phlex View with Layout Rendering Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/layouts.md A base Phlex view that implements an `around_template` hook to render a complete HTML document structure, including head and body. ```ruby class Views::Base < Phlex::HTML def around_template doctype html do head do title { page_title } end body { super } end end end ``` -------------------------------- ### Nokogiri Helper for Parsing HTML Documents Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/testing.md A helper method that renders a component and parses its HTML output as a full document using Nokogiri. This is suitable for testing complete HTML structures. ```ruby def render_document(...) html = render(...) Nokogiri::HTML5(html) end ``` -------------------------------- ### Complete Component Class with Nesting Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md The complete `Component` class includes updated `call` and `render` methods, along with a `div` helper for building HTML structures. ```ruby class Component def call(buffer = [], &) @buffer = buffer view_template(&) @buffer.join end def div(content = nil, **attributes) @buffer << "" if content @buffer << content elsif block_given? yield end @buffer << "" end def render(component, &) component.call(@buffer, &) end end ``` -------------------------------- ### Automatically make Turbo Frames selectively renderable Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md To integrate with Turbo Frames, extend the `turbo_frame` method to automatically make all frames selectively renderable using their IDs. ```ruby def turbo_frame(id:, ...) fragment(id) { super } end ``` -------------------------------- ### Add Plain Text Rendering to Component Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Introduces the `plain` method to allow rendering text content directly without wrapping it in HTML tags. This is useful for inserting simple strings into the component's output. ```Ruby def plain(content) @buffer << content end ``` -------------------------------- ### Define Component Render Method Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Implement a `render` method within the Component class to facilitate rendering other components and passing the current buffer and block. ```ruby def render(component, &) component.call(@buffer, &) end ``` -------------------------------- ### Update selective rendering with explicit fragment declarations Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md Phlex v2 redesigns selective rendering to be more predictable. Content must now be explicitly declared as a renderable fragment using the `fragment` helper. Fragment names are decoupled from DOM element IDs. ```ruby # Before (Phlex ~> 1.10) def view_template section do ul(id: "the-list") do # Could target this by ID li { "Item 1" } li { "Item 2" } end end end # Usage: component.call(fragments: ["the-list"]) ``` ```ruby # After (Phlex 2.0) def view_template section do fragment("the-list") do # Explicitly declare renderable fragment ul(id: "the-list") do li { "Item 1" } li { "Item 2" } end end end end # Usage remains the same: component.call(fragments: ["the-list"]) ``` -------------------------------- ### Bypassing Unsafe Attribute Guard Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/structural-safety.md Illustrates how to bypass Phlex's default guard against unsafe attributes like 'onclick' by marking the value as safe using the `safe` method. ```ruby button onclick: safe("alert(1)") ``` -------------------------------- ### Bypassing JavaScript Protocol Guard Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/structural-safety.md Demonstrates how to bypass Phlex's protection against JavaScript protocol in ref attributes by using the `safe` method. ```ruby a(href: safe("javascript:alert(1)")) { "Click me" } ``` -------------------------------- ### Old Way to Render Rails Partials in Phlex Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/v2-upgrade.md This shows the previous method of rendering Rails partials directly within Phlex. This syntax is no longer supported. ```ruby render "foo" ``` -------------------------------- ### Setting Phlex Layout in Controller Source: https://github.com/yippee-fun/phlex.fun/blob/main/rails/layouts.md Specify a Phlex component as the layout for a Rails controller using a Proc. ```ruby class ArticlesController layout -> { Components::Layout } end ``` -------------------------------- ### String Attribute Values Source: https://github.com/yippee-fun/phlex.fun/blob/main/sgml/attributes.md Shows how string values are rendered directly, with double-quotes being escaped. ```ruby input(name: "first_name") ``` ```html ``` -------------------------------- ### Render Div Tag Source: https://github.com/yippee-fun/phlex.fun/blob/main/miscellaneous/under-the-hood.md Appends opening and closing 'div' tags to the buffer. Yields to a block if provided, allowing for nested content. ```ruby def div @buffer << "
" yield if block_given? @buffer << "
" end ``` -------------------------------- ### Table Component with Explicit Head and Body Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/yielding.md This snippet shows a basic table structure using explicit head, body, row, header, and cell methods. It's useful for directly defining table elements. ```ruby render Table do |t| t.head do t.row do t.header { "Name" } t.header { "Age" } end end t.body do @people.each do |person| t.row do t.cell { person.name } t.cell { person.age } end end end end ``` -------------------------------- ### Rails Integration: Render Helper with View Context Source: https://github.com/yippee-fun/phlex.fun/blob/main/components/testing.md A `render` helper designed for Rails applications. It utilizes the `view_context` to render components, allowing access to Rails view helpers. It also defines helpers for accessing and memoizing the test controller and its view context. ```ruby def render(...) view_context.render(...) end def view_context controller.view_context end def controller @controller ||= ActionView::TestCase::TestController.new end ```