docs/pages/templates.rb in phlex-0.3.2 vs docs/pages/templates.rb in phlex-0.4.0

- old
+ new

@@ -3,239 +3,141 @@ module Pages class Templates < ApplicationPage def template render Layout.new(title: "Templates in Phlex") do render Markdown.new(<<~MD) - # Templates + # Working with templates - Rather than use another language like ERB, HAML or Slim, Phlex provides a Ruby DSL for defining HTML templates. + In Phlex, templates are just methods that call other methods that add things to the output buffer. When you call the method `h1`, an `<h1>` tag is buffered for output. - You can create a view class by subclassing `Phlex::View` and defining a method called `template`. Within the `template` method, you can compose HTML markup by calling the name of any [HTML element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element). + ## Tag attributes - The first argument to an HTML element method is the _text content_ for that element. For example, here’s a view with an `<h1>` element that says “Hello World!” + You can add attributes to HTML tags by passing keyword arguments to the tag methods. MD render Example.new do |e| - e.tab "heading.rb", <<~RUBY - class Heading < Phlex::View + e.tab "hello.rb", <<~RUBY + class Hello < Phlex::View def template - h1 "Hello World!" + h1(class: "text-xl font-bold") { "👋 Hello World!" } end end RUBY - e.execute "Heading.new.call" + e.execute "Hello.new.call" end render Markdown.new(<<~MD) - The text content is always HTML-escaped, so it’s safe to use with user input. + ## Hash attributes - ## Attributes - - You can add attributes to HTML elements by passing keyword arguments to the tag method. Underscores (`_`) in attribute names are automatically converted to dashes (`-`). + If you pass a `Hash` as an attribute value, the hash will be flattened with a dash between each section. MD render Example.new do |e| - e.tab "heading.rb", <<~RUBY - class Heading < Phlex::View + e.tab "hello.rb", <<~RUBY + class Hello < Phlex::View def template - h1 "Hello World!", - class: "text-xl font-bold", - aria_details: "details" + div(data: { controller: "hello" }) do + # ... + end end end RUBY - e.execute "Heading.new.call" + e.execute "Hello.new.call" end render Markdown.new(<<~MD) - You can also use *boolean* attributes. When set to `true`, the attribute will be rendered without a value, when _falsy_, the attribute isn’t rendered at all. + ## Boolean attributes + + When `true`, the attribute will be rendered without a value; when _falsy_, the attribute isn’t rendered at all. You can still use the strings `"true"` and `"false"` as values for non-boolean attributes. MD render Example.new do |e| - e.tab "example.rb", <<~RUBY - class Example < Phlex::View + e.tab "channel_controls.rb", <<~RUBY + class ChannelControls < Phlex::View def template - input type: "radio", name: "channel", id: "1", checked: true - input type: "radio", name: "channel", id: "2", checked: false + input( + value: "1", + name: "channel", + type: "radio", + checked: true + ) + + input( + value: "2", + name: "channel", + type: "radio", + checked: false + ) end end RUBY - e.execute "Example.new.call" + e.execute "ChannelControls.new.call" end render Markdown.new(<<~MD) - ## Nesting + ## The template tag - Pass a block to an element method to nest other elements inside it. + Because the `template` method is used to define the view template itself, you'll need to use the method `template_tag` if you want to to render an HTML `<template>` tag. MD render Example.new do |e| - e.tab "nav.rb", <<~RUBY - class Nav < Phlex::View + e.tab "example.rb", <<~RUBY + class Example < Phlex::View def template - nav do - ul do - li { a "Home", href: "/" } - li { a "About", href: "/about" } - li { a "Contact", href: "/contact" } - end + template_tag do + img src: "hidden.jpg", alt: "A hidden image." end end end RUBY - e.execute "Nav.new.call" + e.execute "Example.new.call" end render Markdown.new(<<~MD) ## Stand-alone text - You can also output text without wrapping it in an element by using the `text` method. All text content is HTML-escaped, so it’s safe to use with user input. + You can output text content without wrapping it in an element by using the `text` helper method. MD render Example.new do |e| e.tab "heading.rb", <<~RUBY class Heading < Phlex::View def template - h1 { strong "Hello "; text "World!" } + h1 do + strong { "Hello " } + text "World!" + end end end RUBY e.execute "Heading.new.call" end render Markdown.new(<<~MD) ## Whitespace - While the examples on this page have been formatted for readability, there is usually no whitespace between HTML tags. If you need to add some whitespace, you can use the `whitespace` method. This is useful for adding space between _inline_ elements to allow them to wrap. + The example output on this site is formatted for readability, but there is usually no whitespace between HTML tags in the output. If you need to add some whitespace, you can use the `whitespace` helper. This is useful for adding space between _inline_ elements to allow them to wrap. MD render Example.new do |e| e.tab "links.rb", <<~RUBY class Links < Phlex::View def template - a "Home", href: "/" + a(href: "/") { "Home" } whitespace - a "About", href: "/about" + a(href: "/about") { "About" } whitespace - a "Contact", href: "/contact" + a(href: "/contact") { "Contact" } end end RUBY e.execute "Links.new.call" - end - - render Markdown.new(<<~MD) - ## Tokens and classes - - The `tokens` method helps you define conditional HTML attribute tokens (such as CSS classes). - - The `tokens` method accepts a splat of tokens that should always be output, and accepts keyword arguments for conditional tokens. - - The keyword arguments allow you to specify under which conditions certain tokens are applicable. The keyword argument keys are the conditions and the values are the tokens. Conditions can be Procs or Symbols that map to a relevant method. The `:active?` Symbol, for example, maps to the `active?` instance method. - - Here we have a `Link` view that produces an `<a>` tag with the CSS class `nav-item`. And if the link is _active_, we also apply the CSS class `nav-item-active`. - MD - - render Example.new do |e| - e.tab "link.rb", <<~RUBY - class Link < Phlex::View - def initialize(text, to:, active:) - @text = text - @to = to - @active = active - end - - def template - a @text, href: @to, class: tokens("nav-item", - active?: "nav-item-active") - end - - private - - def active? = @active - end - RUBY - - e.tab "example.rb", <<~RUBY - class Example < Phlex::View - def template - nav do - ul do - li { render Link.new("Home", to: "/", active: true) } - li { render Link.new("About", to: "/about", active: false) } - end - end - end - end - RUBY - - e.execute "Example.new.call" - end - - render Markdown.new(<<~MD) - You can also use the `classes` helper method to create a token list of classes. Since this method returns a hash (e.g. `{ class: "your CSS classes here" }`), you can destructure it into a `class:` keyword argument using the `**` prefix operator. - MD - - render Example.new do |e| - e.tab "link.rb", <<~RUBY - class Link < Phlex::View - def initialize(text, to:, active:) - @text = text - @to = to - @active = active - end - - def template - a @text, href: @to, **classes("nav-item", - active?: "nav-item-active") - end - - private - - def active? = @active - end - RUBY - - e.tab "example.rb", <<~RUBY - class Example < Phlex::View - def template - nav do - ul do - li { render Link.new("Home", to: "/", active: true) } - li { render Link.new("About", to: "/about", active: false) } - end - end - end - end - RUBY - - e.execute "Example.new.call" - end - - render Markdown.new(<<~MD) - ## The template element - - Because the `template` method is used to define the view template itself, you need to use the method `template_tag` if you want to to render an HTML `<template>` tag. - MD - - render Example.new do |e| - e.tab "example.rb", <<~RUBY - class Example < Phlex::View - def template - template_tag do - img src: "hidden.jpg", alt: "A hidden image." - end - end - end - RUBY - - e.execute "Example.new.call" end end end end end