Open darthmall opened 1 year ago
I'm having the same issue. This is why I dropped .webc as layout format again and I got back to .11ty.js. In opposition to .webc the 11ty.js layouts are evaluated for every template using them.
Yes this is a bug. I was about to create an issue named
I have a footer components which lives on every page. The problem is the footer always thinks it's on one particular page for all instances.
It doesn't matter if I use this.page or $data.page or just page, it's always the same.
My footer-bar.webc
component looks like this:
<script webc:setup>
function getGitLabLink() {
console.log("Get gitlab link function called on page " + page.inputPath);
let repo_url = "https://gitlab.com/-/tree/master";
let relativeFilePath = page.inputPath;
relativeFilePath.startsWith(".") ? relativeFilePath.slice(1) : relativeFilePath;
return repo_url + relativeFilePath;
}
</script>
<p id="contribute-link">Contribute to this page on <a :href="getGitLabLink()">GitLab</a></p>
The console output looks like this:
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
Get gitlab link function called on page ./src/pawn.webc
It looks like the function responsible for providing the page context is here.
Perhaps one of us can figure out how to solve this issue as it's a pretty serious flaw preventing web components from being dynamic.
I made a pull request to fix:
I think I have a better solution! I think this staleness issue can also be avoided if you use pure functions in webc:setup
and you pass in the content to the function in the markup.
<script webc:setup>
// This goes stale and doesn't recompute every time
const impure = () => this.content.toUpperCase();
// Since this is a pure function, it gets called with the right data every time
const pure = (str) => str.toUpperCase();
</script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<meta name="generator" :content="eleventy.generator">
<title @html="this.title ? `@hasanhaja | ${this.title}` : '@hasanhaja'"></title>
<style @raw="getBundle('css')" webc:keep></style>
<script @raw="getBundle('js')" webc:keep></script>
</head>
<body>
<main>
<section>
<h2>Impure</h2>
<p @html="impure()"></p>
</section>
<section>
<h2>Pure</h2>
<p @html="pure(this.content)"></p>
</section>
</main>
<footer>
<p>
Copyright @hasanhaja 2023
</p>
</footer>
</body>
</html>
I need to try this with my project still where I also had this issue, but here's the repo to the code snippet if you want to play with it: https://github.com/hasanhaja/webc-data-cascade
Edit: It works :star_struck:
I can access the full data cascade from inside
<script webc:setup>
, but page-level data is not updated. My guess is thatwebc:setup
is run once per-component the first time it’s loaded and then never again. Inside of Eleventy, this is the first page that’s rendered with that component. This seems reasonable to me, except that you can access page-level data fromwebc:setup
, but that data never changes. I would expect that either the$data
is kept up-to-date for each page, or that access to data is somehow restricted to just global data in Eleventy.Example
Here’s a simple example of how this can be a little weird.
Input Files
my-title.webc
a.webc
b.webc
Output
a/index.html
b/index.html
Expected Output
I would expect that
b/index.html
has “Page B” for both the$data.title
and themyTitle
variables. Or, I think it would be best if trying to access data that changes from page-to-page inwebc:setup
throws an error so people know they can’t do something like this.Motivation
The actual use that motivated this was me trying to dynamically set a
<title>
attribute for a site.site-meta.webc