Add a get_static_url global fn

Fix #108
This commit is contained in:
Vincent Prouillet 2017-08-07 20:38:13 +09:00
parent 45d366dee3
commit fc63765ee1
9 changed files with 86 additions and 3 deletions

View file

@ -6,6 +6,7 @@
root page
- Make `title` in config optional
- Improved `gutenberg init` UX and users first experience
- Add a `get_static_url` global function that can do cachebusting
## 0.1.1 (2017-07-16)

2
Cargo.lock generated
View file

@ -233,6 +233,7 @@ dependencies = [
name = "config"
version = "0.1.0"
dependencies = [
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"errors 0.1.0",
"rendering 0.1.0",
"serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1144,6 +1145,7 @@ name = "templates"
version = "0.1.0"
dependencies = [
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"config 0.1.0",
"content 0.1.0",
"errors 0.1.0",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -64,7 +64,7 @@ the absolute URL of the current page and `current_path` that represents the path
If you want to know all the data present in a template content, simply put `{{ __tera_context }}`
in the templates and it will print it.
Gutenberg also ships with 3 Tera global functions:
Gutenberg also ships with a few Tera global functions:
#### `get_page`
Takes a path to a `.md` file and returns the associated page
@ -88,6 +88,18 @@ link in markdown.
{% set url = get_url(link="./blog/_index.md") %}
```
#### `get_static_url`
Gets the permalink for a given path, with cachebusting support.
```jinja2
{% get_static_url(path="path.css") %}
```
The path should start at the static folder root and should not being with a `/`. By default,
this will add a cachebust of the format `?t=1290192` at the end of a URL. You can disable it
by passing `cachebust=false` to the function.
### Static files
Everything in the `static` folder will be copied into the output directory as-is.

View file

@ -7,6 +7,7 @@ authors = ["Vincent Prouillet <vincent@wearewizards.io>"]
toml = "0.4"
serde = "1.0"
serde_derive = "1.0"
chrono = "0.4"
errors = { path = "../errors" }
rendering = { path = "../rendering" }

View file

@ -4,6 +4,7 @@ extern crate toml;
#[macro_use]
extern crate errors;
extern crate rendering;
extern crate chrono;
use std::collections::HashMap;
use std::fs::File;
@ -11,12 +12,13 @@ use std::io::prelude::*;
use std::path::Path;
use toml::{Value as Toml};
use chrono::Utc;
use errors::{Result, ResultExt};
use rendering::highlighting::THEME_SET;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Config {
/// Base URL of the site, the only required config argument
pub base_url: String,
@ -48,6 +50,9 @@ pub struct Config {
/// All user params set in [extra] in the config
pub extra: Option<HashMap<String, Toml>>,
/// Set automatically when instantiating the config. Used for cachebusting
pub build_timestamp: Option<i64>,
}
macro_rules! set_default {
@ -85,6 +90,7 @@ impl Config {
None => config.highlight_theme = Some("base16-ocean-dark".to_string())
};
config.build_timestamp = Some(Utc::now().timestamp());
Ok(config)
}
@ -136,6 +142,7 @@ impl Default for Config {
insert_anchor_links: Some(false),
compile_sass: Some(false),
extra: None,
build_timestamp: Some(1),
}
}
}

View file

@ -218,6 +218,7 @@ impl Site {
self.tera.register_global_function("get_page", global_fns::make_get_page(&self.pages));
self.tera.register_global_function("get_section", global_fns::make_get_section(&self.sections));
self.tera.register_global_function("get_static_url", global_fns::make_get_static_url(self.config.clone()));
self.register_get_url_fn();
Ok(())

View file

@ -12,3 +12,4 @@ pulldown-cmark = "0"
errors = { path = "../errors" }
utils = { path = "../utils" }
content = { path = "../content" }
config = { path = "../config" }

View file

@ -4,6 +4,7 @@ use std::path::{PathBuf};
use tera::{GlobalFn, Value, from_value, to_value, Result};
use content::{Page, Section};
use config::Config;
use utils::site::resolve_internal_link;
@ -51,7 +52,7 @@ pub fn make_get_section(all_sections: &HashMap<PathBuf, Section>) -> GlobalFn {
})
}
pub fn make_get_url(permalinks: HashMap<String, String>,) -> GlobalFn {
pub fn make_get_url(permalinks: HashMap<String, String>) -> GlobalFn {
Box::new(move |args| -> Result<Value> {
match args.get("link") {
Some(val) => match from_value::<String>(val.clone()) {
@ -65,3 +66,59 @@ pub fn make_get_url(permalinks: HashMap<String, String>,) -> GlobalFn {
}
})
}
pub fn make_get_static_url(config: Config) -> GlobalFn {
Box::new(move |args| -> Result<Value> {
let cachebust = args
.get("cachebust")
.map_or(true, |c| {
from_value::<bool>(c.clone()).unwrap_or(true)
});
match args.get("path") {
Some(val) => match from_value::<String>(val.clone()) {
Ok(v) => {
let mut permalink = config.make_permalink(&v);
if cachebust {
permalink = format!("{}?t={}", permalink, config.build_timestamp.unwrap());
}
Ok(to_value(permalink).unwrap())
},
Err(_) => Err(format!("`get_static_url` received path={:?} but it requires a string", val).into()),
},
None => Err("`get_static_url` requires a `path` argument.".into()),
}
})
}
#[cfg(test)]
mod tests {
use super::make_get_static_url;
use std::collections::HashMap;
use tera::to_value;
use config::Config;
#[test]
fn add_cachebust_to_static_url_by_default() {
let config = Config::default();
let static_fn = make_get_static_url(config);
let mut args = HashMap::new();
args.insert("path".to_string(), to_value("app.css").unwrap());
assert_eq!(static_fn(args).unwrap(), "http://a-website.com/app.css/?t=1");
}
#[test]
fn can_disable_cachebust_for_static_url() {
let config = Config::default();
let static_fn = make_get_static_url(config);
let mut args = HashMap::new();
args.insert("path".to_string(), to_value("app.css").unwrap());
args.insert("cachebust".to_string(), to_value(false).unwrap());
assert_eq!(static_fn(args).unwrap(), "http://a-website.com/app.css/");
}
}

View file

@ -8,6 +8,7 @@ extern crate pulldown_cmark;
extern crate errors;
extern crate utils;
extern crate content;
extern crate config;
pub mod filters;
pub mod global_fns;