11ty / eleventy-plugin-webc

Adds support for WebC *.webc files to Eleventy
https://www.11ty.dev/docs/languages/webc/
119 stars 10 forks source link

Passing data from Nunjucks to Webc #41

Open andeersg opened 1 year ago

andeersg commented 1 year ago

Been testing webc components in a Eleventy blog but I struggle with passing data from existing nunjucks templates to webc components.

I have a collection for my front page like this:

{% for post in collections.latestPosts %}
  {% renderTemplate "webc" %}
  <post-front>
    <div slot="title">
      <a href="{{ post.url }}">{{ post.data.title }}</a>
    </div>
    <p slot="description">{{ post.data.tldr }}</p>
    <span slot="meta">{{ post.date | readableDate}}</span>
  </post-front>
  {% endrenderTemplate %}

  <!-- Old way -->
  <article class="card">
    <h3><a href="{{ post.url }}">{{ post.data.title }}</a></h3>
    <p>{{ post.data.tldr }}</p>
    <span>{{ post.date | readableDate}}</span>
  </article>
{% endfor %}

This is how I have set up my component so far:

<template>
  <article class="card">
    <h3><slot name="title"></slot></h3>
    <slot name="description"></slot>
    <slot name="meta"></slot>
  </article>
</template>

But this is the output:

<article class="card">
  <h3><div slot="title">
              <a href="{{ post.url }}">{{ post.data.title }}</a>
            </div></h3>
  <p slot="description">{{ post.data.tldr }}</p>
  <span slot="meta">{{ post.date | readableDate}}</span>
</article>

I'm probably doing something wrong here?

solution-loisir commented 1 year ago

It's as if the content rendered by WebC is being escaped by Nunjucks. Where you able to find a solution or are you still stuck?

timonforrer commented 1 year ago

@andeersg I ran into a similar issue. I created a WebC component that uses a <script> with webc:type="js" set, so I can pass in data and modify it using js.

The component looks like this:

hello-world.webc

<script webc:type="js" webc:is="template">
  `<p>
    ${data ? data.message : undefined}
  </p>`
</script>

Theoretically, you could pass in the data by prefixing the attribute of the component with a colon. For this component it would look like this:

<hello-world :data="data"></hello-world>

I crated two pages, where I included the component:

The data gets passed in properly on the WebC page, but on the Nunjucks page the component receives undefined.

I created a simple repo to reproduce this: https://github.com/timonforrer/11ty-nunjucks-webc/

solution-loisir commented 1 year ago

@timonforrer, very interesting. Could it be related to #24? I noticed that you try to pass data in a :data dynamic attribute. I'm not sure this is doing what you think as the Eleventy data cascade is available inside of a WebC component since your :data attribute as the same name as the data object it looks like it's passing data, but in fact is passing "data" as a string. Try to remove the :data attribute and see if it still work. Sorry this is side tracking from the topic and I could well be wrong. Nice experiment by the way.

marcradziwill commented 1 year ago

Update:

It was my fault. I got help in the discord forum from darthmall. Thanks again 💪

{%- set translation = 'externallink' | i18n( { link: 'Openstreetmap' }, lang) | safe -%}
{% renderTemplate "webc", {translation: translation} %}
     <tool-tip inert="" role="tooltip" @translation="translation"></tool-tip>
{% endrenderTemplate %}

I'm having the same issue. I can not render data in {% renderTemplate "webc" %} from Nunjucks. If I rewrite it all to webc, it works. As I'm on the latest WebC Plugin Version (0.8.1) it might not be related to #24. But I'm just guessing. If it is rather a bug for EleventyRenderPlugin, sry for posting here.

To Reproduce

  1. Create a njk and a webc layout
  2. Create a njk and webc page referring to that layout from 1.
  3. Create a simple webc component
  4. Render that component on both pages
  5. Render pages with npx eleventy

page.njk

---
layout: layouts/base.njk
lang: 'en'
---

{% renderTemplate "webc" %} 
    <tool-tip role="tooltip" webc:type="11ty" 11ty:type="njk" webc:keep>
        Lang: {{lang}}
        Translation: {{ 'externallink' | i18n({ link: 'Openstreetmap' }, lang)}} 
    </tool-tip>
{% endrenderTemplate %}

page.webc

---
layout: layouts/webc.webc
lang: 'en'
---
<tool-tip role="tooltip" webc:type="11ty" 11ty:type="njk" webc:keep>
    Lang: {{lang}}
    Translation: {{ 'externallink' | i18n({ link: 'Openstreetmap' }, lang)}} 
</tool-tip>

Expected behavior

Both pages should be rendered with the data resolved like this:

<tool-tip role="tooltip" 11ty:type="njk">
    Lang: en
    Translation: The link leads to Openstreetmap. 
    <style>
        tool-tip {
            background-color: blue;
        }
    </style>
</tool-tip>

Actual behavior

Webc files get rendered correctly, while njk looks like this. The lang data from the page is not accessible therefore, the translation shortcode just prints the key externallink:

<tool-tip role="tooltip" 11ty:type="njk">
  Lang: 
  Translation: externallink 
  <style>
    tool-tip {
        background-color: blue;
    }
  </style>
</tool-tip>

Environment:

OS and Version: Mac 12.5.1 Eleventy Version: 2.0.0-canary.29 WebC Plugin: 0.8.1 i18n Plugin: 0.1.3

I've tried to debug into EleventyRenderPlugin but didn't get any further. Let me know if I can help to further investigate this issue.

GuillaumeUnice commented 1 year ago

Anyone know whether there is any improvements or workaround around that?

frangeris commented 1 year ago

@GuillaumeUnice and for others for future references, use this way:

:parameter="`${this.myVar}`"

This is a working example of passing data from njk to webc:

{%- for section in collections.sections -%}
  {% renderTemplate "webc", section.data %}
    <x-section :url="`${this.url}`" :title="`${this.title}`"></x-section>
  {% endrenderTemplate %}
{%- endfor -%}

url and title are properties inside section.data

Hope it helps