From 15f12c618c1983fe5fe5c8b83ac6cc02d19400f8 Mon Sep 17 00:00:00 2001 From: jooseppi12 Date: Mon, 18 Jan 2021 13:45:38 +0100 Subject: [PATCH 1/7] #11 --- src/Hosted/Hosted.fsproj | 1 + src/Hosted/Main.fs | 13 +- src/Hosted/assets/custom.css | 43 ++++++ src/Hosted/userbloglist.html | 288 +++++++++++++++++++++++++++++++++++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 src/Hosted/userbloglist.html diff --git a/src/Hosted/Hosted.fsproj b/src/Hosted/Hosted.fsproj index beac2ee7..f9fae6cb 100644 --- a/src/Hosted/Hosted.fsproj +++ b/src/Hosted/Hosted.fsproj @@ -12,6 +12,7 @@ + diff --git a/src/Hosted/Main.fs b/src/Hosted/Main.fs index 76ecb961..f15fb967 100644 --- a/src/Hosted/Main.fs +++ b/src/Hosted/Main.fs @@ -356,6 +356,7 @@ module Site = type RedirectTemplate = Templating.Template<"../Hosted/redirect.html", serverLoad=Templating.ServerLoad.WhenChanged> type TrainingsTemplate = Templating.Template<"../Hosted/trainings.html", serverLoad=Templating.ServerLoad.WhenChanged> type BlogListTemplate = Templating.Template<"../Hosted/bloglist.html", serverLoad=Templating.ServerLoad.WhenChanged> + type UserBlogListTemplate = Templating.Template<"../Hosted/userbloglist.html", serverLoad=Templating.ServerLoad.WhenChanged> type BlogPostTemplate = Templating.Template<"../Hosted/blogpost.html", serverLoad=Templating.ServerLoad.WhenChanged> type ContactTemplate = Templating.Template<"../Hosted/contact.html", serverLoad=Templating.ServerLoad.WhenChanged> type LegalTemplate = Templating.Template<"../Hosted/legal.html", serverLoad=Templating.ServerLoad.WhenChanged> @@ -1006,6 +1007,16 @@ module Site = .Cookie(Cookies.Banner false) .Doc() |> Content.Page + let USERBLOG_LISTING_NO_PAGING (banner: Doc) f = + UserBlogListTemplate() + .Menubar(menubar config.Value) + .Banner(banner) + .ArticleList(Map.filter f articles.Value |> ARTICLES) + .Pagination(Doc.Empty) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() + |> Content.Page let REDIRECT_TO (url: string) = RedirectTemplate() .Url(url) @@ -1050,7 +1061,7 @@ module Site = ARTICLE ("", p) // All articles by a given user | UserArticle (user, "") -> - BLOG_LISTING_NO_PAGING + USERBLOG_LISTING_NO_PAGING <| BlogListTemplate.BlogCategoryBanner() .Category(user) .Doc() diff --git a/src/Hosted/assets/custom.css b/src/Hosted/assets/custom.css index 959bc794..15e1634e 100644 --- a/src/Hosted/assets/custom.css +++ b/src/Hosted/assets/custom.css @@ -370,3 +370,46 @@ pre:not(.hljs) { border-color: #464646; color: #FFF; } + +.form-ajax .success-box, .form-ajax .error-box { + display: none; + margin-top: 20px; +} + +.user-information { + display: flex; +} + +.user-name { + font-size: 200%; + flex: 1; +} + +.user-bio { + margin-left: 20px; + margin-bottom: 20px; +} + +.user-top { + display: flex; + margin-bottom: 20px; +} + +.user-top i { + color: rgb(102, 102, 102); +} + +.user-top a { + margin-left: 10px; +} + +.user-profile-picture { + min-width: 200px; + margin-bottom: 20px; +} + +@media screen and (max-width: 767px) { + .user-information { + display: block; + } +} \ No newline at end of file diff --git a/src/Hosted/userbloglist.html b/src/Hosted/userbloglist.html new file mode 100644 index 00000000..423aea67 --- /dev/null +++ b/src/Hosted/userbloglist.html @@ -0,0 +1,288 @@ + + + + + + + Blogs + + + + + + + + + + + + + + +
+ +
+ +
+
+

