Skip to content

Commit 2379e3c

Browse files
committed
Merge branch 'v.0.46'
2 parents 0f8c211 + cc10fac commit 2379e3c

File tree

212 files changed

+57735
-44034
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

212 files changed

+57735
-44034
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18.19.0
1+
v20.15.1

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[Publii](https://getpublii.com/) is a desktop-based CMS for Windows, Mac and Linux that makes creating static websites fast
1010
and hassle-free, even for beginners.
1111

12-
**Current version: 0.45.2 (build 16609)**
12+
**Current version: 0.46.0 (build 16889)**
1313

1414
## Why Publii?
1515
Unlike static-site generators that are often unwieldy and difficult to use, Publii provides an
@@ -82,4 +82,4 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
8282

8383

8484
## License
85-
Copyright (c) 2022 TidyCustoms. General Public License v3.0, read [LICENSE](https://getpublii.com/license.html) for details.
85+
Copyright (c) 2024 TidyCustoms. General Public License v3.0, read [LICENSE](https://getpublii.com/license.html) for details.

app/back-end/app-preload.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,19 @@ contextBridge.exposeInMainWorld('mainProcessAPI', {
5050
'app-post-load',
5151
'app-post-save',
5252
'app-post-cancel',
53+
'app-page-load',
54+
'app-page-save',
55+
'app-page-cancel',
56+
'app-pages-hierarchy-load',
57+
'app-pages-hierarchy-save',
5358
'app-image-upload',
5459
'app-image-upload-remove',
5560
'app-post-delete',
5661
'app-post-duplicate',
5762
'app-post-status-change',
63+
'app-page-delete',
64+
'app-page-duplicate',
65+
'app-page-status-change',
5866
'app-site-regenerate-thumbnails',
5967
'app-site-abort-regenerate-thumbnails',
6068
'app-preview-render',
@@ -67,6 +75,7 @@ contextBridge.exposeInMainWorld('mainProcessAPI', {
6775
'app-license-accept',
6876
'app-deploy-render-abort',
6977
'app-deploy-abort',
78+
'app-deploy-continue',
7079
'app-deploy-render',
7180
'app-deploy-upload',
7281
'app-sync-is-done',
@@ -115,7 +124,8 @@ contextBridge.exposeInMainWorld('mainProcessAPI', {
115124
'app-wxr-import-progress',
116125
'app-show-search-form',
117126
'block-editor-undo',
118-
'block-editor-redo'
127+
'block-editor-redo',
128+
'no-remote-files'
119129
];
120130

121131
if (validChannels.includes(channel)) {
@@ -158,6 +168,12 @@ contextBridge.exposeInMainWorld('mainProcessAPI', {
158168
'app-post-deleted',
159169
'app-post-duplicated',
160170
'app-post-status-changed',
171+
'app-page-loaded',
172+
'app-page-saved',
173+
'app-page-deleted',
174+
'app-page-duplicated',
175+
'app-page-status-changed',
176+
'app-pages-hierarchy-loaded',
161177
'app-site-regenerate-thumbnails-error',
162178
'app-site-regenerate-thumbnails-success',
163179
'app-preview-rendered',

app/back-end/app.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const url = require('url');
1414
const { screen, shell, nativeTheme, Menu, dialog, BrowserWindow } = require('electron');
1515
// Collection classes
1616
const Posts = require('./posts.js');
17+
const Pages = require('./pages.js');
1718
const Tags = require('./tags.js');
1819
const Authors = require('./authors.js');
1920
const Themes = require('./themes.js');
@@ -224,9 +225,11 @@ class App {
224225
this.db = new DBUtils(new Database(dbPath));
225226
let tags = new Tags(this, {site});
226227
let posts = new Posts(this, {site});
228+
let pages = new Pages(this, {site});
227229
let authors = new Authors(this, {site});
228230
let themes = new Themes(this, {site});
229231
let themeDir = path.join(siteDir, 'input', 'themes', themes.currentTheme(true));
232+
let themeOverridesDir = path.join(siteDir, 'input', 'themes', themes.currentTheme(true) + '-override');
230233
let themeConfig = Themes.loadThemeConfig(themeConfigPath, themeDir);
231234
let menuStructure = fs.readFileSync(menuConfigPath, 'utf8');
232235
let parsedMenuStructure = {};
@@ -240,14 +243,18 @@ class App {
240243
return {
241244
status: true,
242245
posts: posts.load(),
246+
pages: pages.load(),
243247
tags: tags.load(),
244248
authors: authors.load(),
245249
postsTags: posts.loadTagsXRef(),
246250
postsAuthors: posts.loadAuthorsXRef(),
251+
pagesAuthors: pages.loadAuthorsXRef(),
247252
postTemplates: themes.loadPostTemplates(),
253+
pageTemplates: themes.loadPageTemplates(),
248254
tagTemplates: themes.loadTagTemplates(),
249255
authorTemplates: themes.loadAuthorTemplates(),
250256
themes: themes.load(),
257+
themeHasOverrides: Utils.dirExists(themeOverridesDir),
251258
themeSettings: themeConfig,
252259
menuStructure: parsedMenuStructure,
253260
siteDir: siteDir

app/back-end/author.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
22
const path = require('path');
33
const Model = require('./model.js');
44
const Authors = require('./authors.js');
5+
const Pages = require('./pages.js');
56
const Posts = require('./posts.js');
67
const slug = require('./helpers/slug');
78
const ImageHelper = require('./helpers/image.helper.js');
@@ -23,6 +24,7 @@ class Author extends Model {
2324
this.id = parseInt(authorData.id, 10);
2425
this.authorsData = new Authors(appInstance, authorData);
2526
this.postsData = new Posts(appInstance, authorData);
27+
this.pagesData = new Pages(appInstance, authorData);
2628
this.storeMode = storeMode;
2729

2830
if (authorData.additionalData) {
@@ -133,6 +135,7 @@ class Author extends Model {
133135
message: 'author-added',
134136
authorID: this.id,
135137
postsAuthors: this.postsData.loadAuthorsXRef(),
138+
pagesAuthors: this.pagesData.loadAuthorsXRef(),
136139
authors: this.authorsData.load()
137140
};
138141
}
@@ -292,7 +295,7 @@ class Author extends Model {
292295
featuredImage = path.parse(this.additionalData.featuredImage).base;
293296
}
294297

295-
// If post is cancelled - get the previous featured image
298+
// If author is cancelled - get the previous featured image
296299
if (cancelEvent && this.id !== 0) {
297300
let featuredImageSqlQuery = `SELECT additional_data FROM authors WHERE id = @id`;
298301

@@ -313,6 +316,12 @@ class Author extends Model {
313316
authorDir = 'temp';
314317
}
315318

319+
let imagesInAuthorViewSettings = [];
320+
321+
if (this.additionalData && this.additionalData.viewConfig) {
322+
imagesInAuthorViewSettings = Object.values(this.additionalData.viewConfig).filter(item => item.type === "image").map(item => item.value);
323+
}
324+
316325
// Iterate through images
317326
for (let i in images) {
318327
let imagePath = images[i];
@@ -323,7 +332,14 @@ class Author extends Model {
323332
continue;
324333
}
325334

326-
if ((cancelEvent && authorDir === 'temp') || featuredImage !== imagePath) {
335+
// Remove files which does not exist as featured image and authorViewSettings
336+
if(
337+
(cancelEvent && authorDir === 'temp') ||
338+
(
339+
imagesInAuthorViewSettings.indexOf(imagePath) === -1 &&
340+
featuredImage !== imagePath
341+
)
342+
) {
327343
try {
328344
fs.unlinkSync(fullPath);
329345
} catch(e) {
@@ -337,8 +353,11 @@ class Author extends Model {
337353
// Clean unused avatar images
338354
let themesHelper = new Themes(this.application, { site: this.site });
339355
let themeConfigPath = path.join(this.application.sitesDir, this.site, 'input', 'config', 'theme.config.json');
340-
let themeConfigString = fs.readFileSync(themeConfigPath, 'utf8');
341-
themesHelper.checkAndCleanImages(themeConfigString);
356+
357+
if (fs.fileExists(themeConfigPath)) {
358+
let themeConfigString = fs.readFileSync(themeConfigPath, 'utf8');
359+
themesHelper.checkAndCleanImages(themeConfigString);
360+
}
342361
}
343362

344363
/*

app/back-end/builddata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"version": "0.45.2",
3-
"build": 16609
2+
"version": "0.46.0",
3+
"build": 16889
44
}

app/back-end/events/_modules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
AppEvents: require('./app.js'),
66
CreditsEvents: require('./credits'),
77
ImageUploaderEvents: require('./image-uploader.js'),
8+
PageEvents: require('./page.js'),
89
PostEvents: require('./post.js'),
910
SiteEvents: require('./site.js'),
1011
TagEvents: require('./tag.js'),

app/back-end/events/deploy.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ class DeployEvents {
6565
event.sender.send('app-deploy-aborted', true);
6666
});
6767

68+
ipcMain.on('app-deploy-continue', function() {
69+
if (self.deploymentProcess) {
70+
try {
71+
self.deploymentProcess.send({
72+
type: 'continue-sync'
73+
});
74+
75+
self.deploymentProcess = false;
76+
} catch(e) {
77+
console.log(e);
78+
self.deploymentProcess = false;
79+
}
80+
}
81+
});
82+
6883
ipcMain.on('app-deploy-test', async (event, data) => {
6984
try {
7085
await this.testConnection(data.deploymentConfig, data.siteName, data.uuid);
@@ -162,7 +177,7 @@ class DeployEvents {
162177
});
163178

164179
this.deploymentProcess.on('message', function(data) {
165-
if(data.type === 'web-contents') {
180+
if (data.type === 'web-contents') {
166181
if(data.value) {
167182
self.app.mainWindow.webContents.send(data.message, data.value);
168183
} else {

app/back-end/events/page.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const ipcMain = require('electron').ipcMain;
4+
const Page = require('../page.js');
5+
6+
/*
7+
* Events for the IPC communication regarding pages
8+
*/
9+
10+
class PageEvents {
11+
constructor(appInstance) {
12+
this.app = appInstance;
13+
14+
// Load
15+
ipcMain.on('app-page-load', function (event, pageData) {
16+
let page = new Page(appInstance, pageData);
17+
let result = page.load();
18+
event.sender.send('app-page-loaded', result);
19+
});
20+
21+
// Save
22+
ipcMain.on('app-page-save', function (event, pageData) {
23+
let page = new Page(appInstance, pageData);
24+
let result = page.save();
25+
event.sender.send('app-page-saved', result);
26+
});
27+
28+
// Delete
29+
ipcMain.on('app-page-delete', function (event, pageData) {
30+
let result = false;
31+
32+
for(let i = 0; i < pageData.ids.length; i++) {
33+
let page = new Page(appInstance, {
34+
site: pageData.site,
35+
id: pageData.ids[i]
36+
});
37+
38+
result = page.delete();
39+
}
40+
41+
event.sender.send('app-page-deleted', result);
42+
});
43+
44+
// Delete
45+
ipcMain.on('app-page-duplicate', function (event, pageData) {
46+
let result = false;
47+
48+
for(let i = 0; i < pageData.ids.length; i++) {
49+
let page = new Page(appInstance, {
50+
site: pageData.site,
51+
id: pageData.ids[i]
52+
});
53+
54+
result = page.duplicate();
55+
}
56+
57+
event.sender.send('app-page-duplicated', result);
58+
});
59+
60+
// Status change
61+
ipcMain.on('app-page-status-change', function (event, pageData) {
62+
let result = false;
63+
64+
for(let i = 0; i < pageData.ids.length; i++) {
65+
let page = new Page(appInstance, {
66+
site: pageData.site,
67+
id: pageData.ids[i]
68+
});
69+
70+
result = page.changeStatus(pageData.status, pageData.inverse);
71+
}
72+
73+
event.sender.send('app-page-status-changed', result);
74+
});
75+
76+
// Cancelled edition
77+
ipcMain.on('app-page-cancel', function(event, pageData) {
78+
let page = new Page(appInstance, pageData);
79+
let result = page.checkAndCleanImages(true);
80+
event.sender.send('app-page-cancelled', result);
81+
});
82+
83+
// Load pages hierarchy
84+
ipcMain.on('app-pages-hierarchy-load', (event, siteName) => {
85+
let pagesFile = path.join(this.app.sitesDir, siteName, 'input', 'config', 'pages.config.json');
86+
87+
if (fs.existsSync(pagesFile)) {
88+
event.sender.send('app-pages-hierarchy-loaded', JSON.parse(fs.readFileSync(pagesFile, { encoding: 'utf8' })));
89+
} else {
90+
event.sender.send('app-pages-hierarchy-loaded', null);
91+
}
92+
});
93+
94+
// Save pages hierarchy
95+
ipcMain.on('app-pages-hierarchy-save', (event, pagesData) => {
96+
let pagesFile = path.join(this.app.sitesDir, pagesData.siteName, 'input', 'config', 'pages.config.json');
97+
fs.writeFileSync(pagesFile, JSON.stringify(pagesData.hierarchy, null, 4), { encoding: 'utf8' });
98+
});
99+
}
100+
}
101+
102+
module.exports = PageEvents;

app/back-end/events/preview.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class PreviewEvents {
8888
errorDesc = data.result[0].message + "\n\n" + data.result[0].desc;
8989
}
9090

91+
if (typeof errorDesc === 'object') {
92+
errorDesc = errorDesc.translation;
93+
}
94+
9195
event.sender.send('app-preview-render-error', {
9296
message: [{
9397
message: errorTitle,
@@ -170,7 +174,7 @@ class PreviewEvents {
170174

171175
url = path.join(basePath, 'index.html');
172176

173-
if (mode === 'tag' || mode === 'post' || mode === 'author') {
177+
if (mode === 'tag' || mode === 'post' || mode === 'page' || mode === 'author') {
174178
url = path.join(basePath, 'preview.html');
175179
}
176180

0 commit comments

Comments
 (0)