mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-09 07:25:21 +02:00
Added abiltity to support few pages with same title
This commit is contained in:
parent
88172e7d34
commit
77f671b052
8 changed files with 185 additions and 34 deletions
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"blueimp-md5": "^2.10.0",
|
||||
"body-parser": "latest",
|
||||
"codex.editor": "^2.1.3",
|
||||
"codex.editor.header": "^2.0.5",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const Model = require('../models/page');
|
||||
const Alias = require('../models/alias');
|
||||
const aliasTypes = require('../constants/aliasTypes');
|
||||
const getHashFromString = require('../utils/hash');
|
||||
const md5 = require('blueimp-md5');
|
||||
|
||||
/**
|
||||
* @class Pages
|
||||
|
@ -53,20 +53,18 @@ class Pages {
|
|||
static async insert(data) {
|
||||
try {
|
||||
Pages.validate(data);
|
||||
console.log('data', data);
|
||||
const page = new Model(data);
|
||||
|
||||
const pagePromise = page.save();
|
||||
const updatedPage = await pagePromise;
|
||||
|
||||
pagePromise.then(() => {
|
||||
const alias = new Alias({
|
||||
id: page._id,
|
||||
id: updatedPage._id,
|
||||
type: aliasTypes.PAGE,
|
||||
hash: getHashFromString(page.uri).toString()
|
||||
hash: md5(updatedPage.uri)
|
||||
});
|
||||
|
||||
alias.save();
|
||||
});
|
||||
|
||||
return pagePromise;
|
||||
} catch (validationError) {
|
||||
|
@ -119,10 +117,22 @@ class Pages {
|
|||
if (!page._id) {
|
||||
throw new Error('Page with given id does not exist');
|
||||
}
|
||||
const oldAlias = page.uri;
|
||||
|
||||
page.data = data;
|
||||
const pagePromise = page.save();
|
||||
const updatedPage = await pagePromise;
|
||||
|
||||
return page.save();
|
||||
Alias.markAsDeprecated(oldAlias);
|
||||
|
||||
const alias = new Alias({
|
||||
id: updatedPage._id,
|
||||
type: aliasTypes.PAGE,
|
||||
hash: md5(updatedPage.uri)
|
||||
});
|
||||
|
||||
alias.save();
|
||||
return pagePromise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
const {aliases: aliasesDb} = require('../utils/database/index');
|
||||
const getHashFromString = require('../utils/hash');
|
||||
|
||||
const md5 = require('blueimp-md5');
|
||||
/**
|
||||
* @typedef {Object} AliasData
|
||||
* @property {string} _id - alias id
|
||||
* @property {string} hash - alias hash
|
||||
* @property {string} type - entity type
|
||||
* @property {boolean} deprecated - indicate if alias deprecated
|
||||
* @property {string} id - entity id
|
||||
*
|
||||
*/
|
||||
|
@ -15,6 +15,7 @@ const getHashFromString = require('../utils/hash');
|
|||
* @property {string} _id - alias id
|
||||
* @property {string} hash - alias hash
|
||||
* @property {string} type - entity type
|
||||
* @property {boolean} deprecated - indicate if alias deprecated
|
||||
* @property {string} id - entity title
|
||||
*/
|
||||
class Alias {
|
||||
|
@ -24,7 +25,7 @@ class Alias {
|
|||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
static async get(aliasName) {
|
||||
const hash = getHashFromString(aliasName).toString();
|
||||
const hash = md5(aliasName);
|
||||
const data = await aliasesDb.findOne({hash});
|
||||
|
||||
return new Alias(data);
|
||||
|
@ -42,25 +43,65 @@ class Alias {
|
|||
if (data._id) {
|
||||
this._id = data._id;
|
||||
}
|
||||
this.id = data.id;
|
||||
this.type = data.type;
|
||||
this.hash = data.hash;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update page data in the database
|
||||
* Save or update alias data in the database
|
||||
*
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
async save() {
|
||||
if (!this._id) {
|
||||
const insertedRow = await aliasesDb.insert({id: this.id, type: this.type, hash: this.hash});
|
||||
const insertedRow = await aliasesDb.insert(this.data);
|
||||
} else {
|
||||
await aliasesDb.update({_id: this._id}, this.data);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AliasData object fields to internal model fields
|
||||
*
|
||||
* @param {AliasData} aliasData
|
||||
*/
|
||||
set data(aliasData) {
|
||||
const {id, type, hash, deprecated} = aliasData;
|
||||
|
||||
this.id = id || this.id;
|
||||
this.type = type || this.type;
|
||||
this.hash = hash || this.hash;
|
||||
this.deprecated = deprecated || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return AliasData object
|
||||
*
|
||||
* @returns {AliasData}
|
||||
*/
|
||||
get data() {
|
||||
return {
|
||||
_id: this._id,
|
||||
id: this.id,
|
||||
type: this.type,
|
||||
hash: this.hash,
|
||||
deprecated: this.deprecated
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark alias as deprecated
|
||||
* @param {string} aliasName - alias of entity
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
static async markAsDeprecated(aliasName) {
|
||||
const alias = await Alias.get(aliasName);
|
||||
|
||||
alias.deprecated = true;
|
||||
|
||||
return alias.save();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Alias;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const {pages: pagesDb} = require('../utils/database/index');
|
||||
const {aliases: aliasesDb} = require('../utils/database/index');
|
||||
const translateString = require('../utils/translation');
|
||||
|
||||
/**
|
||||
* @typedef {Object} PageData
|
||||
|
@ -33,6 +34,17 @@ class Page {
|
|||
return new Page(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of page with given uri
|
||||
* @param {string} uri - page uri
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
static async getByUri(uri) {
|
||||
const data = await pagesDb.findOne({uri});
|
||||
|
||||
return new Page(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all pages which match passed query object
|
||||
*
|
||||
|
@ -72,7 +84,7 @@ class Page {
|
|||
|
||||
this.body = body || this.body;
|
||||
this.title = this.extractTitleFromBody();
|
||||
this.uri = uri || this.title.toLowerCase().split(' ').join('-');
|
||||
this.uri = uri || translateString(this.title.toLowerCase()).split(' ').join('-');
|
||||
this._parent = parent || this._parent;
|
||||
}
|
||||
|
||||
|
@ -136,15 +148,29 @@ class Page {
|
|||
* @returns {Promise<Page>}
|
||||
*/
|
||||
async save() {
|
||||
let newUri = translateString(this.title.toLowerCase()).split(' ').join('-');
|
||||
let pageWithSameUri = await Page.getByUri(newUri);
|
||||
let pageWithSameUriCount = 0;
|
||||
|
||||
while (pageWithSameUri._id) {
|
||||
pageWithSameUriCount++;
|
||||
pageWithSameUri = await Page.getByUri(newUri + `-${pageWithSameUriCount}`);
|
||||
}
|
||||
|
||||
this.uri = pageWithSameUriCount ? newUri + `-${pageWithSameUriCount}` : newUri;
|
||||
|
||||
if (!this._id) {
|
||||
const insertedRow = await pagesDb.insert({
|
||||
...this.data,
|
||||
uri: this.title.toLowerCase().split(' ').join('-')
|
||||
uri: this.uri
|
||||
});
|
||||
|
||||
this._id = insertedRow._id;
|
||||
} else {
|
||||
await pagesDb.update({_id: this._id}, this.data);
|
||||
await pagesDb.update({_id: this._id}, {
|
||||
...this.data,
|
||||
uri: this.uri
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* Function for getting hash from stringToHash
|
||||
*
|
||||
* @param stringToHash - stringToHash to encode
|
||||
* @returns {string} - hash index
|
||||
*/
|
||||
module.exports = function getHashFromString(stringToHash) {
|
||||
return stringToHash.split('').reduce((previousHashValue, currentChar) =>
|
||||
(((previousHashValue << 5) - previousHashValue) + currentChar.charCodeAt(0)) | 0, 0);
|
||||
};
|
78
src/utils/translation.js
Normal file
78
src/utils/translation.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
const translationTable = {
|
||||
'а': 'a',
|
||||
'б': 'b',
|
||||
'в': 'v',
|
||||
'г': 'g',
|
||||
'д': 'd',
|
||||
'е': 'e',
|
||||
'ж': 'g',
|
||||
'з': 'z',
|
||||
'и': 'i',
|
||||
'й': 'y',
|
||||
'к': 'k',
|
||||
'л': 'l',
|
||||
'м': 'm',
|
||||
'н': 'n',
|
||||
'о': 'o',
|
||||
'п': 'p',
|
||||
'р': 'r',
|
||||
'с': 's',
|
||||
'т': 't',
|
||||
'у': 'u',
|
||||
'ф': 'f',
|
||||
'ы': 'i',
|
||||
'э': 'e',
|
||||
'А': 'A',
|
||||
'Б': 'B',
|
||||
'В': 'V',
|
||||
'Г': 'G',
|
||||
'Д': 'D',
|
||||
'Е': 'E',
|
||||
'Ж': 'G',
|
||||
'З': 'Z',
|
||||
'И': 'I',
|
||||
'Й': 'Y',
|
||||
'К': 'K',
|
||||
'Л': 'L',
|
||||
'М': 'M',
|
||||
'Н': 'N',
|
||||
'О': 'O',
|
||||
'П': 'P',
|
||||
'Р': 'R',
|
||||
'С': 'S',
|
||||
'Т': 'T',
|
||||
'У': 'U',
|
||||
'Ф': 'F',
|
||||
'Ы': 'I',
|
||||
'Э': 'E',
|
||||
'ё': 'yo',
|
||||
'х': 'h',
|
||||
'ц': 'ts',
|
||||
'ч': 'ch',
|
||||
'ш': 'sh',
|
||||
'щ': 'shch',
|
||||
'ъ': '',
|
||||
'ь': '',
|
||||
'ю': 'yu',
|
||||
'я': 'ya',
|
||||
'Ё': 'YO',
|
||||
'Х': 'H',
|
||||
'Ц': 'TS',
|
||||
'Ч': 'CH',
|
||||
'Ш': 'SH',
|
||||
'Щ': 'SHCH',
|
||||
'Ъ': '',
|
||||
'Ь': '',
|
||||
'Ю': 'YU',
|
||||
'Я': 'YA'
|
||||
};
|
||||
/**
|
||||
* Function to translate string
|
||||
*
|
||||
* @param string - string to translate
|
||||
* @returns {string} - translated string
|
||||
*/
|
||||
|
||||
module.exports = function translateString(string) {
|
||||
return string.replace(/[А-яёЁ]/g, (char) => translationTable[char] || char);
|
||||
};
|
|
@ -8,7 +8,7 @@
|
|||
<ul class="docs-aside__section-list">
|
||||
{% for child in firstLevelPage.children %}
|
||||
<li>
|
||||
<a href="/page/{{ child._id }}">
|
||||
<a href="{{ child.uri }}">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1162,6 +1162,11 @@ bluebird@^3.5.1:
|
|||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
|
||||
integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
|
||||
|
||||
blueimp-md5@^2.10.0:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.10.0.tgz#02f0843921f90dca14f5b8920a38593201d6964d"
|
||||
integrity sha512-EkNUOi7tpV68TqjpiUz9D9NcT8um2+qtgntmMbi5UKssVX2m/2PLqotcric0RE63pB3HPN/fjf3cKHN2ufGSUQ==
|
||||
|
||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
|
||||
version "4.11.8"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue