Skip to content

Commit

Permalink
Add support for images in controlpanels.
Browse files Browse the repository at this point in the history
Add preview link support.
Add block types index.
  • Loading branch information
robgietema committed Dec 1, 2024
1 parent febd56a commit 793f49c
Show file tree
Hide file tree
Showing 21 changed files with 420 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
- Add multilingual support @robgietema
- Add converter from plone.exportimport @robgietema
- Add Nick endpoint @robgietema
- Add support for images in controlpanels @robgietema
- Add preview link support @robgietema
- Add block types index @robgietema

### Bugfix

Expand Down Expand Up @@ -62,6 +65,7 @@
- Fix delete within transaction @robgietema
- Fix keywords endpoint @robgietema
- Fix supported languages endpoint @robgietema
- Fix site logo @robgietema

### Internal

Expand Down
33 changes: 33 additions & 0 deletions packages/nick-blog/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@robgietema/nick-blog",
"description": "Blog for Nick",
"maintainers": [
{
"name": "Rob Gietema",
"email": "[email protected]",
"url": "https://robgietema.nl"
}
],
"license": "MIT",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "[email protected]:robgietema/nick.git"
},
"publishConfig": {
"access": "public"
},
"bugs": {
"url": "https://github.com/robgietema/nick/issues",
"email": "[email protected]"
},
"homepage": "https://nickcms.org",
"keywords": [
"nick",
"blog",
"cms"
],
"engines": {
"node": "^20"
}
}
6 changes: 6 additions & 0 deletions packages/nick-blog/src/profiles/default/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "@robgietema/nick-blog:default",
"title": "Blog Default",
"description": "Blog functionality of Nick",
"version": 1000
}
22 changes: 22 additions & 0 deletions packages/nick-blog/src/profiles/default/types/author.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "Author",
"title:i18n": "Blog Author",
"description:i18n": "A Blog Author",
"global_allow": true,
"filter_content_types": false,
"allowed_content_types": [],
"schema": {
"behaviors": [
"dublin_core",
"dates",
"blocks",
"versioning",
"short_name",
"id_from_title",
"folderish",
"exclude_from_nav",
"preview_image_link"
]
},
"workflow": "simple_publication_workflow"
}
22 changes: 22 additions & 0 deletions packages/nick-blog/src/profiles/default/types/blogfolder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "BlogFolder",
"title:i18n": "Blog Folder",
"description:i18n": "A folderish content item representing a Blog",
"global_allow": true,
"filter_content_types": true,
"allowed_content_types": ["Page", "File", "Image", "Post"],
"schema": {
"behaviors": [
"dublin_core",
"dates",
"blocks",
"versioning",
"short_name",
"id_from_title",
"folderish",
"exclude_from_nav",
"preview_image_link"
]
},
"workflow": "simple_publication_workflow"
}
22 changes: 22 additions & 0 deletions packages/nick-blog/src/profiles/default/types/post.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "Post",
"title:i18n": "Blog Post",
"description:i18n": "A Blog Post",
"global_allow": true,
"filter_content_types": true,
"allowed_content_types": ["File", "Image"],
"schema": {
"behaviors": [
"dublin_core",
"dates",
"blocks",
"versioning",
"short_name",
"id_from_title",
"folderish",
"exclude_from_nav",
"preview_image_link"
]
},
"workflow": "simple_publication_workflow"
}
22 changes: 22 additions & 0 deletions packages/nick-blog/src/profiles/default/types/tag.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "BlogTag",
"title:i18n": "Blog Tag",
"description:i18n": "A Blog Tag",
"global_allow": true,
"filter_content_types": false,
"allowed_content_types": [],
"schema": {
"behaviors": [
"dublin_core",
"dates",
"blocks",
"versioning",
"short_name",
"id_from_title",
"folderish",
"exclude_from_nav",
"preview_image_link"
]
},
"workflow": "simple_publication_workflow"
}
86 changes: 77 additions & 9 deletions scripts/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
* @module scripts/convert
*/

import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
import {
existsSync,
copyFileSync,
mkdirSync,
readFileSync,
rmSync,
writeFileSync,
} from 'fs';
import { sync as glob } from 'glob';
import { endsWith, keys, map } from 'lodash';
import { endsWith, keys, last, map } from 'lodash';
import { v4 as uuid } from 'uuid';

