Skip to content

Commit 0842673

Browse files
Dan blog search (#1359)
1 parent 55890e1 commit 0842673

File tree

28 files changed

+569
-202
lines changed

28 files changed

+569
-202
lines changed

pgml-dashboard/src/api/cms.rs

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ use crate::{
2121
use serde::{Deserialize, Serialize};
2222
use std::fmt;
2323

24+
use crate::components::cards::blog::article_preview;
25+
use sailfish::TemplateOnce;
26+
2427
lazy_static! {
2528
pub static ref BLOG: Collection = Collection::new(
2629
"Blog",
@@ -120,6 +123,25 @@ impl Document {
120123
Document { ..Default::default() }
121124
}
122125

126+
// make a document from a uri of form <blog || docs || careers>/< path and file name >
127+
pub async fn from_url(url: &str) -> anyhow::Result<Document, std::io::Error> {
128+
let doc_type = match url.split('/').collect::<Vec<&str>>().get(1) {
129+
Some(&"blog") => Some(DocType::Blog),
130+
Some(&"docs") => Some(DocType::Docs),
131+
Some(&"careers") => Some(DocType::Careers),
132+
_ => None,
133+
};
134+
135+
let path = match doc_type {
136+
Some(DocType::Blog) => BLOG.url_to_path(url),
137+
Some(DocType::Docs) => DOCS.url_to_path(url),
138+
Some(DocType::Careers) => CAREERS.url_to_path(url),
139+
_ => PathBuf::new(),
140+
};
141+
142+
Document::from_path(&path).await
143+
}
144+
123145
pub async fn from_path(path: &PathBuf) -> anyhow::Result<Document, std::io::Error> {
124146
let doc_type = match path.strip_prefix(config::cms_dir()) {
125147
Ok(path) => match path.into_iter().next() {
@@ -673,6 +695,49 @@ async fn search(query: &str, site_search: &State<crate::utils::markdown::SiteSea
673695
)
674696
}
675697

698+
#[get("/search_blog?<query>&<tag>", rank = 20)]
699+
async fn search_blog(query: &str, tag: &str, site_search: &State<crate::utils::markdown::SiteSearch>) -> ResponseOk {
700+
let tag = if tag.len() > 0 {
701+
Some(Vec::from([tag.to_string()]))
702+
} else {
703+
None
704+
};
705+
706+
// If user is not making a search return all blogs in default design.
707+
let results = if query.len() > 0 || tag.clone().is_some() {
708+
let results = site_search.search(query, Some(DocType::Blog), tag.clone()).await;
709+
710+
let results = match results {
711+
Ok(results) => results
712+
.into_iter()
713+
.map(|document| article_preview::DocMeta::from_document(document))
714+
.collect::<Vec<article_preview::DocMeta>>(),
715+
Err(_) => Vec::new(),
716+
};
717+
718+
results
719+
} else {
720+
let mut results = Vec::new();
721+
722+
for url in BLOG.get_all_urls() {
723+
let doc = Document::from_url(&url).await.unwrap();
724+
725+
results.push(article_preview::DocMeta::from_document(doc));
726+
}
727+
728+
results
729+
};
730+
731+
let is_search = query.len() > 0 || tag.is_some();
732+
733+
ResponseOk(
734+
crate::components::pages::blog::blog_search::Response::new()
735+
.pattern(results, is_search)
736+
.render_once()
737+
.unwrap(),
738+
)
739+
}
740+
676741
#[get("/blog/.gitbook/assets/<path>", rank = 10)]
677742
pub async fn get_blog_asset(path: &str) -> Option<NamedFile> {
678743
BLOG.get_asset(path).await
@@ -751,13 +816,25 @@ async fn blog_landing_page(cluster: &Cluster) -> Result<ResponseOk, crate::respo
751816
.theme(Theme::Docs)
752817
.footer(cluster.context.marketing_footer.to_string());
753818

754-
Ok(ResponseOk(
755-
layout.render(
756-
crate::components::pages::blog::LandingPage::new(cluster)
757-
.index(&BLOG)
758-
.await,
759-
),
760-
))
819+
let mut index = Vec::new();
820+
821+
let urls = BLOG.get_all_urls();
822+
823+
for url in urls {
824+
let doc = Document::from_url(&url).await.unwrap();
825+
let meta = article_preview::DocMeta::from_document(doc);
826+
index.push(meta)
827+
}
828+
829+
let featured_cards = index
830+
.clone()
831+
.into_iter()
832+
.filter(|x| x.featured)
833+
.collect::<Vec<article_preview::DocMeta>>();
834+
835+
Ok(ResponseOk(layout.render(
836+
crate::components::pages::blog::LandingPage::new(cluster).featured_cards(featured_cards),
837+
)))
761838
}
762839

763840
#[get("/docs")]
@@ -806,7 +883,8 @@ pub fn routes() -> Vec<Route> {
806883
get_docs,
807884
get_docs_asset,
808885
get_user_guides,
809-
search
886+
search,
887+
search_blog
810888
]
811889
}
812890

@@ -880,8 +958,9 @@ This is the end of the markdown
880958

881959
async fn rocket() -> Rocket<Build> {
882960
dotenv::dotenv().ok();
961+
883962
rocket::build()
884-
// .manage(crate::utils::markdown::SearchIndex::open().unwrap())
963+
// .manage(crate::utils::markdown::SiteSearch::new().await.expect("Error initializing site search"))
885964
.mount("/", crate::api::cms::routes())
886965
}
887966

pgml-dashboard/src/components/cards/blog/article_preview/article_preview_controller.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

pgml-dashboard/src/components/cards/blog/article_preview/mod.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ pub struct DocMeta {
1717
pub path: String,
1818
}
1919

20+
impl DocMeta {
21+
pub fn from_document(doc: Document) -> DocMeta {
22+
DocMeta {
23+
description: doc.description,
24+
author: doc.author,
25+
author_image: doc.author_image,
26+
featured: doc.featured,
27+
date: doc.date,
28+
tags: doc.tags,
29+
image: doc.image,
30+
title: doc.title,
31+
path: doc.url,
32+
}
33+
}
34+
}
35+
2036
#[derive(TemplateOnce)]
2137
#[template(path = "cards/blog/article_preview/template.html")]
2238
pub struct ArticlePreview {
@@ -59,18 +75,7 @@ impl ArticlePreview {
5975

6076
pub async fn from_path(path: &str) -> ArticlePreview {
6177
let doc = Document::from_path(&PathBuf::from(path)).await.unwrap();
62-
63-
let meta = DocMeta {
64-
description: doc.description,
65-
author: doc.author,
66-
author_image: doc.author_image,
67-
featured: false,
68-
date: doc.date,
69-
tags: doc.tags,
70-
image: doc.image,
71-
title: doc.title,
72-
path: doc.url,
73-
};
78+
let meta = DocMeta::from_document(doc);
7479
ArticlePreview::new(&meta)
7580
}
7681
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
div {
2+
@mixin loading-dot($delay, $initial) {
3+
width: 30px;
4+
height: 30px;
5+
opacity: $initial;
6+
border-radius: 30px;
7+
background-color: #{$gray-100};
8+
animation: opacity 3s infinite linear;
9+
animation-delay: $delay;
10+
}
11+
12+
.loading-dot-1 {
13+
@include loading-dot(0s, 0.1);
14+
}
15+
16+
.loading-dot-2 {
17+
@include loading-dot(0.5s, 0.2);
18+
}
19+
20+
.loading-dot-3 {
21+
@include loading-dot(1s, 0.3);
22+
}
23+
24+
@keyframes opacity {
25+
0% {
26+
opacity: 0.1;
27+
}
28+
29+
75% {
30+
opacity: 1;
31+
}
32+
33+
100% {
34+
opacity: 0.1;
35+
}
36+
}
37+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use pgml_components::component;
2+
use sailfish::TemplateOnce;
3+
4+
#[derive(TemplateOnce, Default)]
5+
#[template(path = "loading/dots/template.html")]
6+
pub struct Dots {}
7+
8+
impl Dots {
9+
pub fn new() -> Dots {
10+
Dots {}
11+
}
12+
}
13+
14+
component!(Dots);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="d-flex flex-row gap-3">
2+
<div class="loading-dot-1">
3+
</div>
4+
<div class="loading-dot-2">
5+
</div>
6+
<div class="loading-dot-3">
7+
</div>
8+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div[data-controller="loading-message"] {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use sailfish::TemplateOnce;
2+
use pgml_components::component;
3+
4+
#[derive(TemplateOnce, Default)]
5+
#[template(path = "loading/message/template.html")]
6+
pub struct Message {
7+
message: String,
8+
}
9+
10+
impl Message {
11+
pub fn new() -> Message {
12+
Message {
13+
message: String::from("Loading..."),
14+
}
15+
}
16+
17+
pub fn message(mut self, message: &str) -> Message {
18+
self.message = String::from(message);
19+
self
20+
}
21+
}
22+
23+
component!(Message);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<% use crate::components::loading::Dots; %>
2+
<div class="d-flex flex-column justify-content-center align-items-center w-100 gap-3">
3+
<%+ Dots::new() %>
4+
<h6 class="fw-semibold"><%- message %></h6>
5+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This file is automatically generated.
2+
// You shouldn't modify it manually.
3+
4+
// src/components/loading/dots
5+
pub mod dots;
6+
pub use dots::Dots;
7+
8+
// src/components/loading/message
9+
pub mod message;
10+
pub use message::Message;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy