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

Override-able template "blocks" #245

Open
jcs224 opened this issue Jul 9, 2023 · 4 comments
Open

Override-able template "blocks" #245

jcs224 opened this issue Jul 9, 2023 · 4 comments

Comments

@jcs224
Copy link

jcs224 commented Jul 9, 2023

Is your feature request related to a problem? Please describe.
There are instances where I'd like to be able to override default content of a template cleanly, such as including different scripts and styles on a different page, or showing different navigation from the default.

Describe the solution you'd like
Here is a basic example of what the desired behavior might look like. In this case, overriding a script. Here is the layout:

<!-- main.eta -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Cool New App</title>
    <% block('styles') %>
</head>
<body>
    <h1>Here is some content.</h1>
    <% it.body %>
    
    <% block('scripts') { %>
    <script>
        console.log('this script will be included on every page by default, unless a sub-template overrides it.')
    </script>
    <% } %>
</body>
</html>

And here is a sub-template, utilizing the above layout:

<!-- some-page.eta -->
<% layout('@main') %>

<p>This is the body of a page.</p>

<% block('styles') { %>
<link rel="stylesheet" href="styles-only-on-this-page.css">
<% } %>

<% block('scripts') { %>
<script>
    console.log('the default script will not load, because I overrode it here.')
</script>
<% } %>

Describe alternatives you've considered
I've looked at other JS templating engines, but this fits my needs best based on the runtime flexibility and most of the features I need are available.

Additional context

Here are some existing templating engine's examples that might provide additional context:

https://mozilla.github.io/nunjucks/templating.html#block
https://laravel.com/docs/10.x/blade#layouts-using-template-inheritance

@nebrelbug
Copy link
Collaborator

@jcs224 this should be possible currently by defining a custom function, block, using the functionHeader option.

@jcs224
Copy link
Author

jcs224 commented Jul 16, 2023

Awesome, thanks! I looked in the documentation for some help on how to get started with using functionHeader, are there any other examples I can follow? A simple example of an existing implementation would be quite helpful...

@nebrelbug
Copy link
Collaborator

@jcs224 I don't have an example right off hand, and am a bit too busy with work to draft one up right now -- sorry 😬.

If you're able to get something working, please comment here and share it with others!

@AimForNaN
Copy link

I've checked the source code, and if I read everything correctly, I don't see how this would be possible with the functionHeader option. If you consider the functionHeader option, this requires valid JS code. The syntax proposed in the OP for the custom block function is not valid JS code. Then there is the issue that the layout function is arguably an alias to the include function with the exception that it inserts its own context (for body). This makes it appear that this feature is beyond the scope of everything aforementioned. Arguably, perhaps something can be done using plugins, but I haven't checked to see what AST plugins are exposed to.

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

No branches or pull requests

3 participants