From a205dc9c7e69821af6dac10259d1c6ca2cf726e7 Mon Sep 17 00:00:00 2001 From: Thomas Wade Date: Tue, 30 Oct 2018 17:33:24 +1030 Subject: [PATCH] Add FAQ functionality and some style tweaks Switched to HTML5-style routing Reworked Express backend to accommodate HTML5-style routing Links are now highlighted with a black background and white foreground Reworked spacing on H1s Added classes to nav buttons --- data/faq.json | 40 ++++++++++++++++++- server.js | 26 +++++++----- 404.html => static/404.html | 0 index.html => static/index.html | 7 ++-- {views => static/partials}/footer.html | 0 {views => static/partials}/header.html | 2 +- static/partials/navbuttons.html | 6 +++ {views => static/partials}/sidebar.html | 0 .../scripts}/angular-route.min.js | 0 .../scripts}/angular-sanitize.min.js | 0 {scripts => static/scripts}/angular.min.js | 0 {scripts => static/scripts}/app.js | 27 ++++++++++--- {scripts => static/scripts}/marked.min.js | 0 .../scripts}/ng-tags-input.min.js | 0 {styles => static/styles}/404.css | 0 {styles => static/styles}/default.css | 33 +++++++++++++-- {styles => static/styles}/ng-tags-input.css | 0 static/templates/faqentry.html | 4 ++ {templates => static/templates}/post.html | 0 {views => static/views}/about.html | 0 {views => static/views}/blog.html | 0 {views => static/views}/create.html | 0 static/views/faq.html | 7 ++++ views/faq.html | 0 views/navbuttons.html | 6 --- 25 files changed, 125 insertions(+), 33 deletions(-) rename 404.html => static/404.html (100%) rename index.html => static/index.html (84%) rename {views => static/partials}/footer.html (100%) rename {views => static/partials}/header.html (82%) create mode 100644 static/partials/navbuttons.html rename {views => static/partials}/sidebar.html (100%) rename {scripts => static/scripts}/angular-route.min.js (100%) rename {scripts => static/scripts}/angular-sanitize.min.js (100%) rename {scripts => static/scripts}/angular.min.js (100%) rename {scripts => static/scripts}/app.js (83%) rename {scripts => static/scripts}/marked.min.js (100%) rename {scripts => static/scripts}/ng-tags-input.min.js (100%) rename {styles => static/styles}/404.css (100%) rename {styles => static/styles}/default.css (93%) rename {styles => static/styles}/ng-tags-input.css (100%) create mode 100644 static/templates/faqentry.html rename {templates => static/templates}/post.html (100%) rename {views => static/views}/about.html (100%) rename {views => static/views}/blog.html (100%) rename {views => static/views}/create.html (100%) create mode 100644 static/views/faq.html delete mode 100644 views/faq.html delete mode 100644 views/navbuttons.html diff --git a/data/faq.json b/data/faq.json index 227e51e..dd8ed79 100644 --- a/data/faq.json +++ b/data/faq.json @@ -1,6 +1,42 @@ [ { - "question":"What's a 'yeet'?", - "answer":"Well you see, Billy..." + "title":"What happened to the old Lemonblog?", + "content":"Long story short, the old Lemonblog is dead. *Super* dead. It's since been redesigned for better cross-platform usability and features a newer (and far better in my opinion) aesthetic." + }, + { + "title":"Lorem ipsum dolor sit amet, consectetur adipiscing elit?", + "content":"Vestibulum iaculis, eros accumsan tincidunt dictum, velit nunc laoreet ipsum, quis varius risus urna sit amet turpis. Vivamus fermentum aliquam maximus. In porta eleifend lectus in fermentum. Aenean placerat mi libero, malesuada maximus mi faucibus vel. Aliquam vitae lacus sagittis, porttitor urna in, fringilla nibh. Quisque nec viverra ipsum, sed tincidunt quam. Quisque vulputate vel lectus ac varius. Aenean vehicula lectus eu arcu pharetra eleifend. Aenean ornare elit sit amet vehicula fringilla. Fusce non accumsan odio. Curabitur elit libero, pellentesque sit amet egestas quis, vehicula sit amet mi." + }, + { + "title":"Etiam tempus ipsum eu nunc posuere suscipit?", + "content":"Sed sit amet nisl ac sapien faucibus lacinia vel sed tortor. Donec tincidunt nulla in arcu condimentum, eget scelerisque nulla euismod. Proin eu est vitae libero ullamcorper convallis quis sed enim. Nunc non quam hendrerit, scelerisque mauris vel, suscipit sem. Nam mattis diam diam, non blandit ante molestie at. Nunc egestas lacus nec placerat mollis. Mauris egestas neque varius consectetur ultricies. Vestibulum ut interdum dui. Pellentesque eu nisl viverra, placerat risus sed, faucibus justo." + }, + { + "title":"Nulla elit dui, luctus ac interdum ut, dignissim sed ante?", + "content":"Maecenas interdum turpis non ligula porttitor pulvinar. Integer at tempor ex. In finibus leo eu commodo convallis. Etiam molestie nisl id ligula vulputate varius. Aenean placerat, erat non placerat iaculis, ipsum nibh luctus ipsum, ac vehicula diam mauris ut purus. Donec nec euismod felis. Sed sagittis eleifend nisi id porttitor. Aliquam erat volutpat. Sed ultricies velit purus, nec suscipit felis sagittis id. Nullam fermentum dictum purus, nec cursus ligula commodo in. Donec commodo a lectus a sagittis." + }, + { + "title":"Pellentesque at ullamcorper velit?", + "content":"Aliquam eros orci, blandit ac nisl sed, convallis eleifend mauris. Sed pretium mollis ante. Suspendisse dictum massa ut libero fringilla sagittis. Donec at sapien bibendum, iaculis quam nec, eleifend nisl. Curabitur ac euismod mi, in gravida arcu. Maecenas nunc urna, ornare eget enim quis, rhoncus euismod tellus. Praesent eget sem placerat, euismod tellus eu, porttitor elit. Donec tempus, nunc id dictum auctor, metus ipsum ornare justo, et vestibulum nulla sem eu turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce fermentum, lacus at consequat facilisis, mauris odio euismod turpis, sed semper turpis mauris quis dui." + }, + { + "title":"Vestibulum id sagittis mauris?", + "content":"Praesent id justo auctor, egestas enim vel, auctor erat. Nunc ullamcorper ac enim a blandit. Maecenas arcu ligula, pretium lacinia imperdiet ac, interdum ac nisl. Aliquam erat volutpat. Nulla commodo malesuada accumsan. Fusce eros quam, viverra sit amet sollicitudin id, pulvinar molestie diam. Nunc et ante vitae risus tempor dapibus et quis enim. Sed sodales urna non semper tristique. In eget elit pharetra, efficitur nisi in, tincidunt nunc. Donec eu mauris lorem. Nulla maximus sodales velit nec ornare." + }, + { + "title":"Sed ipsum metus, pellentesque at enim eget, lacinia consectetur ex?", + "content":"Cras dapibus consequat tempor. Nunc justo mi, tempor nec sodales a, accumsan ac nunc. In volutpat iaculis risus, a ultricies quam egestas nec. Morbi fringilla neque a posuere semper. Suspendisse eget felis in risus elementum rutrum et eu ipsum. Donec sit amet ante elementum, vulputate ante eu, interdum dolor. Mauris consectetur ac elit mollis porttitor. Nam a ex enim. Ut eu massa at dui condimentum viverra." + }, + { + "title":"Curabitur viverra sem ac fringilla egestas?", + "content":"Nunc id diam eleifend, accumsan erat ac, dapibus libero. Donec consectetur id nunc at facilisis. Vestibulum pretium leo in lectus pulvinar, eget imperdiet ex blandit. Praesent in lorem ac velit gravida venenatis scelerisque vel purus. Sed ornare quam non quam volutpat, nec ornare urna finibus. Aliquam sodales dui eu risus mattis, a pellentesque turpis eleifend. Donec leo ex, vulputate sit amet tempus sit amet, sodales et purus. Cras blandit a orci quis maximus." + }, + { + "title":"Aliquam vehicula mauris enim, nec placerat massa pellentesque venenatis?", + "content":"Vivamus fermentum odio magna, et porttitor diam varius sodales. Aenean sit amet ipsum gravida, porta nisi et, convallis turpis. Proin nec felis finibus, vestibulum sapien vitae, posuere nisl. Cras tempus lacinia tincidunt. Mauris placerat elit et sollicitudin interdum. Aenean vehicula maximus euismod. Vivamus mollis, nisl in aliquam rhoncus, mauris metus tincidunt enim, ut finibus lectus nisi vel arcu. Proin pulvinar ipsum nisl, et dignissim justo sodales eu. Proin et lorem augue. Praesent fermentum erat nec est auctor, ac rhoncus nisl lobortis. Duis pellentesque nisi at urna tincidunt cursus. Curabitur aliquam mi ac pulvinar imperdiet. Proin sem leo, aliquam ut aliquam ac, scelerisque nec enim. Curabitur felis velit, varius ac ex ut, ultricies efficitur lorem." + }, + { + "title":"Pellentesque porta tellus in velit suscipit dignissim?", + "content":"Morbi non lectus luctus, dictum leo vitae, finibus nulla. Cras rhoncus diam eu diam porta, id dapibus tortor vulputate. Aliquam dapibus neque sit amet dui aliquam venenatis. Nullam vitae magna tellus. Maecenas faucibus pretium libero, at tempor lectus varius non. Praesent turpis lorem, ultricies ut eleifend nec, dignissim a neque. Duis gravida mollis purus quis blandit. Praesent dui nibh, mattis elementum auctor nec, congue non dolor. Etiam lorem elit, convallis eu dignissim a, imperdiet quis ex. Mauris et lorem blandit, congue dolor sit amet, laoreet leo. Maecenas congue eu nibh et porta. Donec a varius lacus." } ] diff --git a/server.js b/server.js index fe49c3d..9e9e439 100644 --- a/server.js +++ b/server.js @@ -5,27 +5,21 @@ var bodyParser = require('body-parser'); // Data conversion, JSON parsing // Set up Express var app = express(); -app.use(express.static("./")); // Serve static files from root +app.use(express.static("./static/")); // Serve static files from /static/ app.use(express.json()); // Parse JSON in requests // app.use("/", (req, res, next) => // Finally send a 404 page // { // res.status(404).sendFile("404.html", {"root": "./"}); // }); -// Root route, respond with with index.html -app.get("/", function(req, res) -{ - res.sendFile("./index.html"); -}); - // Posts route, return posts.json -app.get("/posts", function(req, res) +app.get("/api/posts", function(req, res) { res.json(JSON.parse(fs.readFileSync('./data/posts.json'))); }); // Posts route, digest received post -app.post("/posts", function(req, res) +app.post("/api/posts", function(req, res) { var postsFile = fs.readFileSync('./data/posts.json'); var posts = JSON.parse(postsFile); @@ -54,11 +48,23 @@ app.post("/posts", function(req, res) }); // About route, return about.json -app.get("/about", (req, res) => +app.get("/api/about", (req, res) => { res.json(JSON.parse(fs.readFileSync('./data/about.json'))); }); +// FAQ route, return faq.json +app.get("/api/faq", (req, res) => +{ + res.json(JSON.parse(fs.readFileSync('./data/faq.json'))); +}); + +// Default route, serve static index.html and let AngularJS handle the remainder +app.get("/*", (req, res) => +{ + res.sendFile("./static/index.html", {root: __dirname}) +}); + // Start listening app.listen(8080, function() { diff --git a/404.html b/static/404.html similarity index 100% rename from 404.html rename to static/404.html diff --git a/index.html b/static/index.html similarity index 84% rename from index.html rename to static/index.html index feec0d8..6921c29 100644 --- a/index.html +++ b/static/index.html @@ -14,18 +14,17 @@ -
- +
- +
- +
diff --git a/views/footer.html b/static/partials/footer.html similarity index 100% rename from views/footer.html rename to static/partials/footer.html diff --git a/views/header.html b/static/partials/header.html similarity index 82% rename from views/header.html rename to static/partials/header.html index b6b9e66..20bb7d4 100644 --- a/views/header.html +++ b/static/partials/header.html @@ -8,6 +8,6 @@ adds zest to your day - + diff --git a/static/partials/navbuttons.html b/static/partials/navbuttons.html new file mode 100644 index 0000000..2c9b7de --- /dev/null +++ b/static/partials/navbuttons.html @@ -0,0 +1,6 @@ + diff --git a/views/sidebar.html b/static/partials/sidebar.html similarity index 100% rename from views/sidebar.html rename to static/partials/sidebar.html diff --git a/scripts/angular-route.min.js b/static/scripts/angular-route.min.js similarity index 100% rename from scripts/angular-route.min.js rename to static/scripts/angular-route.min.js diff --git a/scripts/angular-sanitize.min.js b/static/scripts/angular-sanitize.min.js similarity index 100% rename from scripts/angular-sanitize.min.js rename to static/scripts/angular-sanitize.min.js diff --git a/scripts/angular.min.js b/static/scripts/angular.min.js similarity index 100% rename from scripts/angular.min.js rename to static/scripts/angular.min.js diff --git a/scripts/app.js b/static/scripts/app.js similarity index 83% rename from scripts/app.js rename to static/scripts/app.js index 0b25da1..b269f40 100644 --- a/scripts/app.js +++ b/static/scripts/app.js @@ -1,7 +1,7 @@ var app = angular.module("app", ["ngRoute", "ngSanitize", "ngTagsInput"]); app.config( - function ($routeProvider) + function ($routeProvider, $locationProvider) { $routeProvider .when("/", {templateUrl: "views/blog.html", controller: "blog"}) @@ -9,15 +9,22 @@ app.config( .when("/about", {templateUrl: "views/about.html", controller: "about"}) .when("/faq", {templateUrl: "views/faq.html", controller: "faq"}) .otherwise({templateUrl: "404.html"}); + + $locationProvider.html5Mode({enabled: true, requireBase: false}); } ); +app.run(($anchorScroll) => +{ + $anchorScroll.yOffset = 100; +}) + app.controller("blog", ["$scope", "$http", function($scope, $http) { $scope.posts = []; - $http.get("/posts") + $http.get("/api/posts") .then((r) => { $scope.posts = angular.fromJson(r.data); }); } ]); @@ -44,7 +51,7 @@ app.controller("create", ["$scope", "$http", }; // POST it to the server - $http.post("/posts", post); + $http.post("/api/posts", post); // Clear the fields $scope.title = ""; @@ -83,15 +90,23 @@ app.controller("about", ["$scope", "$http", { $scope.aboutContent = ""; - $http.get("about") + $http.get("/api/about") .then((r) => { $scope.aboutContent = angular.fromJson(r.data).content; }); } ]); -app.controller("faq", ["$scope", - function($scope) +app.controller("faq", ["$scope", "$http", "$location", "$anchorScroll", + function($scope, $http, $location, $anchorScroll) { + $scope.entries = [] + $http.get("/api/faq") + .then((r) => { $scope.entries = angular.fromJson(r.data) }); + + $scope.scrollTo = (hash) => + { + $anchorScroll(hash); + }; } ]); diff --git a/scripts/marked.min.js b/static/scripts/marked.min.js similarity index 100% rename from scripts/marked.min.js rename to static/scripts/marked.min.js diff --git a/scripts/ng-tags-input.min.js b/static/scripts/ng-tags-input.min.js similarity index 100% rename from scripts/ng-tags-input.min.js rename to static/scripts/ng-tags-input.min.js diff --git a/styles/404.css b/static/styles/404.css similarity index 100% rename from styles/404.css rename to static/styles/404.css diff --git a/styles/default.css b/static/styles/default.css similarity index 93% rename from styles/default.css rename to static/styles/default.css index 28e0646..5e7ac43 100644 --- a/styles/default.css +++ b/static/styles/default.css @@ -28,7 +28,16 @@ a text-decoration: none; - color: #000; + color: #fff; + background-color: #000; +} + +a:not(.navButton) +{ + margin-right: 2px; + margin-left: 2px; + + box-shadow: 2px 0 0 0 #000, -2px 0 0 0 #000; } input, @@ -59,6 +68,17 @@ button:disabled background-color: #888; } +h1, +h2, +h3, +h4, +h5, +h6 +{ + margin-top: 20px; + margin-bottom: 5px; +} + h1 { font-size: 45px; @@ -145,7 +165,7 @@ h1 float: right; } -.navButtons a +.navButtons .navButton { display: block; float: left; @@ -163,12 +183,12 @@ h1 color: #fff; background-color: #000; } -.navButtons a.current +.navButtons .navButton.current { color: #000; box-shadow: inset 0 60px 0 0 #fff; /* Box shadow hack to get an inset border */ } -.navButtons a:hover:not(.current) +.navButtons .navButton:hover:not(.current) { box-shadow: inset 0 10px 0 0 #fff; } @@ -387,3 +407,8 @@ h1 /* color: #000; background-color: #fff; */ } + +.faqEntry +{ + margin-bottom: 30px; +} diff --git a/styles/ng-tags-input.css b/static/styles/ng-tags-input.css similarity index 100% rename from styles/ng-tags-input.css rename to static/styles/ng-tags-input.css diff --git a/static/templates/faqentry.html b/static/templates/faqentry.html new file mode 100644 index 0000000..09371cf --- /dev/null +++ b/static/templates/faqentry.html @@ -0,0 +1,4 @@ +
+

{{$index+1}}. {{entry.title}}

+
+
diff --git a/templates/post.html b/static/templates/post.html similarity index 100% rename from templates/post.html rename to static/templates/post.html diff --git a/views/about.html b/static/views/about.html similarity index 100% rename from views/about.html rename to static/views/about.html diff --git a/views/blog.html b/static/views/blog.html similarity index 100% rename from views/blog.html rename to static/views/blog.html diff --git a/views/create.html b/static/views/create.html similarity index 100% rename from views/create.html rename to static/views/create.html diff --git a/static/views/faq.html b/static/views/faq.html new file mode 100644 index 0000000..0c58ec3 --- /dev/null +++ b/static/views/faq.html @@ -0,0 +1,7 @@ +

FAQ

+
    +
  1. + {{entry.title}} +
  2. +
+ diff --git a/views/faq.html b/views/faq.html deleted file mode 100644 index e69de29..0000000 diff --git a/views/navbuttons.html b/views/navbuttons.html deleted file mode 100644 index ebbdb6b..0000000 --- a/views/navbuttons.html +++ /dev/null @@ -1,6 +0,0 @@ -