-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add a Component template tag #165
Comments
Is this mechanism similar to Jinja macros? Considering this example, I'm a bit uncertain about the value of this mechanism. As far as I can see, this example could be implemented very easily using a snippet and the For example, the snippet could look something like this: <button class="{{ type }}">
{{ text | default: "Default slot text" }}
</button> And then you could use this snippet as follows: {% include "my_snippet" with type="primary" %}
{% include "my_snippet" with type="primary", text="Slot text" %} Why couldn't the The other aspect mentioned here is related to limiting access to variables inside included templates. This is something that is not supported by the present implementation of the {% include "my_snippet" with type="primary", text="Slot text" only %} It is true that From my understanding of the issue, what we want to do here is essentially make it possible to include templates whose input variables are validated properly. What about making it easy to define Crystal abstractions that allow doing just that by generating template tags that render these templates (something that is called custom inclusion tag in Django) while performing the intended validation? For example, defining such "inclusion tags" for Marten could look something like this: class MyButtonTag < Marten::Templates::InclusionTag
template_name "tags/button.html"
field :type, :string
field :text, :string, default: "My button name"
end And in a template, you would use the corresponding automatically generated template tag: {% my_button type: "primary", text: "Custom text" %} The advantage of doing this in Crystal is that it becomes possible to leverage But again, this (having validated inclusion tags) seems like a niche use case given that the |
Indeed For the slots I was thinking that marten could use named slots in the future. |
Do you have an example where you would need to include complex HTML in included templates? I guess a card with headers and bodies that can be overridden would be such an example. <div class="card-component">
<div class="header">
{% slot "header" %}Card header{% endslot %}
</div>
<div class="body">
{% slot "body" %}This is a <b>card</b> body{% endslot %}
</div>
</div> I have been using templating languages similar to Marten's for quite a long time and never found myself wishing for something like that so I am curious to understand more about this use case. At first sight, it looks like something inherited from concepts coming mainly from Vue.js? But even trying to implement the example above with For example: <div class="card-component">
<div class="header">
{% if header %}{{ header }}{% else %}Card header{% endif %}
</div>
<div class="body">
{% if body %}{{ body }}{% else %}This is a <b>card</b> body{% endif %}
</div>
</div> {% capture card_body %}
This is a <b>card</b> body with lots of custom HTML
{% endcapture %}
{% include "snippets/card.html" with body=card_body %} |
The upcoming Svelte 5 snippets are more flexible than Vue (and Svelte 4) slots, and the |
@ellmetha The Using However, for complex component logic, defining |
Improvements were shipped for the documentation. I think the Otherwise, I am going to look into these svelte snippets and think a bit more about this idea of inclusion tags. Let's continue this discussion! |
Snippets could replace layouts ( Here are some examples of how the concept of Svelte 5 snippets would translate to Marten templates. This differs from the Using current, {% extend "base.html" %}
{% block title %}Hello{% endblock %}
{% block content %}
<p>Hello world!</p>
{% endblock %} Using new, snippet-based layouts (note that main content is named {% snippet title %}Hello{% endsnippet %}
{% snippet children %}
<p>Hello world!</p>
{% endsnippet %}
{% include "base.html" with children=children title=title %} Even better, snippets defined in descendant content are automatically assigned to the context as variables: {% include "base.html" %}
{% snippet title %}Hello{% endsnippet %}
{# direct content is automatically assigned as a snippet to the 'children' variable #}
<p>Hello world!</p>
{% endinclude %}
<html>
<head>
<title>{% render title %}</title>
</head>
<body>
{% render children %}
</body>
</html> Rendering default when snippet is not provided: {% if title %}
{% render title %}
{% else %}
<h1>No title provided!</h1>
{% endif %} Providing extra context variables to the rendered snippet (similarly to {% render table_row with row_data=record %} This is useful for e.g. rendering tables, and any other situation where a single snippet can be rendered multiple times inside the same component, with different data (e.g. using |
Template inheritance and the use of Let's concentrate our discussion specifically on the matter of included templates. |
The above code examples could be applied to any components, not only layout components, but other use cases too. Obviously, the |
Description
Let's enhance Marten's templating system by introducing a new component tag. Unlike the existing include tag, the component tag provides a more structured and robust approach for building reusable components within templates.
Background
While the include tag serves its purpose for certain scenarios, it falls short when it comes to building complex applications with reusable components. There is a need for a more sophisticated mechanism that ensures better encapsulation, parameterization, and error handling within components.
Proposed Solution
Introduce a component tag to Marten's templating system, which offers the following key features:
Functionality
Example Usage:
Discussion
Where are components stored? How are they loaded when they are referenced?
The text was updated successfully, but these errors were encountered: