antonmedv / monkberry

Monkberry is a JavaScript library for building web user interfaces
https://monkberry.js.org
MIT License
1.49k stars 78 forks source link

Support for content inside components #6

Open benjamminf opened 8 years ago

benjamminf commented 8 years ago

Would be interesting if components could support inner content. Vue uses it's <slot> tags to accomplish this, which I quite like. Twig also has a similar approach using {% block %} tags.

I attempted to add inner content to a component, and while it compiled just fine, there was some strange behaviour. I'm not sure if this is something already implemented but just not documented.

antonmedv commented 8 years ago

Hi,

Now custom tags in Monkberry behave as inline components in vue. I was thinking about adding support for slots and block in future. But i need more use cases, to better understand what API should it have.

benjamminf commented 8 years ago

Here's a use case for a project I'm working on:

I have a header bar that contains the title of the page. The settings page requires a Save button to be added to the right of the title. The data graphing page requires Start, Stop and Export buttons. The buttons here are dependent on the page, and not the header bar, so it doesn't make sense to bundle them inside the header bar component. But I still need a way of displaying these buttons in the header bar.

I'm aware I could just make a "buttons" attribute to the header bar component, but I want it to be flexible enough to hold any form of HTML, and allow binding of any directives to those buttons, or whatever HTML is provided.

This application was written in Vue, and I used slots to solve this problem. I'm currently experimenting with replacing Vue with Monkberry, and I'm really liking how clean and flexible Monkberry's API is. So far, the only thing I can't seem to elegantly rebuild in Monkberry is this.

Thanks for your hard work, I'm really enjoying using it 👍

antonmedv commented 8 years ago

for now i see two options for this: using block and using slots.

Block

<header>
  {{ title }}
  {% block button %}{% endblock %}
</header>
<header title="...">
  {% block button %}
    <button>
  {% endblock %}
</header>

Slot

<header>
  {{ title }}
  <slot name="button"/>
</header>
<header title="...">
  <slot name="button">
    <button>
  </slot>
</header>

With block also possible to implement extending.

antonmedv commented 8 years ago

I like block way, because it allow also to implement template inherence, but need to find way to passing default data to block:

<Component>
    <div>...</div>
</Component>
<div>
    {% block %}{% endblock %}
</div>
benjamminf commented 8 years ago

Yeah I'm a fan of the {% block %} tag as well. It's a specialised tag, so it should stand out syntactically. Reserving a HTML tag name feels a bit too much like a hack. And as you said, it allows for template inheritance.