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

Named block syntax #317

Closed
wants to merge 1 commit into from
Closed

Named block syntax #317

wants to merge 1 commit into from

Conversation

mmun
Copy link
Member

@mmun mmun commented Mar 23, 2018

@jonnii
Copy link

jonnii commented Mar 24, 2018

I personally find this syntax really awkward to parse, and I think the reason is that I expect something to be on the other side of the = sign, to me it looks like something is missing... what's the reason for not being able to do <@this.header> ?

@mmun
Copy link
Member Author

mmun commented Mar 24, 2018

I think you mean <@header>, right? It's hard for me to assign a useful meaning to <@this.header>

It's certainly a possibility to not have the equal sign but it comes with its own problems:

Not clear that it has the same semantics as a named arg

A beginner is more likely to think that this sort of syntax is possible when in it is not:

<Table>
  <@column>...</@column>
  <@column>...</@column>
  <@column>...</@column>
</Table>

In fact, it is equivalent to

<Table @column=... @column=... @column=... />

which is fairly clearly an invalid.

Contrast with

<Table>
  <@column=>...</@column>
  <@column=>...</@column>
  <@column=>...</@column>
</Table>

which carries more of the characteristics of the second snippet.

It looks like an angle bracket invocation

In the angle bracket invocation RFC we propose that <PowerAccordian></PowerAccordian> should be equivalent to {{#power-accordian}}{{/power-accordian}}.

Consequently, I think it would be very surprising if <@header></@header> meant anything other than {{@header}}{{/@header}}.

To be clear, I'm not proposing that we add this syntax, but rather that if we did add that syntax that there is only one real possible thing that it can mean.

@mmun
Copy link
Member Author

mmun commented Mar 24, 2018

In case it's not clear to anyone what is meant by "named blocks are named args" it may be useful to make an analogy with JavaScript.

The Handlebars template

<PowerAccordian @items={{blogPosts}}>
  <@header= as |item|>
    {{item.title}}
  </@header>

  <@details= as |item|>
    <h4>By {{item.author}}</h4>
    <p>{{item.text}}</p>
  </@details>
</PowerAccordian>

is conceptually similar to this JavaScript

PowerAccordian(Object.assign({ items: this.blogPosts }, {
  header: (item) => {
    return item.title;
  },
  details: (item) => {
    return [item.author, item.text];
  }
}));

@Turbo87
Copy link
Member

Turbo87 commented Mar 25, 2018

bildschirmfoto 2018-03-25 um 16 02 14

FYI for IntelliJ (20% of our users according to https://www.emberjs.com/ember-community-survey-2018/) this is entirely broken... 😞

@mmun
Copy link
Member Author

mmun commented Mar 25, 2018

@Turbo87 Damn. Part of this RFC should be to address the impact on syntax highlighting in popular editors and how difficult it would be to change them to support this syntax. If it's too difficult to change them we may have to look to another syntax style entirely...

@Turbo87
Copy link
Member

Turbo87 commented Mar 25, 2018

I think you mentioned it above already, it's not (only) the = sign that's breaking, the @ prefix alone is also a problem. Using {{#@foobar as |whatever|}} works fine, but I assume you would prefer to use angle brackets for everything?

@ef4
Copy link
Contributor

ef4 commented Mar 26, 2018

I think making nice syntax highlighters is important, but I don't think that should limit our syntax choices here.

We are already far from having a good experience with a generic handlebars syntax highlighter. Having dedicated glimmer template highlighters seems already a pretty strong requirement.

Consider for example that <Input> and <input> should be highlighted in different colors (because one will be a component invocation and one is regular HTML). No generic hbs highlighter is going to do that.

@Turbo87
Copy link
Member

Turbo87 commented Mar 26, 2018

I think making nice syntax highlighters is important

FWIW this is not just about syntax highlighters. We might be able to make our own (for each editor/IDE...), but e.g. in IntelliJ we would lose all of the builtin refactoring and code analysis functionality around HTML and Handlebars since we most likely can't just extend the builtins that easily...

@cibernox
Copy link
Contributor

I'm curious about why this (and previous) RFCs lean towards special syntax <@foo= as |arg1 arg2|> instead of using a keyword, like <Block name="foo" as |arg1 arg2|>.

It seems simpler to me so I'd like to know if there is a reason I can't see.

@ef4
Copy link
Contributor

ef4 commented Mar 27, 2018

I'm not sure which part of the syntax you consider special, so I will address both.

First, I'll address the @. The argument here is that it's not special. It's how all arguments to angle bracket components are named:

<Panel @title="x">
  <@body=>
     y
  </@body>
</Panel>

Is just a more expanded/generalized form of

<Panel @title="x" @body="y"/>

Second, I'll address the =. Partly it's there because of the strength of the analogy above. But it's also there because <@foo= is doing something radically different from a regular component invocation, so I think it's important that it look different from a component invocation.

For example: it's reasonable to expect that <Block /> is going to put something into the DOM at the location where it appears. But <@foo= doesn't do that. When (if!) it ends up in DOM, it will be somewhere else.

Another example: when you use <@foo=, it suddenly becomes a syntax error to have anything other than more block definitions as siblings. No regular component invocation would impose that kind of requirement.

On the other side (block invocation), we actually do try to make it feel like regular invocation (because it is). <@foo /> is taking the @foo argument you received and invoking it. The intention here is not really "special syntax", it's that (1) arguments you receive from outside always start with @, (2) this particular argument we want to invoke like a component, so it goes in angle brackets.

@cibernox
Copy link
Contributor

cibernox commented Mar 27, 2018

I can see how the<@foo=> declaration aligns nicely with the <@foo /> invocation. The explanation is satisfactory.

@kellyselden
Copy link
Member

Can we have some examples of the rendering side? Like:

{{#each @items as |item|}}
  {{@header item}}
  {{@details item}}
{{/each}}
{{#if @header}}
  {{@header item}}
{{else}}
  No header
{{/if}}
{{#@header}}
  I assume we error gracefully here.
{{/@header}}

Any other different ways to use this I missed?

@balinterdi
Copy link

For example: it's reasonable to expect that is going to put something into the DOM at the location where it appears. But <@foo= doesn't do that. When (if!) it ends up in DOM, it will be somewhere else.

@ef4 The result of invoking the named block will still render it inside the component (<Panel ...>) unless the component uses a wormhole internally, won't it?

@ef4
Copy link
Contributor

ef4 commented Mar 28, 2018

Yes, they'll normally be somewhere inside the component, but the specific location and ordering of blocks doesn't match the way they appear in the caller's template:

{{! Invocation }}
<Panel>
  <@first=>
    First
  </@first>
  <@second=>
    Second
  </@second>
{{! implementation of Panel}}
<div class="panel">
  <@second />
  <table>
    <tbody>
      <tr>
         <td>
           {{#if showFirst}}
             <@first />
           {{/if}}
         </td>
      </tr>
    </tbody>
  </table>
</div>

If we treated the block definitions as if you were invoking components, it would be very weird for @first to come after @second, and so far away from it in DOM.

@rtablada
Copy link
Contributor

@mmun something that I noticed when looking at other RFCs. It would be helpful to see how this is different from the existing RFC'd syntax.

I worry that some comments may be more about named blocks in general rather than the changes being recommended.

@knownasilya
Copy link
Contributor

Is there any movement on this, anything blocking from FCP?

@billybonks
Copy link

would love to know if anything is blocking this as well.

@rwjblue
Copy link
Member

rwjblue commented Jun 28, 2019

@mmun - I think this was superseded by (now merged) #460, can you confirm?

@mmun
Copy link
Member Author

mmun commented Jun 28, 2019

@rwjblue confirm

@mmun mmun closed this Jun 28, 2019
@mmun mmun deleted the named-block-syntax branch June 28, 2019 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.