/**
* Read file
Expand Down Expand Up @@ -75,22 +83,83 @@ const convertGroups = (groups, path) => {
const convertDocuments = (input, path) => {
console.log('Converting documents...');

// Remove folder if exists
if (existsSync(`${path}/documents`)) {
rmSync(`${path}/documents`, { recursive: true });
}

// Create folder
mkdirSync(`${path}/documents`);
mkdirSync(`${path}/documents/images`);

map(glob(`${input}/content/**/*.json`), (filename) => {
if (endsWith(filename, '__metadata__.json')) {
return;
}
let document = JSON.parse(readFileSync(filename, 'utf8'));

// Set correct uuid field
document.uuid = document.UID;
delete document.UID;

// Convert types
if (document['@type'] === 'Plone Site') {
document['@type'] = 'Site';
document.uuid = uuid();
}
if (document['@type'] === 'LRF') {
document['@type'] = 'Languageroot';
}
if (document['@type'] === 'Document') {
document['@type'] = 'Page';
}
if (document['@type'] === 'LIF') {
document['@type'] = 'Folder';
}
document.type = document['@type'];
delete document['@type'];

// Remove fields
delete document.version;

// Fix language
if (document.language === '##DEFAULT##') {
document.language = 'en';
}

// Fix images
if (document.type === 'Image') {
const file = last(document.image.blob_path.split('/')).replace(' ', '_');
mkdirSync(`${path}/documents/images/${document.uuid}`);
copyFileSync(
`${input}/content/${document.image.blob_path}`,
`${path}/documents/images/${document.uuid}/${file}`,
);
document.image = `/images/${document.uuid}/${file}`;
}

// Convert to string
let json = JSON.stringify(document);
json = json.replaceAll(/\"[^"]*resolveuid\/([^"]*)\"/g, (result, uuid) => {
const targetfile = `${input}/content/${uuid}/data.json`;
if (existsSync(targetfile)) {
const target = JSON.parse(
readFileSync(`${input}/content/${uuid}/data.json`, 'utf8'),
);
return `"${target['@id'].replace('.', '-')}"`;
} else {
console.log(`Not found: ${targetfile}`);
}
return `"${uuid}"`;
});

const output =
document['@id'] === '/Plone'
? `${path}/documents/_root.json`
: `${path}/documents/${document['@id'].replaceAll('.', '-').replaceAll('/', '.').substring(1)}.json`;

// Write files
writeFileSync(
`${path}/documents/${document['@id'].replaceAll('.', '-').replaceAll('/', '.').substring(1)}.json`,
JSON.stringify(document),
);
writeFileSync(output, json);
});

console.log('done!');
Expand All @@ -113,10 +182,9 @@ async function main() {
const outputfolder = process.argv[3];

// Create output folder
if (existsSync(outputfolder)) {
rmSync(outputfolder, { recursive: true });
if (!existsSync(outputfolder)) {
mkdirSync(outputfolder, { recursive: true });
}
mkdirSync(outputfolder, { recursive: true });

// Convert principals
if (existsSync(`${inputfolder}/principals.json`)) {
Expand Down
21 changes: 17 additions & 4 deletions src/helpers/content/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function handleFiles(json, type, profile) {
fields[field] = {
data: readProfileFile(profile, fields[field]),
encoding: 'base64',
'content-type': mime.lookup(`${profile}/documents${fields[field]}`),
'content-type': mime.lookup(`${profile}${fields[field]}`),
filename: last(fields[field].split('/')),
};
}
Expand Down Expand Up @@ -83,7 +83,7 @@ export async function handleImages(json, type, profile) {
fields[field] = {
data: readProfileFile(profile, fields[field]),
encoding: 'base64',
'content-type': mime.lookup(`${profile}/documents${fields[field]}`),
'content-type': mime.lookup(`${profile}${fields[field]}`),
filename: last(fields[field].split('/')),
};
}
Expand Down Expand Up @@ -118,10 +118,9 @@ export async function handleImages(json, type, profile) {
* @method handleRelationLists
* @param {Object} json Current json object.
* @param {Object} type Type object.
* @param {string} profile Path of the profile.
* @returns {Object} Fields with uuid info.
*/
export async function handleRelationLists(json, type, profile) {
export async function handleRelationLists(json, type) {
// Make a copy of the json data
const fields = { ...json };

Expand All @@ -141,3 +140,17 @@ export async function handleRelationLists(json, type, profile) {
// Return new field data
return fields;
}

/**
* Handle block references
* @method handleBlockReferences
* @param {Object} json Current json object.
* @returns {Object} Json with references expanded.
*/
export async function handleBlockReferences(json) {
// Make a copy of the json data
const output = { ...json };

// Return new json data
return output;
}
18 changes: 11 additions & 7 deletions src/helpers/fs/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function readFile(uuid) {
* @returns {string} Base64 string of the file
*/
export function readProfileFile(profile, path) {
const file = `${profile}/documents${path}`;
const file = `${profile}${path}`;
if (!existsSync(file)) {
throw `Can not read file: ${file}`;
}
Expand Down Expand Up @@ -118,12 +118,16 @@ export async function writeImage(data, encoding) {
// Write scales
await mapAsync(keys(config.imageScales), async (scale) => {
const scaleId = uuid();
const scaleImage = sharp(buffer)
.rotate()
.resize(...config.imageScales[scale], {
fit: 'inside',
});
await scaleImage.toFile(`${config.blobsDir}/${scaleId}`);
if ((await image.metadata()).format === 'svg') {
writeFileSync(`${config.blobsDir}/${scaleId}`, buffer);
} else {
const scaleImage = sharp(buffer)
.rotate()
.resize(...config.imageScales[scale], {
fit: 'inside',
});
await scaleImage.toFile(`${config.blobsDir}/${scaleId}`);
}
const [scaleWidth, scaleHeight] = getScaleDimensions(
width,
height,
Expand Down
18 changes: 18 additions & 0 deletions src/models/controlpanel/controlpanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @module models/controlpanel/controlpanel
*/

import { compact, keys, map } from 'lodash';
import { getRootUrl, translateSchema } from '../../helpers';
import { Model } from '../../models';

Expand Down Expand Up @@ -32,4 +33,21 @@ export class Controlpanel extends Model {
? { ...json, data: this.data, schema: translateSchema(this.schema, req) }
: json;
}

/**
* Get factory fields.
* @method getFactoryFields
* @static
* @param {string} factory Factory field.
* @returns {Array} Array of fields with given factory.
*/
getFactoryFields(factory) {
const properties = this.schema.properties;

// Get factory fields
const factoryFields = map(keys(properties), (property) =>
properties[property].factory === factory ? property : false,
);
return compact(factoryFields);
}
}
Loading

0 comments on commit 793f49c

Please sign in to comment.