Refactor generation of links from slugs

This fixes a bug where the cancel-link on the front page would be to "" rather than "."
This commit is contained in:
Magnus Hoff 2017-10-30 12:42:53 +01:00
parent 4ca748f180
commit 1bdc21039b
6 changed files with 28 additions and 52 deletions

View file

@ -1,5 +1,13 @@
use chrono;
fn slug_link(slug: &str) -> &str {
if slug.is_empty() {
"."
} else {
slug
}
}
#[derive(Debug, Queryable)]
pub struct ArticleRevision {
pub sequence_number: i32,
@ -18,13 +26,7 @@ pub struct ArticleRevision {
}
impl ArticleRevision {
pub fn link(&self) -> &str {
if self.slug.is_empty() {
"."
} else {
&self.slug
}
}
pub fn link(&self) -> &str { slug_link(&self.slug) }
}
#[derive(Debug, Queryable)]
@ -43,9 +45,17 @@ pub struct ArticleRevisionStub {
pub author: Option<String>,
}
impl ArticleRevisionStub {
pub fn link(&self) -> &str { slug_link(&self.slug) }
}
#[derive(Debug, Queryable, Serialize)]
pub struct SearchResult {
pub title: String,
pub snippet: String,
pub slug: String,
}
impl SearchResult {
pub fn link(&self) -> &str { slug_link(&self.slug) }
}

View file

@ -106,7 +106,7 @@ impl Resource for ArticleResource {
data.author.as_ref().map(|x| &**x)
)),
edit: self.edit,
cancel_url: Some(&data.slug),
cancel_url: Some(data.link()),
title: &data.title,
raw: &data.body,
rendered: render_markdown(&data.body),

View file

@ -6,7 +6,7 @@ use serde_json;
use serde_urlencoded;
use mimes::*;
use models;
use models::SearchResult;
use site::Layout;
use state::State;
use web::{Resource, ResponseFuture};
@ -148,33 +148,16 @@ impl Resource for SearchResource {
#[derive(Serialize)]
struct JsonResponse<'a> {
query: &'a str,
hits: &'a [models::SearchResult],
hits: &'a [SearchResult],
prev: Option<String>,
next: Option<String>,
}
struct Hit<'a> {
index: usize,
slug: &'a str,
title: &'a str,
snippet: &'a str,
}
impl<'a> Hit<'a> {
fn link(&self) -> &'a str {
if self.slug == "" {
"."
} else {
self.slug
}
}
}
#[derive(BartDisplay)]
#[template="templates/search.html"]
struct Template<'a> {
query: &'a str,
hits: &'a [Hit<'a>],
hits: &'a [(usize, &'a SearchResult)],
prev: Option<String>,
next: Option<String>,
}
@ -223,12 +206,6 @@ impl Resource for SearchResource {
query: self.query.as_ref().map(|x| &**x).unwrap_or(""),
hits: &data.iter()
.enumerate()
.map(|(i, result)| Hit {
index: i,
slug: &result.slug,
title: &result.title,
snippet: &result.snippet,
})
.collect::<Vec<_>>(),
prev,
next,

View file

@ -4,6 +4,7 @@ use hyper::header::ContentType;
use hyper::server::*;
use mimes::*;
use models::ArticleRevisionStub;
use site::Layout;
use state::State;
use web::{Resource, ResponseFuture};
@ -35,12 +36,7 @@ impl Resource for SitemapResource {
#[derive(BartDisplay)]
#[template="templates/sitemap.html"]
struct Template<'a> {
articles: &'a [ArticleReference],
}
struct ArticleReference {
link: String,
title: String,
articles: &'a [ArticleRevisionStub],
}
let data = self.state.get_latest_article_revision_stubs();
@ -48,20 +44,13 @@ impl Resource for SitemapResource {
Box::new(data.join(head)
.and_then(move |(articles, head)| {
use std::iter::Iterator;
let articles = &articles.into_iter().map(|x| {
ArticleReference {
link: if x.slug.is_empty() { ".".to_owned() } else { x.slug },
title: x.title,
}
}).collect::<Vec<_>>();
Ok(head
.with_body(Layout {
base: None, // Hmm, should perhaps accept `base` as argument
title: "Sitemap",
body: &Template { articles },
body: &Template {
articles: &articles,
},
}.to_string()))
}))
}

View file

@ -13,7 +13,7 @@
<ul class="search-results default-keyboard-focus-control">
{{#hits}}
<li class="search-result"><a data-focusindex="{{.index}}" class="link" href="{{.link()}}"><p class="title">{{.title}}</p><p class="snippet">{{.snippet}}</p></a></li>
<li class="search-result"><a data-focusindex="{{.0}}" class="link" href="{{.1.link()}}"><p class="title">{{.1.title}}</p><p class="snippet">{{.1.snippet}}</p></a></li>
{{/hits}}
</ul>
{{/hits}}

View file

@ -6,7 +6,7 @@
<article>
<ul class="dense"
{{#articles}}
><li><a href="{{.link}}">{{.title}}</a></li
><li><a href="{{.link()}}">{{.title}}</a></li
{{/articles}}
></ul>
</article>