Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECR: Support block syntax #15147

Open
skinnyjames opened this issue Nov 1, 2024 · 0 comments
Open

ECR: Support block syntax #15147

skinnyjames opened this issue Nov 1, 2024 · 0 comments

Comments

@skinnyjames
Copy link
Contributor

Feature Request

From discussion at https://forum.crystal-lang.org/t/block-capture-in-an-ecr-like-template-engine-results-in-out-of-order-output/6979/

Block syntax in ECR could allow for the composition of complex templates using Crystal classes and methods

Example:

# template.ecr
<div>
  <%|= form("POST", "/something.cgi") do |f| %>
    <div>
      <%= f.input("hello") %>
      <%|= f.nested("Foo") do |inner|  %>
        <div>
          <%= inner.input("hello") %>
        </div>
      <%| end %>
    </div>
  <%| end %>
</div>
# main.cr
class Builder  
  def nested(name, &block : Proc(Builder, IO, Nil))
    ->(io : IO) do
      io << "<nested type='#{name}'>"
      block.call(self, io)
      io << "</nested>"
    end
  end

  def input(name)
    "<input name='#{name}' />"
  end
end

def form(etc, name, &block : Proc(Builder, IO, Nil))
  ->(io : IO) do 
    io << "<form etc='#{etc}' name='#{name}'>"
    builder = Builder.new
    block.call(builder, io)
    io << "</form>"
  end
end
<div>
  <form etc='POST' name='/something.cgi'>
    <div>
      <input name='hello' />
      <nested type='Foo'>
        <div>
          <input name='hello' />
        </div>
      </nested>
    </div>
  </form>
</div>
  • Is your feature request related to a problem? Please describe clearly and concisely what is it.
    above

  • Describe the feature you would like, optionally illustrated by examples, and how it will solve the above problem.

Example: https://github.com/skinnyjames/ecr_with_blocks

Proposal would be to add a new token type to ECR that supports methods which

  • accept a block whose last parameter is an IO
  • return a Proc(IO, Nil)

The embed macro could then generate code which appends an IO parameter to the end of the template block

  • Describe considered alternative solutions, and the reasons why you have not proposed them as a solution here.
    alternatives may be to alter the template method call to accept an IO in parameter position.
    I think returning Proc(IO, Nil) is more clean and consistent.

  • Does it break backward compatibility, if yes then what's the migration path?
    Since the tokens are new, no major breaking changes, however, it should work with suppressing indentation.

In case this proposal includes a substantial change to the language, we ask you to go through an RFC process.

The best place to start an open discussion about potential changes is the Crystal forum.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants