cobalt-org / liquid-rust

Liquid templating for Rust
docs.rs/liquid
MIT License
468 stars 80 forks source link

How do you use `{% include x.liquid %}`? #509

Open ghost opened 1 year ago

ghost commented 1 year ago

liquid-rust version: 0.26.4 rust version: 1.70.0 OS: Mac OSX 13.2.1

I need this functionality for my static-site generator, Mandy. I have this context structure here which is applied through the object macro. How would I handle include statements in templates through this? I couldn't find anything in the docs.

ghost commented 1 year ago

Sitrep: I figured it out. But y'all should really document this!

Here's my Rust experiment for this that yields the wanted results:

use coutils::read_file;
use liquid::ObjectView;
use liquid::ValueView;
use liquid::ParserBuilder;
use std::fmt::Debug;
use liquid::Template;
use liquid::object;
use coutils::clean_split;
use coutils::create_file;
use coutils::write_to_file;
use std::collections::HashMap;
use liquid::partials::EagerCompiler;
use liquid::partials::InMemorySource;

#[derive(ObjectView, ValueView, Clone, Debug)]
pub struct SiteContext {
    title: String,
    content: String,
}

impl SiteContext {
    pub fn new(title: &str, content: &str) -> SiteContext {
        return SiteContext{
            title: title.to_owned(),
            content: content.to_owned(),
        }
    }
}

pub fn render_template(template_path: &String, ctx: &SiteContext) -> Result<(), String> {
    let template_string: String = read_file(template_path);
    type Partials =  EagerCompiler<InMemorySource>;
    let mut new_ctx: HashMap<String, SiteContext> = HashMap::new();
    let src: &String = &String::from("header.liquid");
    let src_contents: &String = &read_file(src);
    let mut partial_source = Partials::empty();
    partial_source.add(src, src_contents);
    new_ctx.insert(String::from("site"), ctx.to_owned());
    let mut template: Template = match ParserBuilder::with_stdlib().partials(partial_source)
        .build().unwrap()
        .parse(&template_string){
            Ok(template) => template,
            Err(e) =>  {
                return Err(e.to_string());
            }
        };
    let mut globals = object!(new_ctx);
    let mut html_string = match template.render(&globals) {
        Ok(html_string) => html_string,
        Err(e) =>  {
            return Err(e.to_string());
        }
    };
    let path_items: Vec<String> = clean_split(template_path, &String::from("/"));
    let last_index: usize = path_items.len() -1 ;
    let fname_components: Vec<String> = clean_split(&path_items[last_index], &String::from("."));
    let base: &String = &fname_components[0];
    let new_name: &String = &format!("{}.html", base);
    create_file(new_name);
    write_to_file(new_name, &html_string);
    return Ok(());
}

fn main(){
    let ctx: SiteContext = SiteContext::new(
        &"TEST",
        &"TEXT TEXT TEXT TEXT TEXT TEXT\nTEXT TEXT TEXT TEXT TEXT TEXT"
    );
    let template_path = &String::from("test.liquid");
    match render_template(template_path, &ctx) {
        Ok(_x) => {},
        Err(e) => {
            println!("{}", e);
        }
    }
}
[package]
name = "liquid-exp"
version = "0.1.0"
edition = "2021"

[dependencies]
liquid = "0.26.4"
coutils = { git = "https://github.com/angeldollface/coutils", version = "1.3.0" }
<!DOCTYPE html>
<html>
 {% include "header.liquid" %}
 <body>
  <h1>{{ site.title }}</h1>
  <p>{{ site.content }}</p>
 </body>
</html>
<head>
 <title>{{ site.title }}</title>
</head>
<!DOCTYPE html>
<html>
 <head>
 <title>TEST</title>
</head>
 <body>
  <h1>TEST</h1>
  <p>TEXT TEXT TEXT TEXT TEXT TEXT
TEXT TEXT TEXT TEXT TEXT TEXT</p>
 </body>
</html>
.
├── Cargo.toml
├── header.liquid
├── src
│   └── main.rs
├── test.html
└── test.liquid
ghost commented 1 year ago

Please add the label documentation needed. Also, I should add that Mandy now has the functionality of using partials. The link to the Liquid template processor is here.

ghost commented 3 months ago

Can I mark this as closed?

epage commented 3 months ago

Why would this be marked as closed? You requested documentation updates which someone is doing in #542

ghost commented 3 months ago

Why would this be marked as closed? You requested documentation updates which someone is doing in #542

@epage Wasn't quite sure. Right you are! <3 Issue was somewhere in the dusty attic of my mind. Got a bit confused. Thank you both for adding that!