@@ -2355,6 +2355,7 @@ dependencies = [ | |||||
"config 0.1.0", | "config 0.1.0", | ||||
"csv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", | "csv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"errors 0.1.0", | "errors 0.1.0", | ||||
"image 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"imageproc 0.1.0", | "imageproc 0.1.0", | ||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"library 0.1.0", | "library 0.1.0", | ||||
@@ -395,6 +395,10 @@ impl Site { | |||||
"resize_image", | "resize_image", | ||||
global_fns::ResizeImage::new(self.imageproc.clone()), | global_fns::ResizeImage::new(self.imageproc.clone()), | ||||
); | ); | ||||
self.tera.register_function( | |||||
"get_image_metadata", | |||||
global_fns::GetImageMeta::new(self.content_path.clone()), | |||||
); | |||||
self.tera.register_function("load_data", global_fns::LoadData::new(self.base_path.clone())); | self.tera.register_function("load_data", global_fns::LoadData::new(self.base_path.clone())); | ||||
self.tera.register_function("trans", global_fns::Trans::new(self.config.clone())); | self.tera.register_function("trans", global_fns::Trans::new(self.config.clone())); | ||||
self.tera.register_function( | self.tera.register_function( | ||||
@@ -10,6 +10,7 @@ lazy_static = "1" | |||||
pulldown-cmark = "0.5" | pulldown-cmark = "0.5" | ||||
toml = "0.4" | toml = "0.4" | ||||
csv = "1" | csv = "1" | ||||
image = "0.21" | |||||
serde_json = "1.0" | serde_json = "1.0" | ||||
reqwest = "0.9" | reqwest = "0.9" | ||||
url = "1.5" | url = "1.5" | ||||
@@ -2,11 +2,13 @@ use std::collections::HashMap; | |||||
use std::path::PathBuf; | use std::path::PathBuf; | ||||
use std::sync::{Arc, Mutex, RwLock}; | use std::sync::{Arc, Mutex, RwLock}; | ||||
use tera::{from_value, to_value, Function as TeraFn, Result, Value}; | |||||
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value}; | |||||
use config::Config; | use config::Config; | ||||
use library::{Library, Taxonomy}; | use library::{Library, Taxonomy}; | ||||
use utils::site::resolve_internal_link; | use utils::site::resolve_internal_link; | ||||
use image; | |||||
use image::GenericImageView; | |||||
use imageproc; | use imageproc; | ||||
@@ -140,6 +142,39 @@ impl TeraFn for ResizeImage { | |||||
} | } | ||||
} | } | ||||
#[derive(Debug)] | |||||
pub struct GetImageMeta { | |||||
content_path: PathBuf | |||||
} | |||||
impl GetImageMeta { | |||||
pub fn new(content_path: PathBuf) -> Self { | |||||
Self { content_path } | |||||
} | |||||
} | |||||
impl TeraFn for GetImageMeta { | |||||
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> { | |||||
let path = required_arg!( | |||||
String, | |||||
args.get("path"), | |||||
"`get_image_meta` requires a `path` argument with a string value" | |||||
); | |||||
let src_path = self.content_path.join(&path); | |||||
if !src_path.exists(){ | |||||
return Err(format!("`get_image_meta`: Cannot find path: {}", path).into()); | |||||
} | |||||
let img = image::open(&src_path) | |||||
.map_err(|e| Error::chain(format!("Failed to process image: {}", path), e))?; | |||||
let mut map = tera::Map::new(); | |||||
map.insert(String::from("height"), Value::Number(tera::Number::from(img.height()))); | |||||
map.insert(String::from("width"), Value::Number(tera::Number::from(img.width()))); | |||||
Ok(Value::Object(map)) | |||||
} | |||||
} | |||||
#[derive(Debug)] | #[derive(Debug)] | ||||
pub struct GetTaxonomyUrl { | pub struct GetTaxonomyUrl { | ||||
taxonomies: HashMap<String, HashMap<String, String>>, | taxonomies: HashMap<String, HashMap<String, String>>, | ||||
@@ -7,7 +7,7 @@ extern crate csv; | |||||
extern crate pulldown_cmark; | extern crate pulldown_cmark; | ||||
extern crate reqwest; | extern crate reqwest; | ||||
extern crate url; | extern crate url; | ||||
extern crate image; | |||||
#[cfg(test)] | #[cfg(test)] | ||||
#[macro_use] | #[macro_use] | ||||
extern crate serde_json; | extern crate serde_json; | ||||
@@ -145,3 +145,9 @@ Here is the result: | |||||
<small> | <small> | ||||
Image attribution: Public domain, except: _06-example.jpg_: Willi Heidelbach, _07-example.jpg_: Daniel Ullrich. | Image attribution: Public domain, except: _06-example.jpg_: Willi Heidelbach, _07-example.jpg_: Daniel Ullrich. | ||||
</small> | </small> | ||||
## Get image size | |||||
Sometimes when building a gallery it is useful to know the dimensions of each asset. You can get this information with | |||||
[get_image_metadata](./documentation/templates/overview.md#get-image-metadata) |
@@ -130,6 +130,14 @@ In the case of non-internal links, you can also add a cachebust of the format `? | |||||
by passing `cachebust=true` to the `get_url` function. | by passing `cachebust=true` to the `get_url` function. | ||||
### `get_image_metadata` | |||||
Gets metadata for an image. Today the only supported keys are `width` and `height`. | |||||
```jinja2 | |||||
{% set meta = get_image_metadata(path="...") %} | |||||
Our image is {{ meta.width }}x{{ meta.height }} | |||||
``` | |||||
### `get_taxonomy_url` | ### `get_taxonomy_url` | ||||
Gets the permalink for the taxonomy item found. | Gets the permalink for the taxonomy item found. | ||||
@@ -3,9 +3,12 @@ title = "Pagination" | |||||
weight = 30 | weight = 30 | ||||
+++ | +++ | ||||
Two things can get paginated: a section or a taxonomy term. | |||||
Two things can get paginated: a section and a taxonomy term. | |||||
Every paginated template gets a `paginator` variable of the `Pager` type: | |||||
A paginated section gets the same `section` variable as a normal | |||||
[section page](./documentation/templates/pages-sections.md#section-variables) minus its pages | |||||
while both a paginated taxonomy page and a paginated section page gets a | |||||
`paginator` variable of the `Pager` type: | |||||
```ts | ```ts | ||||
// How many items per page | // How many items per page | ||||
@@ -32,11 +35,12 @@ current_index: Number; | |||||
## Section | ## Section | ||||
A paginated section gets the same `section` variable as a normal | A paginated section gets the same `section` variable as a normal | ||||
[section page](@/documentation/templates/pages-sections.md#section-variables) minus its pages. | |||||
[section page](./documentation/templates/pages-sections.md#section-variables) | |||||
minus its pages. The pages are instead in `paginator.pages`. | |||||
## Taxonomy term | ## Taxonomy term | ||||
A paginated taxonomy gets two variables: | |||||
A paginated taxonomy gets two variables aside from the `paginator` variable: | |||||
- a `taxonomy` variable of type `TaxonomyConfig` | - a `taxonomy` variable of type `TaxonomyConfig` | ||||
- a `term` variable of type `TaxonomyTerm`. | - a `term` variable of type `TaxonomyTerm`. | ||||