ftml/render/html/element/
image.rs1use super::prelude::*;
22use crate::tree::{AttributeMap, FileSource, FloatAlignment, LinkLocation};
23use crate::url::normalize_link;
24
25pub fn render_image(
26 ctx: &mut HtmlContext,
27 source: &FileSource,
28 link: &Option<LinkLocation>,
29 alignment: Option<FloatAlignment>,
30 attributes: &AttributeMap,
31) {
32 debug!(
33 "Rendering image element (source '{}', link {:?}, alignment {}, float {})",
34 source.name(),
35 link,
36 match alignment {
37 Some(image) => image.align.name(),
38 None => "<default>",
39 },
40 match alignment {
41 Some(image) => image.float,
42 None => false,
43 },
44 );
45
46 let source_url = ctx
47 .handle()
48 .get_file_link(source, ctx.info(), ctx.settings());
49
50 match source_url {
51 Some(url) => render_image_element(ctx, &url, link, alignment, attributes),
53
54 None => render_image_missing(ctx),
56 }
57}
58
59fn render_image_element(
60 ctx: &mut HtmlContext,
61 image_url: &str,
62 link: &Option<LinkLocation>,
63 alignment: Option<FloatAlignment>,
64 attributes: &AttributeMap,
65) {
66 trace!("Found URL, rendering image (value '{image_url}')");
67
68 match ctx.layout() {
69 Layout::Wikidot => {
70 render_image_element_wikidot(ctx, image_url, link, alignment, attributes);
71 }
72 Layout::Wikijump => {
73 render_image_element_wikijump(ctx, image_url, link, alignment, attributes);
74 }
75 }
76}
77
78fn render_image_element_wikidot(
88 ctx: &mut HtmlContext,
89 image_url: &str,
90 link: &Option<LinkLocation>,
91 alignment: Option<FloatAlignment>,
92 attributes: &AttributeMap,
93) {
94 let build_image = |ctx: &mut HtmlContext| {
95 ctx.html().img().attr(attr!(
96 "src" => image_url,
97 "class" => "image",
98 "crossorigin";;
99 attributes,
100 ));
101 };
102
103 let build_link = |ctx: &mut HtmlContext| match link {
104 None => build_image(ctx),
105 Some(link) => {
106 let url = normalize_link(link, ctx.handle());
107 ctx.html()
108 .a()
109 .attr(attr!("href" => &url))
110 .inner(build_image);
111 }
112 };
113
114 match alignment {
115 None => build_link(ctx),
116 Some(align) => {
117 ctx.html()
118 .div()
119 .attr(attr!("class" => "image-container " align.wd_html_class()))
120 .inner(build_link);
121 }
122 }
123}
124
125fn render_image_element_wikijump(
126 ctx: &mut HtmlContext,
127 image_url: &str,
128 link: &Option<LinkLocation>,
129 alignment: Option<FloatAlignment>,
130 attributes: &AttributeMap,
131) {
132 let (space, align_class) = match alignment {
133 Some(align) => (" ", align.wj_html_class()),
134 None => ("", ""),
135 };
136
137 ctx.html()
138 .div()
139 .attr(attr!(
140 "class" => "wj-image-container" space align_class,
141 ))
142 .inner(|ctx| {
143 let build_image = |ctx: &mut HtmlContext| {
144 ctx.html().img().attr(attr!(
145 "class" => "wj-image",
146 "src" => image_url,
147 "crossorigin";;
148 attributes
149 ));
150 };
151
152 match link {
153 Some(link) => {
154 let url = normalize_link(link, ctx.handle());
155 ctx.html()
156 .a()
157 .attr(attr!("href" => &url))
158 .inner(build_image);
159 }
160 None => build_image(ctx),
161 };
162 });
163}
164
165fn render_image_missing(ctx: &mut HtmlContext) {
166 trace!("Image URL unresolved, missing or error");
167
168 let message = ctx
169 .handle()
170 .get_message(ctx.language(), "image-context-bad");
171
172 ctx.html()
173 .div()
174 .attr(attr!("class" => "wj-error-block"))
175 .contents(message);
176}