Skip to content

Commit 20be589

Browse files
committed
first commit
0 parents  commit 20be589

File tree

5 files changed

+379
-0
lines changed

5 files changed

+379
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.DS_Store

example.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { compile } from "./index.js";
2+
3+
const html = `
4+
<div id="app" x-data="app()">
5+
6+
<section class="header h-100">
7+
<div class="container h-100">
8+
<div class="row align-items-center h-100">
9+
<div class="col-md-6">
10+
<img src="/templates/homebase/img/planet.png" class="img-fluid">
11+
</div>
12+
<div class="col-md-6 mx-auto" data-edit="header">
13+
<div>
14+
<h2 x-html="data.header.title"></h2>
15+
<p x-html="data.header.body"></p>
16+
</div>
17+
</div>
18+
</div>
19+
</div>
20+
</section>
21+
22+
<div class="row">
23+
<template x-for="item in data.items">
24+
<div class="col-md-4" data-edit="items" :id="item.id">
25+
<img :src="item.img" class="img-fluid w-50">
26+
<h3 x-html="item.title"></h3>
27+
<p x-html="item.body"></p>
28+
</div>
29+
</template>
30+
</div>
31+
32+
<template x-if="data.header.subtitle">
33+
<div x-text="data.header.subtitle"></div>
34+
</template>
35+
36+
</div>
37+
`;
38+
39+
const data = {
40+
header: {
41+
title: "Welcome to our site.",
42+
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et lacus non turpis congue congue. Integer porttitor non leo.",
43+
},
44+
items: [
45+
{
46+
id: "item-1",
47+
img: "/img/blobs1.png",
48+
title: "Feature One",
49+
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus id tortor neque.",
50+
layout: "post",
51+
},
52+
{
53+
id: "item-2",
54+
img: "/img/blobs2.png",
55+
title: "Feature Two",
56+
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus id tortor neque.",
57+
layout: "post",
58+
},
59+
{
60+
id: "item-3",
61+
img: "/img/blobs3.png",
62+
title: "Feature Three",
63+
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus id tortor neque.",
64+
layout: "post",
65+
},
66+
],
67+
};
68+
69+
console.log(compile(html, data));

index.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import cheerio from "cheerio";
2+
import _ from "lodash";
3+
4+
function compile(html, data) {
5+
const $ = cheerio.load(html);
6+
7+
$("[x-for]").each(function () {
8+
const key = $(this).attr("x-for").split(" in ")[1].slice(5); // Remove 'data.' from the start
9+
const items = _.get(data, key);
10+
const template = $(this).html();
11+
12+
let result = "";
13+
items.forEach((item) => {
14+
let itemHtml = cheerio.load(template);
15+
for (const prop in item) {
16+
const regex = new RegExp(`item.${prop}`, "g");
17+
itemHtml("[x-html]").each(function () {
18+
if ($(this).attr("x-html") === `item.${prop}`) {
19+
$(this).html(item[prop]);
20+
}
21+
});
22+
itemHtml("[x-text]").each(function () {
23+
if ($(this).attr("x-text") === `item.${prop}`) {
24+
$(this).text(item[prop]);
25+
}
26+
});
27+
itemHtml("[:src]").each(function () {
28+
if ($(this).attr(":src") === `item.${prop}`) {
29+
$(this).attr("src", item[prop]);
30+
}
31+
});
32+
itemHtml("[:id]").each(function () {
33+
if ($(this).attr(":id") === `item.${prop}`) {
34+
$(this).attr("id", item[prop]);
35+
}
36+
});
37+
}
38+
result += itemHtml.html();
39+
});
40+
41+
$(this).replaceWith(result);
42+
});
43+
44+
$("[x-html]").each(function () {
45+
const key = $(this).attr("x-html").slice(5); // Remove 'data.' from the start
46+
const value = _.get(data, key);
47+
if (value) {
48+
$(this).html(value);
49+
}
50+
});
51+
52+
$("[x-text]").each(function () {
53+
const key = $(this).attr("x-text").slice(5); // Remove 'data.' from the start
54+
const value = _.get(data, key);
55+
if (value) {
56+
$(this).text(value);
57+
}
58+
});
59+
60+
$("[:src]").each(function () {
61+
const key = $(this).attr(":src").slice(5); // Remove 'data.' from the start
62+
const value = _.get(data, key);
63+
if (value) {
64+
$(this).attr("src", value);
65+
}
66+
});
67+
68+
$("[:id]").each(function () {
69+
const key = $(this).attr(":id").slice(5); // Remove 'data.' from the start
70+
const value = _.get(data, key);
71+
if (value) {
72+
$(this).attr("id", value);
73+
}
74+
});
75+
76+
/*
77+
$('[x-if]').each(function() {
78+
const condition = $(this).attr('x-if').slice(5); // Remove 'data.' from the start
79+
const value = _.get(data, condition);
80+
if (!value) {
81+
$(this).remove();
82+
}
83+
});
84+
*/
85+
86+
return $.html();
87+
}
88+
89+
export { compile };

package-lock.json

Lines changed: 203 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "alpinejs-ssr",
3+
"version": "1.0.0",
4+
"description": "Simple server-side-rendering for Alpine.js.",
5+
"main": "index.js",
6+
"type": "module",
7+
"scripts": {
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"author": "Dashpilot",
11+
"license": "ISC",
12+
"dependencies": {
13+
"cheerio": "^1.0.0-rc.12",
14+
"lodash": "^4.17.21"
15+
}
16+
}

0 commit comments

Comments
 (0)