mirror of
https://github.com/zyllian/webdog.git
synced 2025-01-17 19:22:21 -08:00
add support for custom partials
Some checks are pending
Build Site / build (push) Waiting to run
Build Site / deploy (push) Blocked by required conditions
Some checks are pending
Build Site / build (push) Waiting to run
Build Site / deploy (push) Blocked by required conditions
This commit is contained in:
parent
fd40a5d31a
commit
1d502881f6
7 changed files with 690 additions and 350 deletions
720
Cargo.lock
generated
720
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -12,8 +12,10 @@ fs_extra = "1.2"
|
|||
futures = {version = "0.3", optional = true}
|
||||
grass = {version = "0.13", default-features = false}
|
||||
hotwatch = {version = "0.5", optional = true}
|
||||
html5ever = "0.29"
|
||||
include_dir = "0.7"
|
||||
itertools = "0.13"
|
||||
itertools = "0.14"
|
||||
kuchikiki = "0.8.6-speedreader"
|
||||
lol_html = "2"
|
||||
minifier = {version = "0.3", features = ["html"]}
|
||||
percent-encoding = {version = "2", optional = true}
|
||||
|
|
|
@ -20,6 +20,10 @@ learn about standard webdog pages here
|
|||
|
||||
learn how to use webdog templates
|
||||
|
||||
## <a href="webdog-html">webdog html</a>
|
||||
|
||||
learn about webdog html extensions
|
||||
|
||||
## <a href="styling">styling</a>
|
||||
|
||||
learn about webdog styling
|
||||
|
|
34
site/pages/docs/webdog-html.md
Normal file
34
site/pages/docs/webdog-html.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
title: webdog html
|
||||
template: docs.tera
|
||||
---
|
||||
|
||||
# webdog html
|
||||
|
||||
webdog adds some extensions to html to make building your site easier.
|
||||
|
||||
## `wd-partial`
|
||||
|
||||
any template can be used as a partial in another template or page.
|
||||
|
||||
in a template like this:
|
||||
|
||||
```html
|
||||
<p>this is a partial.</p>
|
||||
<p>the hi argument is {{ userdata.hi }}</p>
|
||||
<p>the hello argument is {{ userdata.hello }}</p>
|
||||
<div>
|
||||
<p>and here's the inner content:
|
||||
{{ page | safe }}
|
||||
</div>
|
||||
```
|
||||
|
||||
simply include the `wd-partial` html tag like so:
|
||||
|
||||
```html
|
||||
<wd-partial t="template-to-use.tera" hello="hi" hi="hello">
|
||||
hiiiiiiiiiii~
|
||||
</wd-partial>
|
||||
```
|
||||
|
||||
a `wd-partial` tag consists of the `t` attribute to determine the template and any number of additional arguments, which are passed on to the partial template.
|
|
@ -12,6 +12,7 @@
|
|||
{{ self::docLink(text="configuration", href="config") }}
|
||||
{{ self::docLink(text="pages", href="pages") }}
|
||||
{{ self::docLink(text="templates", href="templates") }}
|
||||
{{ self::docLink(text="webdog html", href="webdog-html") }}
|
||||
{{ self::docLink(text="styling", href="styling") }}
|
||||
{{ self::docLink(text="resources", href="resources") }}
|
||||
{{ self::docLink(text="webdog assumptions", href="wd-assumptions") }}
|
||||
|
|
|
@ -163,7 +163,64 @@ impl SiteBuilder {
|
|||
head: &Option<String>,
|
||||
scripts: &[String],
|
||||
styles: &[String],
|
||||
is_partial: bool,
|
||||
) -> eyre::Result<String> {
|
||||
use kuchikiki::traits::*;
|
||||
|
||||
let html = {
|
||||
let document = kuchikiki::parse_html().one(html.clone()).document_node;
|
||||
let mut needs_reserialized = false;
|
||||
|
||||
while let Ok(el) = document.select_first("wd-partial") {
|
||||
needs_reserialized = true;
|
||||
let attr_map = el.attributes.borrow();
|
||||
let template = attr_map
|
||||
.get("t")
|
||||
.ok_or_eyre("missing t attribute on wd-partial")?;
|
||||
let attr_map: HashMap<_, _> = attr_map
|
||||
.map
|
||||
.iter()
|
||||
.map(|(k, v)| (k.local.to_string(), &v.value))
|
||||
.collect();
|
||||
let mut html_buf = Vec::new();
|
||||
for child in el.as_node().children() {
|
||||
child.serialize(&mut html_buf)?;
|
||||
}
|
||||
let html = String::from_utf8(html_buf)?;
|
||||
let new_html = self.build_page_raw(
|
||||
PageMetadata {
|
||||
template: Some(template.to_string()),
|
||||
userdata: serde_yml::to_value(attr_map)?,
|
||||
is_partial: true,
|
||||
..Default::default()
|
||||
},
|
||||
&html,
|
||||
(),
|
||||
)?;
|
||||
let new_doc = kuchikiki::parse_html()
|
||||
.one(new_html)
|
||||
.document_node
|
||||
.select_first("body")
|
||||
.map(|b| b.as_node().children())
|
||||
.expect("should never fail");
|
||||
for child in new_doc {
|
||||
el.as_node().insert_before(child);
|
||||
}
|
||||
el.as_node().detach();
|
||||
}
|
||||
|
||||
if needs_reserialized {
|
||||
let mut html = Vec::new();
|
||||
document.serialize(&mut html)?;
|
||||
String::from_utf8(html)?
|
||||
} else {
|
||||
html
|
||||
}
|
||||
};
|
||||
|
||||
let output = if is_partial {
|
||||
html
|
||||
} else {
|
||||
let mut output = Vec::new();
|
||||
let mut rewriter = HtmlRewriter::new(
|
||||
Settings {
|
||||
|
@ -212,7 +269,8 @@ impl SiteBuilder {
|
|||
"me" => {
|
||||
el.set_attribute(
|
||||
"rel",
|
||||
&(el.get_attribute("rel").unwrap_or_default() + " me"),
|
||||
&(el.get_attribute("rel").unwrap_or_default()
|
||||
+ " me"),
|
||||
)?;
|
||||
}
|
||||
_ => {
|
||||
|
@ -289,7 +347,10 @@ impl SiteBuilder {
|
|||
rewriter.write(html.as_bytes())?;
|
||||
rewriter.end()?;
|
||||
|
||||
Ok(String::from_utf8(output)?)
|
||||
String::from_utf8(output)?
|
||||
};
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
/// Helper to build a page without writing it to disk.
|
||||
|
@ -334,6 +395,7 @@ impl SiteBuilder {
|
|||
&head,
|
||||
&page_metadata.scripts,
|
||||
&page_metadata.styles,
|
||||
page_metadata.is_partial,
|
||||
)?;
|
||||
|
||||
if let Some(data) = extra {
|
||||
|
|
|
@ -130,6 +130,9 @@ pub struct PageMetadata {
|
|||
/// Custom values passed to the base template.
|
||||
#[serde(default)]
|
||||
pub userdata: serde_yml::Value,
|
||||
/// Whether this page being rendered is a partial. Set by the builder, not your page metadata.
|
||||
#[serde(skip)]
|
||||
pub is_partial: bool,
|
||||
}
|
||||
|
||||
/// Struct containing information about the site.
|
||||
|
|
Loading…
Add table
Reference in a new issue