-
-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Hi!
First off, thanks for your work on this project — it's been really helpful!
While working on my current project, I wanted to use posthtml-include to include HTML partials with a slot-like feature. After digging into the source code, I noticed that the plugin uses posthtml-expressions, which supports the {{{ }}} triple-brace syntax to embed raw HTML.
This gave me an idea: I wanted to pass HTML directly inside the <include> tag and inject it into the partial using a {{{ defaultSlot }}} placeholder. To accomplish this, I created the following patch using patch-package:
diff --git a/node_modules/@vituum/vite-plugin-posthtml/node_modules/posthtml-include/lib/index.js b/node_modules/@vituum/vite-plugin-posthtml/node_modules/posthtml-include/lib/index.js
index ad5320a..3e18659 100644
--- a/node_modules/@vituum/vite-plugin-posthtml/node_modules/posthtml-include/lib/index.js
+++ b/node_modules/@vituum/vite-plugin-posthtml/node_modules/posthtml-include/lib/index.js
@@ -30,13 +30,17 @@ module.exports = (options = {}) => {
source = fs.readFileSync(src, options.encoding);
try {
- const localsRaw = node.attrs.locals || (node.content ? node.content.join().replace(/\n/g, '') : false);
+ const localsRaw = node.attrs.locals || "{}";
const localsJson = JSON.parse(localsRaw);
+ localsJson["defaultSlot"] = generateHtmlString(node.content)
+
posthtmlExpressionsOptions = {
...posthtmlExpressionsOptions,
locals: posthtmlExpressionsOptions.locals ? Object.assign(posthtmlExpressionsOptions.locals, localsJson) : localsJson
};
- } catch {}
+ } catch(e) {
+ console.log(e)
+ }
if (posthtmlExpressionsOptions.locals) {
const result = posthtml()
@@ -68,3 +72,24 @@ module.exports = (options = {}) => {
return tree;
};
};
+
+function generateHtmlString(element) {
+ if (typeof element === 'string') {
+ return element;
+ }
+
+ if (Array.isArray(element)) {
+ return element.map(generateHtmlString).join('');
+ }
+
+ if (typeof element === 'object' && element !== null) {
+ const { tag, attrs, content } = element;
+ const attributes = attrs ? Object.entries(attrs).map(([key, value]) => `${key}="${value}"`).join(' ') : '';
+ const openTag = `<${tag}${attributes ? ' ' + attributes : ''}>`;
+ const closeTag = `</${tag}>`;
+ const innerContent = content ? generateHtmlString(content) : '';
+ return `${openTag}${innerContent}${closeTag}`;
+ }
+
+ return '';
+}Proposal
I'm happy to contribute to this project in one of two ways:
-
Documentation-only — I can update the documentation to show how to use the
{{{ defaultSlot }}}syntax inposthtml-includeviaposthtml-expressions. -
Feature Addition — I'd love to help implement a more official "slot" feature, similar to how it's done in Vue/React/Web Components. If this route sounds good, I’d appreciate a bit of guidance on the preferred API shape, and I’ll take care of the implementation.
Let me know which direction you'd prefer. Either way, I’d love to help make this more usable for others. 😊
Thanks again!
This issue body was [partially generated by patch-package](ds300/patch-package#296).