${Title}

+

${Subtitle}

+
+
+
+
+

${Category}

+

Filtered articles

+
+
+
+
+
+
+
+
+ +
+
+

John Doe

+ + +
+
+ Maecenas eget nunc dui. Fusce sit amet diam vel arcu auctor accumsan id sit amet libero. Nunc tempus purus et cursus ultrices. Quisque sollicitudin interdum arcu, ut posuere enim posuere id. Vivamus congue ipsum at ante ultrices, nec sodales turpis fringilla. Suspendisse vitae volutpat lacus. Donec luctus, nisl id sollicitudin condimentum, lacus mauris condimentum massa, posuere elementum magna magna vitae nibh. Ut non ligula purus. Integer sed metus quis nulla consectetur facilisis. Aliquam mattis, massa id rhoncus viverra, est nulla molestie arcu, non aliquam nunc nisi nec justo. Proin id pellentesque sapien, vel aliquet lorem. Nam tincidunt nisi at ligula fermentum, et ultrices ante suscipit. Pellentesque scelerisque non metus vitae consectetur. Phasellus mollis pharetra magna, nec luctus augue. +
+
+
+
+
+
+
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+
+
+
+

+ ${Title} +

+
+
+ #${Title}  +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+

Company and team

+ +
+
+

Help and support

+ +
+
+

Learn more

+ +
+
+

Follow us

+ +

Newsletter

+ +
+
+
+ +
+
+ + + + + + + + + + + + + +
+ + \ No newline at end of file From bf444506e67b77c1542f3eb6ba151ae1f8b215e5 Mon Sep 17 00:00:00 2001 From: jooseppi12 Date: Mon, 18 Jan 2021 17:32:36 +0100 Subject: [PATCH 2/7] Updates to blog user page template --- src/Hosted/Main.fs | 6 +-- src/Hosted/assets/custom.css | 21 +++++---- .../media/icons/fontawesome/icons.css | 4 ++ src/Hosted/userbloglist.html | 46 ++++++++----------- 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/Hosted/Main.fs b/src/Hosted/Main.fs index f15fb967..e5d71476 100644 --- a/src/Hosted/Main.fs +++ b/src/Hosted/Main.fs @@ -1007,10 +1007,9 @@ module Site = .Cookie(Cookies.Banner false) .Doc() |> Content.Page - let USERBLOG_LISTING_NO_PAGING (banner: Doc) f = + let USERBLOG_LISTING_NO_PAGING f = UserBlogListTemplate() .Menubar(menubar config.Value) - .Banner(banner) .ArticleList(Map.filter f articles.Value |> ARTICLES) .Pagination(Doc.Empty) .Footer(MainTemplate.Footer().Doc()) @@ -1062,9 +1061,6 @@ module Site = // All articles by a given user | UserArticle (user, "") -> USERBLOG_LISTING_NO_PAGING - <| BlogListTemplate.BlogCategoryBanner() - .Category(user) - .Doc() <| fun (u, _) _ -> user = u | UserArticle (user, p) -> ARTICLE (user, p) diff --git a/src/Hosted/assets/custom.css b/src/Hosted/assets/custom.css index 15e1634e..868a3c46 100644 --- a/src/Hosted/assets/custom.css +++ b/src/Hosted/assets/custom.css @@ -375,14 +375,15 @@ pre:not(.hljs) { display: none; margin-top: 20px; } - .user-information { - display: flex; + text-align: center; + margin-top: 60px; } .user-name { font-size: 200%; flex: 1; + margin-bottom: 10px; } .user-bio { @@ -391,25 +392,27 @@ pre:not(.hljs) { } .user-top { - display: flex; margin-bottom: 20px; } +.user-social { +} + .user-top i { color: rgb(102, 102, 102); } -.user-top a { +.user-top a:not(:first-child) { margin-left: 10px; } .user-profile-picture { - min-width: 200px; + max-width: 200px; margin-bottom: 20px; + margin-left: auto; + margin-right: auto; } -@media screen and (max-width: 767px) { - .user-information { - display: block; - } +.user-profile-picture img { + border-radius: 50%; } \ No newline at end of file diff --git a/src/Hosted/themekit/media/icons/fontawesome/icons.css b/src/Hosted/themekit/media/icons/fontawesome/icons.css index bdeb806d..fbd564e7 100644 --- a/src/Hosted/themekit/media/icons/fontawesome/icons.css +++ b/src/Hosted/themekit/media/icons/fontawesome/icons.css @@ -74,4 +74,8 @@ .fa-spinner:before { content: "\f110"; +} + +.fa-rss:before { + content: "\f09e"; } \ No newline at end of file diff --git a/src/Hosted/userbloglist.html b/src/Hosted/userbloglist.html index 423aea67..661a68fb 100644 --- a/src/Hosted/userbloglist.html +++ b/src/Hosted/userbloglist.html @@ -20,43 +20,33 @@
-
+
+ + + +
+
John Doe
-
-
-

