Browse Source

add customization

Pouria Ezzati 1 năm trước cách đây
mục cha
commit
1e01e10459
7 tập tin đã thay đổi với 47 bổ sung3 xóa
  1. 2 0
      .gitignore
  2. 3 0
      custom/.gitkeep
  3. 1 1
      package.json
  4. 1 0
      server/handlers/locals.handler.js
  5. 9 1
      server/server.js
  6. 28 1
      server/utils/utils.js
  7. 3 0
      server/views/layout.hbs

+ 2 - 0
.gitignore

@@ -14,3 +14,5 @@ docs/api/static
 **/.DS_Store
 db/*
 !db/.gitkeep
+custom/*
+!custom/.gitkeep

+ 3 - 0
custom/.gitkeep

@@ -0,0 +1,3 @@
+# keep this folder in git
+# put supported customization files for styles and such
+# if you're using docker make sure to mount this folder

+ 1 - 1
package.json

@@ -4,7 +4,7 @@
   "description": "Modern URL shortener.",
   "main": "./server/server.js",
   "scripts": {
-    "dev": "cross-env NODE_ENV=development node --watch-path=./server server/server.js",
+    "dev": "cross-env NODE_ENV=development node --watch-path=./server --watch-path=./custom server/server.js",
     "start": "cross-env NODE_ENV=production node server/server.js",
     "migrate": "knex migrate:latest",
     "migrate:make": "knex migrate:make",

+ 1 - 0
server/handlers/locals.handler.js

@@ -29,6 +29,7 @@ function config(req, res, next) {
   res.locals.disallow_registration = env.DISALLOW_REGISTRATION;
   res.locals.mail_enabled = env.MAIL_ENABLED;
   res.locals.report_email = env.REPORT_EMAIL;
+  res.locals.custom_styles = utils.getCustomCSSFileNames();
   next();
 }
 

+ 9 - 1
server/server.js

@@ -40,6 +40,10 @@ app.use(helmet({ contentSecurityPolicy: false }));
 app.use(cookieParser());
 app.use(express.json());
 app.use(express.urlencoded({ extended: true }));
+
+// serve static
+app.use("/images", express.static("custom/images"));
+app.use("/css", express.static("custom/css", { extensions: ["css"] }));
 app.use(express.static("static"));
 
 app.use(passport.initialize());
@@ -47,8 +51,12 @@ app.use(locals.isHTML);
 app.use(locals.config);
 
 // template engine / serve html
+
 app.set("view engine", "hbs");
-app.set("views", path.join(__dirname, "views"));
+app.set("views", [
+  path.join(__dirname, "../custom/views"),
+  path.join(__dirname, "views"),
+]);
 utils.registerHandlebarsHelpers();
 
 // if is custom domain, redirect to the set homepage

+ 28 - 1
server/utils/utils.js

@@ -1,7 +1,8 @@
 const { differenceInDays, differenceInHours, differenceInMonths, differenceInMilliseconds, addDays, subHours, subDays, subMonths, subYears, format } = require("date-fns");
 const { customAlphabet } = require("nanoid");
 const JWT = require("jsonwebtoken");
-const path = require("path");
+const path = require("node:path");
+const fs = require("node:fs");
 const hbs = require("hbs");
 const ms = require("ms");
 
@@ -360,6 +361,31 @@ function registerHandlebarsHelpers() {
       return val;
   });
   hbs.registerPartials(path.join(__dirname, "../views/partials"), function (err) {});
+  const customPartialsPath = path.join(__dirname, "../../custom/views/partials");
+  const customPartialsExist = fs.existsSync(customPartialsPath);
+  if (customPartialsExist) {
+    hbs.registerPartials(customPartialsPath, function (err) {});
+  }
+}
+
+// grab custom styles file name from the custom/css folder
+const custom_css_file_names = [];
+const customCSSPath = path.join(__dirname, "../../custom/css");
+const customCSSExists = fs.existsSync(customCSSPath);
+if (customCSSExists) {
+  fs.readdir(customCSSPath, function(error, files) {
+    if (error) {
+      console.warn("Could not read the custom CSS folder:", error);
+    } else {
+      files.forEach(function(file_name) {
+        custom_css_file_names.push(file_name);
+      });
+    }
+  })
+}
+
+function getCustomCSSFileNames() {
+  return custom_css_file_names;
 }
 
 module.exports = {
@@ -368,6 +394,7 @@ module.exports = {
   dateToUTC,
   deleteCurrentToken,
   generateId,
+  getCustomCSSFileNames,
   getDifferenceFunction,
   getInitStats,
   getShortURL,

+ 3 - 0
server/views/layout.hbs

@@ -24,6 +24,9 @@
   <meta name="description" content="{{site_name}} is a free and open source URL shortener with custom domains and stats." />
   <title>{{site_name}} | {{title}}</title>
   <link rel="stylesheet" href="/css/styles.css">
+  {{#each custom_styles}}
+    <link rel="stylesheet" href="/css/{{this}}">
+  {{/each}}
   {{{block "stylesheets"}}}
 </head>
 <body>