mirror of
https://github.com/plankanban/planka.git
synced 2026-07-15 21:48:11 +03:00
feat: Support running under subpath (#1451)
This commit is contained in:
committed by
GitHub
parent
61a3ff55cc
commit
5e6195b252
@@ -11,7 +11,7 @@ server/test
|
|||||||
server/.tmp
|
server/.tmp
|
||||||
server/.venv
|
server/.venv
|
||||||
|
|
||||||
server/views/index.html
|
server/views/index.ejs
|
||||||
|
|
||||||
server/data/*
|
server/data/*
|
||||||
!server/data/.gitkeep
|
!server/data/.gitkeep
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
working-directory: ./client
|
working-directory: ./client
|
||||||
|
|
||||||
- name: Build client
|
- name: Build client
|
||||||
run: DISABLE_ESLINT_PLUGIN=true npm run build
|
run: INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build
|
||||||
working-directory: ./client
|
working-directory: ./client
|
||||||
|
|
||||||
- name: Include licenses into dist
|
- name: Include licenses into dist
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
- name: Include built client into dist
|
- name: Include built client into dist
|
||||||
run: |
|
run: |
|
||||||
mv ../../client/dist/* public
|
mv ../../client/dist/* public
|
||||||
cp public/index.html views
|
mv public/index.ejs views
|
||||||
working-directory: ./server/dist
|
working-directory: ./server/dist
|
||||||
|
|
||||||
- name: Create release package
|
- name: Create release package
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Build client
|
- name: Build client
|
||||||
run: |
|
run: |
|
||||||
DISABLE_ESLINT_PLUGIN=true npm run build
|
INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build
|
||||||
mv dist build
|
mv dist build
|
||||||
working-directory: ./client
|
working-directory: ./client
|
||||||
|
|
||||||
- name: Update Dockerfile to use prebuilt client
|
- name: Update Dockerfile to use prebuilt client
|
||||||
run: |
|
run: |
|
||||||
sed -i '/^FROM node:22 AS client/,/^ && DISABLE_ESLINT_PLUGIN=true npm run build$/c\
|
sed -i '/^FROM node:22 AS client/,/^ && INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build$/c\
|
||||||
FROM node:22 AS client\n\
|
FROM node:22 AS client\n\
|
||||||
WORKDIR /app\n\
|
WORKDIR /app\n\
|
||||||
COPY client/build /app/dist' Dockerfile
|
COPY client/build /app/dist' Dockerfile
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Build client
|
- name: Build client
|
||||||
run: |
|
run: |
|
||||||
DISABLE_ESLINT_PLUGIN=true npm run build
|
INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build
|
||||||
mv dist build
|
mv dist build
|
||||||
working-directory: ./client
|
working-directory: ./client
|
||||||
|
|
||||||
- name: Update Dockerfile to use prebuilt client
|
- name: Update Dockerfile to use prebuilt client
|
||||||
run: |
|
run: |
|
||||||
sed -i '/^FROM node:22 AS client/,/^ && DISABLE_ESLINT_PLUGIN=true npm run build$/c\
|
sed -i '/^FROM node:22 AS client/,/^ && INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build$/c\
|
||||||
FROM node:22 AS client\n\
|
FROM node:22 AS client\n\
|
||||||
WORKDIR /app\n\
|
WORKDIR /app\n\
|
||||||
COPY client/build /app/dist' Dockerfile
|
COPY client/build /app/dist' Dockerfile
|
||||||
|
|||||||
2
.github/workflows/build-and-test.yml
vendored
2
.github/workflows/build-and-test.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
npm install
|
npm install
|
||||||
cd client
|
cd client
|
||||||
npm run build
|
INDEX_FORMAT=ejs npm run build
|
||||||
|
|
||||||
- name: Set up and start server for testing
|
- name: Set up and start server for testing
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ COPY client .
|
|||||||
|
|
||||||
RUN npm install npm --global \
|
RUN npm install npm --global \
|
||||||
&& npm install --omit=dev \
|
&& npm install --omit=dev \
|
||||||
&& DISABLE_ESLINT_PLUGIN=true npm run build
|
&& INDEX_FORMAT=ejs DISABLE_ESLINT_PLUGIN=true npm run build
|
||||||
|
|
||||||
# Stage 3: Final image
|
# Stage 3: Final image
|
||||||
FROM node:22-alpine
|
FROM node:22-alpine
|
||||||
@@ -41,12 +41,12 @@ COPY --from=server --chown=node:node /app/node_modules node_modules
|
|||||||
COPY --from=server --chown=node:node /app/dist .
|
COPY --from=server --chown=node:node /app/dist .
|
||||||
|
|
||||||
COPY --from=client --chown=node:node /app/dist public
|
COPY --from=client --chown=node:node /app/dist public
|
||||||
COPY --from=client --chown=node:node /app/dist/index.html views
|
|
||||||
|
|
||||||
RUN python3 -m venv .venv \
|
RUN python3 -m venv .venv \
|
||||||
&& .venv/bin/pip3 install --upgrade pip \
|
&& .venv/bin/pip3 install --upgrade pip \
|
||||||
&& .venv/bin/pip3 install -r requirements.txt --no-cache-dir \
|
&& .venv/bin/pip3 install -r requirements.txt --no-cache-dir \
|
||||||
&& mv .env.sample .env \
|
&& mv .env.sample .env \
|
||||||
|
&& mv public/index.ejs views \
|
||||||
&& npm config set update-notifier false
|
&& npm config set update-notifier false
|
||||||
|
|
||||||
VOLUME /app/data
|
VOLUME /app/data
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const http = {};
|
|||||||
return result;
|
return result;
|
||||||
}, new FormData());
|
}, new FormData());
|
||||||
|
|
||||||
return fetch(`${Config.SERVER_BASE_URL}/api${url}`, {
|
return fetch(`${Config.BASE_PATH}/api${url}`, {
|
||||||
method,
|
method,
|
||||||
headers,
|
headers,
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Config from '../constants/Config';
|
|||||||
|
|
||||||
const io = sailsIOClient(socketIOClient);
|
const io = sailsIOClient(socketIOClient);
|
||||||
|
|
||||||
io.sails.url = Config.SERVER_BASE_URL;
|
io.sails.path = `${Config.BASE_PATH}/socket.io`;
|
||||||
io.sails.autoConnect = false;
|
io.sails.autoConnect = false;
|
||||||
io.sails.reconnection = true;
|
io.sails.reconnection = true;
|
||||||
io.sails.useCORSRouteToGetCookie = false;
|
io.sails.useCORSRouteToGetCookie = false;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useSelector } from 'react-redux';
|
|||||||
import history from '../../../history';
|
import history from '../../../history';
|
||||||
import selectors from '../../../selectors';
|
import selectors from '../../../selectors';
|
||||||
import matchPaths from '../../../utils/match-paths';
|
import matchPaths from '../../../utils/match-paths';
|
||||||
|
import Config from '../../../constants/Config';
|
||||||
import Paths from '../../../constants/Paths';
|
import Paths from '../../../constants/Paths';
|
||||||
|
|
||||||
const Link = React.memo(({ href, content, stopPropagation, ...props }) => {
|
const Link = React.memo(({ href, content, stopPropagation, ...props }) => {
|
||||||
@@ -23,7 +24,8 @@ const Link = React.memo(({ href, content, stopPropagation, ...props }) => {
|
|||||||
}
|
}
|
||||||
}, [href]);
|
}, [href]);
|
||||||
|
|
||||||
const isSameSite = !!url && url.origin === window.location.origin;
|
const isSameSite =
|
||||||
|
!!url && url.origin === window.location.origin && url.pathname.startsWith(Config.BASE_PATH);
|
||||||
|
|
||||||
const cardsPathMatch = useMemo(() => {
|
const cardsPathMatch = useMemo(() => {
|
||||||
if (!isSameSite) {
|
if (!isSameSite) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import history from '../../history';
|
import history from '../../history';
|
||||||
|
import Config from '../../constants/Config';
|
||||||
|
|
||||||
const SAME_SITE_CLASS = 'same-site';
|
const SAME_SITE_CLASS = 'same-site';
|
||||||
|
|
||||||
@@ -30,7 +31,9 @@ function process(token, nextToken) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSameSite = url.origin === window.location.origin;
|
const isSameSite =
|
||||||
|
url.origin === window.location.origin && url.pathname.startsWith(Config.BASE_PATH);
|
||||||
|
|
||||||
const trimOrigin = isSameSite && nextToken.type === 'text' && nextToken.content === href;
|
const trimOrigin = isSameSite && nextToken.type === 'text' && nextToken.content === href;
|
||||||
|
|
||||||
if (isSameSite) {
|
if (isSameSite) {
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SERVER_BASE_URL =
|
const BASE_PATH = window.BASE_PATH || '';
|
||||||
import.meta.env.VITE_SERVER_BASE_URL || (import.meta.env.DEV ? 'http://localhost:1337' : '');
|
|
||||||
|
|
||||||
const ACCESS_TOKEN_KEY = 'accessToken';
|
const ACCESS_TOKEN_KEY = 'accessToken';
|
||||||
const ACCESS_TOKEN_VERSION_KEY = 'accessTokenVersion';
|
const ACCESS_TOKEN_VERSION_KEY = 'accessTokenVersion';
|
||||||
@@ -20,7 +19,7 @@ const MAX_SIZE_TO_DISPLAY_CONTENT = 256 * 1024;
|
|||||||
const IS_MAC = navigator.platform.startsWith('Mac');
|
const IS_MAC = navigator.platform.startsWith('Mac');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
SERVER_BASE_URL,
|
BASE_PATH,
|
||||||
ACCESS_TOKEN_KEY,
|
ACCESS_TOKEN_KEY,
|
||||||
ACCESS_TOKEN_VERSION_KEY,
|
ACCESS_TOKEN_VERSION_KEY,
|
||||||
ACCESS_TOKEN_VERSION,
|
ACCESS_TOKEN_VERSION,
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ROOT = '/';
|
import Config from './Config';
|
||||||
const LOGIN = '/login';
|
|
||||||
const OIDC_CALLBACK = '/oidc-callback';
|
const ROOT = `${Config.BASE_PATH}/`;
|
||||||
const PROJECTS = '/projects/:id';
|
const LOGIN = `${Config.BASE_PATH}/login`;
|
||||||
const BOARDS = '/boards/:id';
|
const OIDC_CALLBACK = `${Config.BASE_PATH}/oidc-callback`;
|
||||||
const CARDS = '/cards/:id';
|
const PROJECTS = `${Config.BASE_PATH}/projects/:id`;
|
||||||
|
const BOARDS = `${Config.BASE_PATH}/boards/:id`;
|
||||||
|
const CARDS = `${Config.BASE_PATH}/cards/:id`;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ROOT,
|
ROOT,
|
||||||
|
|||||||
@@ -8,24 +8,28 @@ import { jwtDecode } from 'jwt-decode';
|
|||||||
|
|
||||||
import Config from '../constants/Config';
|
import Config from '../constants/Config';
|
||||||
|
|
||||||
|
const PATH = Config.BASE_PATH || '/';
|
||||||
|
|
||||||
export const setAccessToken = (accessToken) => {
|
export const setAccessToken = (accessToken) => {
|
||||||
const { exp } = jwtDecode(accessToken);
|
const { exp } = jwtDecode(accessToken);
|
||||||
const expires = new Date(exp * 1000);
|
const expires = new Date(exp * 1000);
|
||||||
|
|
||||||
Cookies.set(Config.ACCESS_TOKEN_KEY, accessToken, {
|
Cookies.set(Config.ACCESS_TOKEN_KEY, accessToken, {
|
||||||
expires,
|
expires,
|
||||||
|
path: PATH,
|
||||||
secure: window.location.protocol === 'https:',
|
secure: window.location.protocol === 'https:',
|
||||||
sameSite: 'strict',
|
sameSite: 'strict',
|
||||||
});
|
});
|
||||||
|
|
||||||
Cookies.set(Config.ACCESS_TOKEN_VERSION_KEY, Config.ACCESS_TOKEN_VERSION, {
|
Cookies.set(Config.ACCESS_TOKEN_VERSION_KEY, Config.ACCESS_TOKEN_VERSION, {
|
||||||
expires,
|
expires,
|
||||||
|
path: PATH,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeAccessToken = () => {
|
export const removeAccessToken = () => {
|
||||||
Cookies.remove(Config.ACCESS_TOKEN_KEY);
|
Cookies.remove(Config.ACCESS_TOKEN_KEY, { path: PATH });
|
||||||
Cookies.remove(Config.ACCESS_TOKEN_VERSION_KEY);
|
Cookies.remove(Config.ACCESS_TOKEN_VERSION_KEY, { path: PATH });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAccessToken = () => {
|
export const getAccessToken = () => {
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ ln -s ${CLIENT_PATH}/logo512.png ${SERVER_PUBLIC_PATH}/logo512.png && echo "Link
|
|||||||
ln -s ${CLIENT_PATH}/manifest.json ${SERVER_PUBLIC_PATH}/manifest.json && echo "Linked manifest.json successfully"
|
ln -s ${CLIENT_PATH}/manifest.json ${SERVER_PUBLIC_PATH}/manifest.json && echo "Linked manifest.json successfully"
|
||||||
ln -s ${CLIENT_PATH}/robots.txt ${SERVER_PUBLIC_PATH}/robots.txt && echo "Linked robots.txt successfully"
|
ln -s ${CLIENT_PATH}/robots.txt ${SERVER_PUBLIC_PATH}/robots.txt && echo "Linked robots.txt successfully"
|
||||||
ln -s ${CLIENT_PATH}/assets ${SERVER_PUBLIC_PATH}/assets && echo "Linked assets folder successfully"
|
ln -s ${CLIENT_PATH}/assets ${SERVER_PUBLIC_PATH}/assets && echo "Linked assets folder successfully"
|
||||||
ln -s ${CLIENT_PATH}/index.html ${SERVER_VIEWS_PATH}/index.html && echo "Linked index.html successfully"
|
ln -s ${CLIENT_PATH}/index.ejs ${SERVER_VIEWS_PATH}/index.ejs && echo "Linked index.ejs successfully"
|
||||||
|
|
||||||
echo "Setup symbolic links completed successfully."
|
echo "Setup symbolic links completed successfully."
|
||||||
|
|||||||
@@ -1,13 +1,42 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import commonjs from 'vite-plugin-commonjs';
|
import commonjs from 'vite-plugin-commonjs';
|
||||||
import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
||||||
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import svgr from 'vite-plugin-svgr';
|
import svgr from 'vite-plugin-svgr';
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import browserslistToEsbuild from 'browserslist-to-esbuild';
|
import browserslistToEsbuild from 'browserslist-to-esbuild';
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
const createEjsTemplate = () => ({
|
||||||
|
name: 'create-ejs-template',
|
||||||
|
closeBundle() {
|
||||||
|
if (process.env.INDEX_FORMAT !== 'ejs') return;
|
||||||
|
|
||||||
|
const distPath = path.resolve(__dirname, 'dist');
|
||||||
|
const htmlPath = path.join(distPath, 'index.html');
|
||||||
|
|
||||||
|
if (!fs.existsSync(htmlPath)) return;
|
||||||
|
|
||||||
|
const html = fs.readFileSync(htmlPath, 'utf8');
|
||||||
|
|
||||||
|
const ejs = html
|
||||||
|
.replace(/(href|src)="\.\/([^"]+)"/g, '$1="<%- basePath %>/$2"')
|
||||||
|
.replace('</head>', " <script>window.BASE_PATH = '<%- basePath %>';</script>\n </head>");
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(distPath, 'index.ejs'), ejs);
|
||||||
|
fs.unlinkSync(htmlPath);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
base: './',
|
||||||
plugins: [
|
plugins: [
|
||||||
commonjs(),
|
commonjs(),
|
||||||
nodePolyfills({
|
nodePolyfills({
|
||||||
@@ -15,6 +44,7 @@ export default defineConfig({
|
|||||||
}),
|
}),
|
||||||
react(),
|
react(),
|
||||||
svgr(),
|
svgr(),
|
||||||
|
createEjsTemplate(),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
@@ -24,6 +54,10 @@ export default defineConfig({
|
|||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
open: true,
|
open: true,
|
||||||
|
proxy: {
|
||||||
|
'/api': 'http://localhost:1337',
|
||||||
|
'/socket.io': { target: 'http://localhost:1337', ws: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
target: browserslistToEsbuild(['>0.2%', 'not dead', 'not op_mini all']),
|
target: browserslistToEsbuild(['>0.2%', 'not dead', 'not op_mini all']),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ test
|
|||||||
.tmp
|
.tmp
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
views/index.html
|
views/index.ejs
|
||||||
|
|
||||||
data/*
|
data/*
|
||||||
|
|
||||||
|
|||||||
2
server/.gitignore
vendored
2
server/.gitignore
vendored
@@ -134,7 +134,7 @@ swagger.json
|
|||||||
dist
|
dist
|
||||||
logs
|
logs
|
||||||
|
|
||||||
views/index.html
|
views/index.ejs
|
||||||
|
|
||||||
data/*
|
data/*
|
||||||
!data/.gitkeep
|
!data/.gitkeep
|
||||||
|
|||||||
19
server/api/controllers/index.js
Normal file
19
server/api/controllers/index.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright (c) 2025 PLANKA Software GmbH
|
||||||
|
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
exits: {
|
||||||
|
success: {
|
||||||
|
responseType: 'view',
|
||||||
|
viewTemplatePath: 'index',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
fn() {
|
||||||
|
return {
|
||||||
|
basePath: sails.config.custom.baseUrlPath,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -15,7 +15,7 @@ module.exports = {
|
|||||||
|
|
||||||
fn(inputs) {
|
fn(inputs) {
|
||||||
inputs.response.clearCookie('httpOnlyToken', {
|
inputs.response.clearCookie('httpOnlyToken', {
|
||||||
path: sails.config.custom.baseUrlPath,
|
path: sails.config.custom.baseUrlPath || '/',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ module.exports = {
|
|||||||
fn(inputs) {
|
fn(inputs) {
|
||||||
inputs.response.cookie('httpOnlyToken', inputs.value, {
|
inputs.response.cookie('httpOnlyToken', inputs.value, {
|
||||||
expires: new Date(inputs.accessTokenPayload.exp * 1000),
|
expires: new Date(inputs.accessTokenPayload.exp * 1000),
|
||||||
path: sails.config.custom.baseUrlPath,
|
path: sails.config.custom.baseUrlPath || '/',
|
||||||
secure: sails.config.custom.baseUrlSecure,
|
secure: sails.config.custom.baseUrlSecure,
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: 'strict',
|
sameSite: 'strict',
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ module.exports.custom = {
|
|||||||
version,
|
version,
|
||||||
|
|
||||||
baseUrl,
|
baseUrl,
|
||||||
baseUrlPath: parsedBasedUrl.pathname,
|
baseUrlPath: parsedBasedUrl.pathname.replace(/\/$/, ''), // Remove trailing slash
|
||||||
baseUrlSecure: parsedBasedUrl.protocol === 'https:',
|
baseUrlSecure: parsedBasedUrl.protocol === 'https:',
|
||||||
|
|
||||||
maxUploadFileSize: envToBytes(process.env.MAX_UPLOAD_FILE_SIZE),
|
maxUploadFileSize: envToBytes(process.env.MAX_UPLOAD_FILE_SIZE),
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ module.exports.policies = {
|
|||||||
|
|
||||||
'_internal/update-config': ['is-authenticated', 'is-internal'],
|
'_internal/update-config': ['is-authenticated', 'is-internal'],
|
||||||
|
|
||||||
|
index: true,
|
||||||
'swagger/show': true,
|
'swagger/show': true,
|
||||||
'bootstrap/show': true,
|
'bootstrap/show': true,
|
||||||
'terms/show': true,
|
'terms/show': true,
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ module.exports.routes = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'GET /*': {
|
'GET /*': {
|
||||||
view: 'index',
|
action: 'index',
|
||||||
skipAssets: true,
|
skipAssets: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ module.exports.views = {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extension: 'html',
|
// extension: 'ejs',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user