John Doe

-
- - - -
-
-
- Maecenas eget nunc dui. Fusce sit amet diam vel arcu auctor accumsan id sit amet libero. Nunc tempus purus et cursus ultrices. Quisque sollicitudin interdum arcu, ut posuere enim posuere id. Vivamus congue ipsum at ante ultrices, nec sodales turpis fringilla. Suspendisse vitae volutpat lacus. Donec luctus, nisl id sollicitudin condimentum, lacus mauris condimentum massa, posuere elementum magna magna vitae nibh. Ut non ligula purus. Integer sed metus quis nulla consectetur facilisis. Aliquam mattis, massa id rhoncus viverra, est nulla molestie arcu, non aliquam nunc nisi nec justo. Proin id pellentesque sapien, vel aliquet lorem. Nam tincidunt nisi at ligula fermentum, et ultrices ante suscipit. Pellentesque scelerisque non metus vitae consectetur. Phasellus mollis pharetra magna, nec luctus augue. -
+
+ Maecenas eget nunc dui. Fusce sit amet diam vel arcu auctor accumsan id sit amet libero. Nunc tempus purus et cursus ultrices. Quisque sollicitudin interdum arcu, ut posuere enim posuere id. Vivamus congue ipsum at ante ultrices, nec sodales turpis fringilla. Suspendisse vitae volutpat lacus. Donec luctus, nisl id sollicitudin condimentum, lacus mauris condimentum massa, posuere elementum magna magna vitae nibh. Ut non ligula purus. Integer sed metus quis nulla consectetur facilisis. Aliquam mattis, massa id rhoncus viverra, est nulla molestie arcu, non aliquam nunc nisi nec justo. Proin id pellentesque sapien, vel aliquet lorem. Nam tincidunt nisi at ligula fermentum, et ultrices ante suscipit. Pellentesque scelerisque non metus vitae consectetur. Phasellus mollis pharetra magna, nec luctus augue.
From 2e7c69f09116ccff00e98f105ed54b2630edaeef Mon Sep 17 00:00:00 2001 From: Adam Granicz Date: Fri, 22 Jan 2021 20:43:25 +0100 Subject: [PATCH 4/7] Added #23 - RSS/atom feeds for user blogs Stuck on project file changes. --- src/Hosted/Main.fs | 139 ++++++++++++++++++++++------------- src/Hosted/userbloglist.html | 2 +- src/Website/Website.fsproj | 10 +++ 3 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/Hosted/Main.fs b/src/Hosted/Main.fs index e5d71476..16d4105c 100644 --- a/src/Hosted/Main.fs +++ b/src/Hosted/Main.fs @@ -26,6 +26,8 @@ type EndPoint = | [] Categories | [] AtomFeed | [] RSSFeed + | [] AtomFeedForUser of string + | [] RSSFeedForUser of string | [] Refresh | [] Contact | [] TermsOfUse @@ -1007,20 +1009,77 @@ module Site = .Cookie(Cookies.Banner false) .Doc() |> Content.Page - let USERBLOG_LISTING_NO_PAGING f = - UserBlogListTemplate() - .Menubar(menubar config.Value) - .ArticleList(Map.filter f articles.Value |> ARTICLES) - .Pagination(Doc.Empty) - .Footer(MainTemplate.Footer().Doc()) - .Cookie(Cookies.Banner false) - .Doc() + let USERBLOG_LISTING_NO_PAGING user f = + let templateFile = Path.Combine (__SOURCE_DIRECTORY__, sprintf @"../Hosted/userblog-%s.html" user) + if File.Exists templateFile then + UserBlogListTemplate(templateFile) + else + UserBlogListTemplate() + |> fun template -> + let name = user + //if String.IsNullOrEmpty(user) then + // config.Value.MasterUserDisplayName + //else + // config.Value.Users.[user] + template + .Menubar(menubar config.Value) + .AuthorName(name) + .ArticleList(Map.filter f articles.Value |> ARTICLES) + .Pagination(Doc.Empty) + .Footer(MainTemplate.Footer().Doc()) + .Cookie(Cookies.Banner false) + .Doc() |> Content.Page let REDIRECT_TO (url: string) = RedirectTemplate() .Url(url) .Doc() |> Content.Page + let ARTICLES_BY_USEROPT (userOpt: string option) = + articles.Value |> Map.toList + // Filter by user, if given + |> List.filter (fun ((user, _), _) -> if userOpt.IsSome then user = userOpt.Value else true) + |> List.sortByDescending (fun (_, article: Article) -> article.Date.Ticks) + let ATOM_FEED userOpt = + let ns = XNamespace.Get "http://www.w3.org/2005/Atom" + let articles = ARTICLES_BY_USEROPT userOpt + X (ns + "feed") [] [ + X (ns + "title") [] [TEXT config.Value.Title] + X (ns + "subtitle") [] [TEXT config.Value.Description] + X (ns + "link") ["href" => config.Value.ServerUrl] [] + X (ns + "updated") [] [Helpers.ATOM_DATE DateTime.UtcNow] + for ((user, slug), article) in articles do + X (ns + "entry") [] [ + X (ns + "title") [] [TEXT article.Title] + X (ns + "link") ["href" => config.Value.ServerUrl + Urls.POST_URL (user, slug)] [] + X (ns + "id") [] [TEXT (user+slug)] + for category in article.Categories do + X (ns + "category") [] [TEXT category] + X (ns + "summary") [] [TEXT article.Abstract] + X (ns + "updated") [] [TEXT <| Helpers.ATOM_DATE article.Date] + ] + ] + let RSS_FEED userOpt = + let articles = ARTICLES_BY_USEROPT userOpt + X (N "rss") ["version" => "2.0"] [ + X (N "channel") [] [ + X (N "title") [] [TEXT config.Value.Title] + X (N "description") [] [TEXT config.Value.Description] + X (N "link") [] [TEXT config.Value.ServerUrl] + X (N "lastBuildDate") [] [Helpers.RSS_DATE DateTime.UtcNow] + for ((user, slug), article) in articles do + X (N "item") [] [ + X (N "title") [] [TEXT article.Title] + X (N "link") [] [TEXT <| config.Value.ServerUrl + Urls.POST_URL (user, slug)] + X (N "guid") ["isPermaLink" => "false"] [TEXT (user+slug)] + for category in article.Categories do + X (N "category") [] [TEXT category] + X (N "description") [] [TEXT article.Abstract] + X (N "pubDate") [] [TEXT <| Helpers.RSS_DATE article.Date] + ] + ] + ] + Application.MultiPage (fun (ctx: Context<_>) -> function | Trainings -> TRAININGS () @@ -1060,7 +1119,7 @@ module Site = ARTICLE ("", p) // All articles by a given user | UserArticle (user, "") -> - USERBLOG_LISTING_NO_PAGING + USERBLOG_LISTING_NO_PAGING user <| fun (u, _) _ -> user = u | UserArticle (user, p) -> ARTICLE (user, p) @@ -1090,26 +1149,15 @@ module Site = Status = Http.Status.Ok, Headers = [Http.Header.Custom "content-type" "application/atom+xml"], WriteBody = fun stream -> - let ns = XNamespace.Get "http://www.w3.org/2005/Atom" - let articles = - articles.Value |> Map.toList |> List.sortByDescending (fun (_, article: Article) -> article.Date.Ticks) - let doc = - X (ns + "feed") [] [ - X (ns + "title") [] [TEXT config.Value.Title] - X (ns + "subtitle") [] [TEXT config.Value.Description] - X (ns + "link") ["href" => config.Value.ServerUrl] [] - X (ns + "updated") [] [Helpers.ATOM_DATE DateTime.UtcNow] - for ((user, slug), article) in articles do - X (ns + "entry") [] [ - X (ns + "title") [] [TEXT article.Title] - X (ns + "link") ["href" => config.Value.ServerUrl + Urls.POST_URL (user, slug)] [] - X (ns + "id") [] [TEXT (user+slug)] - for category in article.Categories do - X (ns + "category") [] [TEXT category] - X (ns + "summary") [] [TEXT article.Abstract] - X (ns + "updated") [] [TEXT <| Helpers.ATOM_DATE article.Date] - ] - ] + let doc = ATOM_FEED None + doc.Save(stream) + ) + | AtomFeedForUser user -> + Content.Custom ( + Status = Http.Status.Ok, + Headers = [Http.Header.Custom "content-type" "application/atom+xml"], + WriteBody = fun stream -> + let doc = ATOM_FEED (Some user) doc.Save(stream) ) | RSSFeed -> @@ -1117,27 +1165,15 @@ module Site = Status = Http.Status.Ok, Headers = [Http.Header.Custom "content-type" "application/rss+xml"], WriteBody = fun stream -> - let articles = - articles.Value |> Map.toList |> List.sortByDescending (fun (_, article: Article) -> article.Date.Ticks) - let doc = - X (N "rss") ["version" => "2.0"] [ - X (N "channel") [] [ - X (N "title") [] [TEXT config.Value.Title] - X (N "description") [] [TEXT config.Value.Description] - X (N "link") [] [TEXT config.Value.ServerUrl] - X (N "lastBuildDate") [] [Helpers.RSS_DATE DateTime.UtcNow] - for ((user, slug), article) in articles do - X (N "item") [] [ - X (N "title") [] [TEXT article.Title] - X (N "link") [] [TEXT <| config.Value.ServerUrl + Urls.POST_URL (user, slug)] - X (N "guid") ["isPermaLink" => "false"] [TEXT (user+slug)] - for category in article.Categories do - X (N "category") [] [TEXT category] - X (N "description") [] [TEXT article.Abstract] - X (N "pubDate") [] [TEXT <| Helpers.RSS_DATE article.Date] - ] - ] - ] + let doc = RSS_FEED None + doc.Save(stream) + ) + | RSSFeedForUser user -> + Content.Custom ( + Status = Http.Status.Ok, + Headers = [Http.Header.Custom "content-type" "application/rss+xml"], + WriteBody = fun stream -> + let doc = RSS_FEED (Some user) doc.Save(stream) ) | Refresh -> @@ -1228,6 +1264,9 @@ type Website() = // Generate the RSS/Atom feeds RSSFeed AtomFeed + for user in users do + RSSFeedForUser user + AtomFeedForUser user // Generate 404 page Error404 // Generate legal pages diff --git a/src/Hosted/userbloglist.html b/src/Hosted/userbloglist.html index a080a4b2..16511695 100644 --- a/src/Hosted/userbloglist.html +++ b/src/Hosted/userbloglist.html @@ -30,7 +30,7 @@
-
John Doe
+
${AuthorName}
diff --git a/src/Website/Website.fsproj b/src/Website/Website.fsproj index 890954c3..11eacc9e 100644 --- a/src/Website/Website.fsproj +++ b/src/Website/Website.fsproj @@ -23,6 +23,11 @@ + + + + + @@ -33,6 +38,11 @@ + + + + + From 842171913ed18c7481c728be2a2dce1b060744ab Mon Sep 17 00:00:00 2001 From: jooseppi12 Date: Fri, 22 Jan 2021 21:31:18 +0100 Subject: [PATCH 5/7] Rename rss and atom files from html files --- src/Website/Website.fsproj | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Website/Website.fsproj b/src/Website/Website.fsproj index 11eacc9e..62d058bc 100644 --- a/src/Website/Website.fsproj +++ b/src/Website/Website.fsproj @@ -39,8 +39,11 @@ + + + - + @@ -48,6 +51,14 @@ + + + + + + + + From 6c0748f24f8688046830e24dd40665ee00e97ef5 Mon Sep 17 00:00:00 2001 From: jooseppi12 Date: Fri, 22 Jan 2021 21:33:36 +0100 Subject: [PATCH 6/7] Remove outside ItemGroup for atom and rss files --- src/Website/Website.fsproj | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Website/Website.fsproj b/src/Website/Website.fsproj index 62d058bc..01ddda78 100644 --- a/src/Website/Website.fsproj +++ b/src/Website/Website.fsproj @@ -22,11 +22,6 @@ - - - - - From a0225f93382a1501dc34b73dbbf2d45e3fee6f50 Mon Sep 17 00:00:00 2001 From: Adam Granicz Date: Fri, 22 Jan 2021 21:55:49 +0100 Subject: [PATCH 7/7] Added an RSS feed link to each user's blog page. --- src/Hosted/Main.fs | 16 +++++++++++----- src/Hosted/userbloglist.html | 10 +--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Hosted/Main.fs b/src/Hosted/Main.fs index 16d4105c..67d84415 100644 --- a/src/Hosted/Main.fs +++ b/src/Hosted/Main.fs @@ -160,6 +160,11 @@ module Urls = else sprintf "/user/%s" user let LANG (lang: string) = sprintf "/%s" lang + let RSS_URL user = + if String.IsNullOrEmpty user then + sprintf "/rss" + else + sprintf "/rss/%s.rss" user module Helpers = open System.IO @@ -1016,14 +1021,15 @@ module Site = else UserBlogListTemplate() |> fun template -> - let name = user - //if String.IsNullOrEmpty(user) then - // config.Value.MasterUserDisplayName - //else - // config.Value.Users.[user] + let name = + if String.IsNullOrEmpty(user) then + config.Value.MasterUserDisplayName + else + config.Value.Users.[user] template .Menubar(menubar config.Value) .AuthorName(name) + .AuthorRSSUrl(Urls.RSS_URL user) .ArticleList(Map.filter f articles.Value |> ARTICLES) .Pagination(Doc.Empty) .Footer(MainTemplate.Footer().Doc()) diff --git a/src/Hosted/userbloglist.html b/src/Hosted/userbloglist.html index 16511695..a2a4965a 100644 --- a/src/Hosted/userbloglist.html +++ b/src/Hosted/userbloglist.html @@ -26,17 +26,9 @@
- - - +
${AuthorName}
- -
- Maecenas eget nunc dui. Fusce sit amet diam vel arcu auctor accumsan id sit amet libero. Nunc tempus purus et cursus ultrices. Quisque sollicitudin interdum arcu, ut posuere enim posuere id. Vivamus congue ipsum at ante ultrices, nec sodales turpis fringilla. Suspendisse vitae volutpat lacus. Donec luctus, nisl id sollicitudin condimentum, lacus mauris condimentum massa, posuere elementum magna magna vitae nibh. Ut non ligula purus. Integer sed metus quis nulla consectetur facilisis. Aliquam mattis, massa id rhoncus viverra, est nulla molestie arcu, non aliquam nunc nisi nec justo. Proin id pellentesque sapien, vel aliquet lorem. Nam tincidunt nisi at ligula fermentum, et ultrices ante suscipit. Pellentesque scelerisque non metus vitae consectetur. Phasellus mollis pharetra magna, nec luctus augue. -