mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-08 06:55:26 +02:00
Made uri property of page be optional
This commit is contained in:
parent
ad6582f0ca
commit
6f3d0a19a5
12 changed files with 79 additions and 44 deletions
4
public/dist/main.bundle.js
vendored
4
public/dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/main.css
vendored
2
public/dist/main.css
vendored
File diff suppressed because one or more lines are too long
|
@ -56,12 +56,14 @@ class Pages {
|
||||||
|
|
||||||
const insertedPage = await page.save();
|
const insertedPage = await page.save();
|
||||||
|
|
||||||
const alias = new Alias({
|
if (insertedPage.uri) {
|
||||||
id: insertedPage._id,
|
const alias = new Alias({
|
||||||
type: aliasTypes.PAGE
|
id: insertedPage._id,
|
||||||
}, insertedPage.uri);
|
type: aliasTypes.PAGE
|
||||||
|
}, insertedPage.uri);
|
||||||
|
|
||||||
alias.save();
|
alias.save();
|
||||||
|
}
|
||||||
|
|
||||||
return insertedPage;
|
return insertedPage;
|
||||||
} catch (validationError) {
|
} catch (validationError) {
|
||||||
|
@ -110,19 +112,17 @@ class Pages {
|
||||||
*/
|
*/
|
||||||
static async update(id, data) {
|
static async update(id, data) {
|
||||||
const page = await Model.get(id);
|
const page = await Model.get(id);
|
||||||
|
const previousUri = page.uri;
|
||||||
|
|
||||||
if (!page._id) {
|
if (!page._id) {
|
||||||
throw new Error('Page with given id does not exist');
|
throw new Error('Page with given id does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.uri.match(/^[a-z0-9'-]+$/i)) {
|
if (data.uri && !data.uri.match(/^[a-z0-9'-]+$/i)) {
|
||||||
throw new Error('Uri has unexpected characters');
|
throw new Error('Uri has unexpected characters');
|
||||||
}
|
}
|
||||||
|
|
||||||
const previousUri = page.uri;
|
|
||||||
|
|
||||||
page.data = data;
|
page.data = data;
|
||||||
|
|
||||||
const updatedPage = await page.save();
|
const updatedPage = await page.save();
|
||||||
|
|
||||||
if (updatedPage.uri !== previousUri) {
|
if (updatedPage.uri !== previousUri) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default class Writing {
|
||||||
const title = firstBlock && firstBlock.type === 'header' ? firstBlock.data.text : null;
|
const title = firstBlock && firstBlock.type === 'header' ? firstBlock.data.text : null;
|
||||||
let uri = '';
|
let uri = '';
|
||||||
|
|
||||||
if (this.nodes.uriInput) {
|
if (this.nodes.uriInput && this.nodes.uriInput.value) {
|
||||||
if (this.nodes.uriInput.value.match(/^[a-z0-9'-]+$/i)) {
|
if (this.nodes.uriInput.value.match(/^[a-z0-9'-]+$/i)) {
|
||||||
uri = this.nodes.uriInput.value;
|
uri = this.nodes.uriInput.value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,7 +127,7 @@ export default class Writing {
|
||||||
response = await response.json();
|
response = await response.json();
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
window.location.pathname = response.result.uri;
|
window.location.pathname = response.result.uri ? response.result.uri : '/page/' + response.result._id;
|
||||||
} else {
|
} else {
|
||||||
alert(response.error);
|
alert(response.error);
|
||||||
console.log('Validation failed:', response.error);
|
console.log('Validation failed:', response.error);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const {aliases: aliasesDb} = require('../utils/database/index');
|
const {aliases: aliasesDb} = require('../utils/database/index');
|
||||||
const md5 = require('../utils/md5');
|
const binaryMD5 = require('../utils/crypto');
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AliasData
|
* @typedef {Object} AliasData
|
||||||
* @property {string} _id - alias id
|
* @property {string} _id - alias id
|
||||||
* @property {string} hash - alias hash
|
* @property {string} hash - alias binary hash
|
||||||
* @property {string} type - entity type
|
* @property {string} type - entity type
|
||||||
* @property {boolean} deprecated - indicate if alias deprecated
|
* @property {boolean} deprecated - indicate if alias deprecated
|
||||||
* @property {string} id - entity id
|
* @property {string} id - entity id
|
||||||
|
@ -13,7 +13,7 @@ const md5 = require('../utils/md5');
|
||||||
/**
|
/**
|
||||||
* @class Alias
|
* @class Alias
|
||||||
* @property {string} _id - alias id
|
* @property {string} _id - alias id
|
||||||
* @property {string} hash - alias hash
|
* @property {string} hash - alias binary hash
|
||||||
* @property {string} type - entity type
|
* @property {string} type - entity type
|
||||||
* @property {boolean} deprecated - indicate if alias deprecated
|
* @property {boolean} deprecated - indicate if alias deprecated
|
||||||
* @property {string} id - entity title
|
* @property {string} id - entity title
|
||||||
|
@ -25,7 +25,7 @@ class Alias {
|
||||||
* @returns {Promise<Alias>}
|
* @returns {Promise<Alias>}
|
||||||
*/
|
*/
|
||||||
static async get(aliasName) {
|
static async get(aliasName) {
|
||||||
const hash = md5(aliasName);
|
const hash = binaryMD5(aliasName);
|
||||||
let data = await aliasesDb.findOne({hash: hash, deprecated: false});
|
let data = await aliasesDb.findOne({hash: hash, deprecated: false});
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
@ -49,7 +49,7 @@ class Alias {
|
||||||
this._id = data._id;
|
this._id = data._id;
|
||||||
}
|
}
|
||||||
if (aliasName) {
|
if (aliasName) {
|
||||||
this.hash = md5(aliasName);
|
this.hash = binaryMD5(aliasName);
|
||||||
}
|
}
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,14 +83,7 @@ class Page {
|
||||||
|
|
||||||
this.body = body || this.body;
|
this.body = body || this.body;
|
||||||
this.title = this.extractTitleFromBody();
|
this.title = this.extractTitleFromBody();
|
||||||
this.uri = uri || translateString(this.title
|
this.uri = uri || '';
|
||||||
.replace(/ /g, ' ')
|
|
||||||
.replace(/[^a-zA-Z0-9А-Яа-яЁё ]/g, ' ')
|
|
||||||
.replace(/ +/g, ' ')
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
.split(' ')
|
|
||||||
.join('-'));
|
|
||||||
this._parent = parent || this._parent;
|
this._parent = parent || this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +112,21 @@ class Page {
|
||||||
return headerBlock ? headerBlock.data.text : '';
|
return headerBlock ? headerBlock.data.text : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform title for uri
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
transformTitleToUri() {
|
||||||
|
return translateString(this.title
|
||||||
|
.replace(/ /g, ' ')
|
||||||
|
.replace(/[^a-zA-Z0-9А-Яа-яЁё ]/g, ' ')
|
||||||
|
.replace(/ +/g, ' ')
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.split(' ')
|
||||||
|
.join('-'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link given page as parent
|
* Link given page as parent
|
||||||
*
|
*
|
||||||
|
@ -186,12 +194,19 @@ class Page {
|
||||||
* @returns {Promise<string>}
|
* @returns {Promise<string>}
|
||||||
*/
|
*/
|
||||||
async composeUri(uri) {
|
async composeUri(uri) {
|
||||||
let pageWithSameUri = await Page.getByUri(uri);
|
|
||||||
let pageWithSameUriCount = 0;
|
let pageWithSameUriCount = 0;
|
||||||
|
|
||||||
while (pageWithSameUri._id && pageWithSameUri._id !== this._id) {
|
if (!this._id) {
|
||||||
pageWithSameUriCount++;
|
uri = this.transformTitleToUri();
|
||||||
pageWithSameUri = await Page.getByUri(uri + `-${pageWithSameUriCount}`);
|
}
|
||||||
|
|
||||||
|
if (uri) {
|
||||||
|
let pageWithSameUri = await Page.getByUri(uri);
|
||||||
|
|
||||||
|
while (pageWithSameUri._id && pageWithSameUri._id !== this._id) {
|
||||||
|
pageWithSameUriCount++;
|
||||||
|
pageWithSameUri = await Page.getByUri(uri + `-${pageWithSameUriCount}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pageWithSameUriCount ? uri + `-${pageWithSameUriCount}` : uri;
|
return pageWithSameUriCount ? uri + `-${pageWithSameUriCount}` : uri;
|
||||||
|
|
|
@ -5,7 +5,7 @@ const crypto = require('crypto');
|
||||||
* @param stringToHash - string to hash
|
* @param stringToHash - string to hash
|
||||||
* @returns {string} - binary hash of argument
|
* @returns {string} - binary hash of argument
|
||||||
*/
|
*/
|
||||||
module.exports = function md5(stringToHash) {
|
module.exports = function binaryMD5(stringToHash) {
|
||||||
return crypto.createHash('md5')
|
return crypto.createHash('md5')
|
||||||
.update(stringToHash)
|
.update(stringToHash)
|
||||||
.digest('binary');
|
.digest('binary');
|
|
@ -1,14 +1,24 @@
|
||||||
<div class="docs-aside">
|
<div class="docs-aside">
|
||||||
{% for firstLevelPage in menu %}
|
{% for firstLevelPage in menu %}
|
||||||
<section class="docs-aside__section">
|
<section class="docs-aside__section">
|
||||||
<a class="docs-aside__section-title" href="/{{ firstLevelPage.uri }}">
|
<a class="docs-aside__section-title"
|
||||||
|
{% if firstLevelPage.uri %}
|
||||||
|
href="/{{ firstLevelPage.uri }}"
|
||||||
|
{% else %}
|
||||||
|
href="/page/{{ firstLevelPage._id }}"
|
||||||
|
{% endif %}>
|
||||||
{{ firstLevelPage.title }}
|
{{ firstLevelPage.title }}
|
||||||
</a>
|
</a>
|
||||||
{% if firstLevelPage.children is not empty %}
|
{% if firstLevelPage.children is not empty %}
|
||||||
<ul class="docs-aside__section-list">
|
<ul class="docs-aside__section-list">
|
||||||
{% for child in firstLevelPage.children %}
|
{% for child in firstLevelPage.children %}
|
||||||
<li>
|
<li>
|
||||||
<a href="/{{ child.uri }}">
|
<a
|
||||||
|
{% if child.uri %}
|
||||||
|
href="/{{ child.uri }}"
|
||||||
|
{% else %}
|
||||||
|
href="/page/{{ child._id }}"
|
||||||
|
{% endif %}>
|
||||||
{{ child.title }}
|
{{ child.title }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -11,7 +11,12 @@
|
||||||
</li>
|
</li>
|
||||||
{% for option in config.menu %}
|
{% for option in config.menu %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{option.uri}}">
|
<a
|
||||||
|
{% if child.uri %}
|
||||||
|
href="{{ option.uri }}"
|
||||||
|
{% else %}
|
||||||
|
href="/page/{{ option._id }}"
|
||||||
|
{% endif %}>
|
||||||
{{ option.title }}
|
{{ option.title }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -7,7 +7,12 @@
|
||||||
Documentation
|
Documentation
|
||||||
</a>
|
</a>
|
||||||
{% if page._parent %}
|
{% if page._parent %}
|
||||||
<a href="{{ pageParent.uri }}" class="page__header-nav">
|
<a class="page__header-nav"
|
||||||
|
{% if pageParent.uri %}
|
||||||
|
href="/{{ pageParent.uri }}"
|
||||||
|
{% else %}
|
||||||
|
href="/page/{{ pageParent._id }}"
|
||||||
|
{% endif %}>
|
||||||
Parent {{ pageParent.title }}
|
Parent {{ pageParent.title }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -3,7 +3,7 @@ const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const config = require('../../config');
|
const config = require('../../config');
|
||||||
const Alias = require('../../src/models/alias');
|
const Alias = require('../../src/models/alias');
|
||||||
const md5 = require('../../src/utils/md5');
|
const binaryMD5 = require('../../src/utils/crypto');
|
||||||
const aliasTypes = require('../../src/constants/aliasTypes');
|
const aliasTypes = require('../../src/constants/aliasTypes');
|
||||||
const {aliases} = require('../../src/utils/database');
|
const {aliases} = require('../../src/utils/database');
|
||||||
|
|
||||||
|
@ -50,14 +50,14 @@ describe('Alias model', () => {
|
||||||
data = alias.data;
|
data = alias.data;
|
||||||
|
|
||||||
expect(data._id).to.equal(initialData._id);
|
expect(data._id).to.equal(initialData._id);
|
||||||
expect(data.hash).to.equal(md5(aliasName));
|
expect(data.hash).to.equal(binaryMD5(aliasName));
|
||||||
expect(data.type).to.equal(initialData.type);
|
expect(data.type).to.equal(initialData.type);
|
||||||
expect(data.deprecated).to.equal(false);
|
expect(data.deprecated).to.equal(false);
|
||||||
|
|
||||||
const update = {
|
const update = {
|
||||||
type: aliasTypes.PAGE,
|
type: aliasTypes.PAGE,
|
||||||
id: 'page_id',
|
id: 'page_id',
|
||||||
hash: md5('another test hash'),
|
hash: binaryMD5('another test hash'),
|
||||||
deprecated: true
|
deprecated: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ describe('Alias model', () => {
|
||||||
const {data} = foundAlias;
|
const {data} = foundAlias;
|
||||||
|
|
||||||
expect(data._id).to.equal(savedAlias._id);
|
expect(data._id).to.equal(savedAlias._id);
|
||||||
expect(data.hash).to.equal(md5(aliasName));
|
expect(data.hash).to.equal(binaryMD5(aliasName));
|
||||||
expect(data.type).to.equal(initialData.type);
|
expect(data.type).to.equal(initialData.type);
|
||||||
expect(data.deprecated).to.equal(false);
|
expect(data.deprecated).to.equal(false);
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,7 @@ describe('Alias model', () => {
|
||||||
const savedAlias = await alias.save();
|
const savedAlias = await alias.save();
|
||||||
|
|
||||||
expect(savedAlias._id).not.be.undefined;
|
expect(savedAlias._id).not.be.undefined;
|
||||||
expect(savedAlias.hash).to.equal(md5(aliasName));
|
expect(savedAlias.hash).to.equal(binaryMD5(aliasName));
|
||||||
expect(savedAlias.type).to.equal(initialData.type);
|
expect(savedAlias.type).to.equal(initialData.type);
|
||||||
expect(savedAlias.id).to.equal(initialData.id);
|
expect(savedAlias.id).to.equal(initialData.id);
|
||||||
expect(savedAlias.deprecated).to.equal(false);
|
expect(savedAlias.deprecated).to.equal(false);
|
||||||
|
@ -120,7 +120,7 @@ describe('Alias model', () => {
|
||||||
const updateData = {
|
const updateData = {
|
||||||
type: aliasTypes.PAGE,
|
type: aliasTypes.PAGE,
|
||||||
id: 'page_id',
|
id: 'page_id',
|
||||||
hash: md5('another test hash'),
|
hash: binaryMD5('another test hash'),
|
||||||
deprecated: true
|
deprecated: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ describe('Page model', () => {
|
||||||
|
|
||||||
expect(data._id).to.equal(initialData._id);
|
expect(data._id).to.equal(initialData._id);
|
||||||
expect(data.title).to.equal(initialData.body.blocks[0].data.text);
|
expect(data.title).to.equal(initialData.body.blocks[0].data.text);
|
||||||
expect(data.uri).to.equal(transformToUri(initialData.body.blocks[0].data.text));
|
expect(data.uri).to.be.empty;
|
||||||
expect(data.body).to.deep.equal(initialData.body);
|
expect(data.body).to.deep.equal(initialData.body);
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ describe('Page model', () => {
|
||||||
|
|
||||||
expect(data._id).to.equal(initialData._id);
|
expect(data._id).to.equal(initialData._id);
|
||||||
expect(data.title).to.equal(update.body.blocks[0].data.text);
|
expect(data.title).to.equal(update.body.blocks[0].data.text);
|
||||||
expect(data.uri).to.equal(transformToUri(update.body.blocks[0].data.text));
|
expect(data.uri).to.be.empty;
|
||||||
expect(data.body).to.equal(update.body);
|
expect(data.body).to.equal(update.body);
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue