Skip to content

Commit 072ba65

Browse files
authored
Merge pull request #596 from thmarx/cleanups
Cleanups
2 parents bb7d3e0 + 4160ea3 commit 072ba65

14 files changed

Lines changed: 209 additions & 67 deletions

File tree

cms-content/src/main/java/com/condation/cms/content/DefaultContentRenderer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import com.condation.cms.content.pipeline.ContentPipelineFactory;
5050
import com.condation.cms.content.views.model.View;
5151
import com.condation.cms.api.content.MapAccess;
52-
import com.condation.cms.api.utils.HTTPUtil;
5352
import com.condation.cms.extensions.hooks.DBHooks;
5453
import com.condation.cms.extensions.hooks.TemplateHooks;
5554
import com.condation.cms.content.template.functions.LinkFunction;

cms-templates/src/main/java/com/condation/cms/templates/CMSTemplateEngine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private JexlEngine createJexlEngine() {
6161
builder
6262
.cache(512)
6363
.safe(false)
64-
.strict(true)
64+
.strict(false)
6565
.silent(false)
6666
.debug(false);
6767
} else {

cms-templates/src/main/java/com/condation/cms/templates/DefaultTemplate.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.condation.cms.templates.functions.JexlTemplateFunction;
2626
import com.condation.cms.templates.functions.impl.DateFunction;
2727
import com.condation.cms.templates.functions.impl.NodeFunction;
28+
import com.condation.cms.templates.functions.impl.NodeMetaFunction;
2829
import com.condation.cms.templates.parser.ASTNode;
2930
import com.condation.cms.templates.renderer.Renderer;
3031
import com.condation.cms.templates.renderer.ScopeStack;
@@ -75,6 +76,7 @@ private ScopeStack createScope (Map<String, Object> context, DynamicConfiguratio
7576
var scope = new ScopeStack(context);
7677
scope.setVariable(DateFunction.NAME, new JexlTemplateFunction(new DateFunction()));
7778
scope.setVariable(NodeFunction.NAME, new JexlTemplateFunction(new NodeFunction(dynamicConfiguration.requestContext())));
79+
scope.setVariable(NodeMetaFunction.NAME, new JexlTemplateFunction(new NodeMetaFunction(dynamicConfiguration.requestContext())));
7880

7981
dynamicConfiguration.templateFunctions().forEach(tf -> {
8082
scope.setVariable(tf.name(), new JexlTemplateFunction(tf));
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.condation.cms.templates.functions.impl;
2+
3+
/*-
4+
* #%L
5+
* cms-templates
6+
* %%
7+
* Copyright (C) 2023 - 2026 CondationCMS
8+
* %%
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public
20+
* License along with this program. If not, see
21+
* <http://www.gnu.org/licenses/gpl-3.0.html>.
22+
* #L%
23+
*/
24+
25+
import com.condation.cms.api.content.MapAccess;
26+
import com.condation.cms.api.db.ContentNode;
27+
import com.condation.cms.api.db.DB;
28+
import com.condation.cms.api.db.cms.ReadOnlyFile;
29+
import com.condation.cms.api.feature.features.InjectorFeature;
30+
import com.condation.cms.api.request.RequestContext;
31+
import com.condation.cms.api.utils.PathUtil;
32+
import com.condation.cms.core.content.ContentResolvingStrategy;
33+
import com.condation.cms.templates.functions.TemplateFunction;
34+
import java.util.HashMap;
35+
import java.util.Map;
36+
import java.util.Optional;
37+
import lombok.RequiredArgsConstructor;
38+
39+
/**
40+
*
41+
* @author thmar
42+
*/
43+
@RequiredArgsConstructor
44+
public abstract class AbstractNodeFunction implements TemplateFunction {
45+
protected final RequestContext requestContext;
46+
47+
protected void extendMap (Map<String, Object> node, ReadOnlyFile contentFile) {
48+
49+
}
50+
51+
@Override
52+
public Object invoke(Object... params) {
53+
54+
if (params == null || params.length == 0 ) {
55+
return null;
56+
}
57+
if (!(params[0] instanceof String)) {
58+
return null;
59+
}
60+
String uri = ContentResolvingStrategy.uriToPath((String)params[0]);
61+
62+
var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
63+
var contentBase = db.getReadOnlyFileSystem().contentBase();
64+
65+
Optional<ReadOnlyFile> contentFileOpt = ContentResolvingStrategy.resolve(uri, db);
66+
67+
if (contentFileOpt.isPresent()) {
68+
var node_uri = PathUtil.toRelativeFile(contentFileOpt.get(), contentBase);
69+
final Optional<ContentNode> nodeByUri = db.getContent().byUri(node_uri);
70+
if (nodeByUri.isPresent()) {
71+
var node = new HashMap<String, Object>();
72+
node.put("meta", new MapAccess(nodeByUri.get().data()));
73+
node.put("uri", PathUtil.toURL(contentFileOpt.get(), contentBase));
74+
75+
extendMap(node, contentFileOpt.get());
76+
77+
return node;
78+
}
79+
}
80+
81+
return null;
82+
}
83+
}

cms-templates/src/main/java/com/condation/cms/templates/functions/impl/NodeFunction.java

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,61 +22,43 @@
2222
* #L%
2323
*/
2424

25-
import com.condation.cms.api.content.MapAccess;
2625
import com.condation.cms.api.db.ContentNode;
2726
import com.condation.cms.api.db.DB;
2827
import com.condation.cms.api.db.cms.ReadOnlyFile;
29-
import com.condation.cms.api.feature.features.DBFeature;
3028
import com.condation.cms.api.feature.features.InjectorFeature;
31-
import com.condation.cms.api.feature.features.RequestFeature;
3229
import com.condation.cms.api.request.RequestContext;
33-
import com.condation.cms.api.utils.PathUtil;
34-
import com.condation.cms.core.content.ContentResolvingStrategy;
35-
import com.condation.cms.templates.functions.TemplateFunction;
36-
import java.util.Date;
30+
import com.condation.cms.content.ContentRenderer;
31+
import com.condation.cms.content.Section;
32+
import java.io.IOException;
33+
import java.util.List;
3734
import java.util.Map;
38-
import java.util.Optional;
39-
import lombok.RequiredArgsConstructor;
35+
import lombok.extern.slf4j.Slf4j;
4036

4137
/**
4238
*
4339
* @author thorstenmarx
4440
*/
45-
@RequiredArgsConstructor
46-
public class NodeFunction implements TemplateFunction {
41+
@Slf4j
42+
public class NodeFunction extends AbstractNodeFunction {
4743

4844
public static final String NAME = "select_node";
49-
50-
private final RequestContext requestContext;
45+
46+
public NodeFunction(RequestContext requestContext) {
47+
super(requestContext);
48+
}
5149

5250
@Override
53-
public Object invoke(Object... params) {
54-
55-
if (params == null || params.length == 0 ) {
56-
return null;
57-
}
58-
if (!(params[0] instanceof String)) {
59-
return null;
60-
}
61-
String uri = ContentResolvingStrategy.uriToPath((String)params[0]);
62-
63-
var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
64-
var contentBase = db.getReadOnlyFileSystem().contentBase();
65-
66-
Optional<ReadOnlyFile> contentFileOpt = ContentResolvingStrategy.resolve(uri, db);
67-
68-
if (contentFileOpt.isPresent()) {
69-
var node_uri = PathUtil.toRelativeFile(contentFileOpt.get(), contentBase);
70-
final Optional<ContentNode> nodeByUri = db.getContent().byUri(node_uri);
71-
if (nodeByUri.isPresent()) {
72-
return Map.of(
73-
"meta", new MapAccess(nodeByUri.get().data()),
74-
"uri", PathUtil.toURL(contentFileOpt.get(), contentBase)
75-
);
76-
}
51+
protected void extendMap(Map<String, Object> node, ReadOnlyFile contentFile) {
52+
try {
53+
var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
54+
var contentRenderer = requestContext.get(InjectorFeature.class).injector().getInstance(ContentRenderer.class);
55+
List<ContentNode> sections = db.getContent().listSections(contentFile);
56+
57+
Map<String, List<Section>> renderedSections = contentRenderer.renderSections(sections, requestContext);
58+
node.put("sections", renderedSections);
59+
} catch (IOException iOException) {
60+
log.error("error loading sections", iOException);
7761
}
78-
79-
return null;
8062
}
8163

8264
@Override
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.condation.cms.templates.functions.impl;
2+
3+
/*-
4+
* #%L
5+
* cms-templates
6+
* %%
7+
* Copyright (C) 2023 - 2026 CondationCMS
8+
* %%
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public
20+
* License along with this program. If not, see
21+
* <http://www.gnu.org/licenses/gpl-3.0.html>.
22+
* #L%
23+
*/
24+
25+
import com.condation.cms.api.db.ContentNode;
26+
import com.condation.cms.api.db.DB;
27+
import com.condation.cms.api.db.cms.ReadOnlyFile;
28+
import com.condation.cms.api.feature.features.InjectorFeature;
29+
import com.condation.cms.api.request.RequestContext;
30+
import com.condation.cms.content.ContentRenderer;
31+
import com.condation.cms.content.Section;
32+
import java.io.IOException;
33+
import java.util.List;
34+
import java.util.Map;
35+
import lombok.extern.slf4j.Slf4j;
36+
37+
/**
38+
*
39+
* @author thorstenmarx
40+
*/
41+
@Slf4j
42+
public class NodeMetaFunction extends AbstractNodeFunction {
43+
44+
public static final String NAME = "select_node_meta";
45+
46+
public NodeMetaFunction(RequestContext requestContext) {
47+
super(requestContext);
48+
}
49+
50+
@Override
51+
public String name() {
52+
return NAME;
53+
}
54+
55+
}

cms-templates/src/test/java/com/condation/cms/templates/TemplateEngineExceptionTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public void test_invalid_template() {
5151
}
5252

5353
@Test
54+
@Disabled("because disabling the strict mode")
5455
public void test_unknown_variable() {
5556
Assertions.assertThatCode(
5657
() -> {

modules/ui-module/src/main/resources/manager/index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
baseUrl: '{{ managerBaseURL }}',
9696
contextPath: '{{ contextPath }}',
9797
siteId: '{{ siteId }}',
98-
previewUrl: "{{ links.createUrl('/?preview=manager&preview-token22=' + previewToken) | raw }}"
98+
previewUrl: "{{ links.createUrl('/?preview=manager') | raw }}"
9999
}
100100
</script>
101101
<link rel="stylesheet" href="{{ links.createUrl('/manager/css/manager.css') }}" />
@@ -211,8 +211,7 @@
211211
</div>
212212
<div id="content" class="flex-grow-1 d-flex flex-column overflow-hidden">
213213
<div id="previewWrapper" class="flex-grow-1 position-relative">
214-
<iframe id="contentPreview" class="position-absolute top-0 start-0 w-100 h-100 border-0"
215-
srcalt="{{ links.createUrl('/?preview=manager&preview-token22=' + previewToken) | raw }}"></iframe>
214+
<iframe id="contentPreview" class="position-absolute top-0 start-0 w-100 h-100 border-0"></iframe>
216215

217216
<!-- Overlay -->
218217
<div id="previewOverlay"

modules/ui-module/src/main/resources/manager/js/manager.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* #L%
2121
*/
2222
import frameMessenger from '@cms/modules/frameMessenger.js';
23-
import { loadPreview } from '@cms/modules/preview.utils.js';
23+
import { activatePreviewOverlay, getPreviewFrame, loadPreview } from '@cms/modules/preview.utils.js';
2424
import { UIStateManager } from '@cms/modules/ui-state.js';
2525
import { updateStateButton } from '@cms/modules/manager-ui.js';
2626
import { EventBus } from '@cms/modules/event-bus.js';
@@ -33,13 +33,14 @@ frameMessenger.on('load', (payload) => {
3333
document.addEventListener("DOMContentLoaded", function () {
3434
//PreviewHistory.init("/");
3535
//updateStateButton();
36+
activatePreviewOverlay();
3637
const intervalId = window.setInterval(() => {
3738
var token = createCSRFToken({});
3839
token.then((token) => {
3940
setCSRFToken(token.result);
4041
});
4142
}, 5 * 60 * 1000);
42-
const iframe = document.getElementById('contentPreview');
43+
const iframe = getPreviewFrame();
4344
iframe.addEventListener("load", previewLoadedHandler);
4445
const urlParams = new URLSearchParams(window.location.search);
4546
const pageUrl = urlParams.get('page');
@@ -64,9 +65,8 @@ document.addEventListener("DOMContentLoaded", function () {
6465
initMessageHandlers();
6566
});
6667
const previewLoadedHandler = () => {
67-
EventBus.emit("preview:loaded", {});
6868
try {
69-
const iframe = document.getElementById('contentPreview');
69+
const iframe = getPreviewFrame();
7070
const currentUrl = iframe.contentWindow.location.href;
7171
const url = new URL(currentUrl);
7272
const preview_url = url.pathname + url.search;
@@ -76,6 +76,7 @@ const previewLoadedHandler = () => {
7676
};
7777
UIStateManager.setTabState("preview", preview_update);
7878
updateStateButton();
79+
EventBus.emit("preview:loaded", {});
7980
}
8081
catch (e) {
8182
console.log(e);

modules/ui-module/src/main/ts/dist/js/manager.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* #L%
2121
*/
2222
import frameMessenger from '@cms/modules/frameMessenger.js';
23-
import { loadPreview } from '@cms/modules/preview.utils.js';
23+
import { activatePreviewOverlay, getPreviewFrame, loadPreview } from '@cms/modules/preview.utils.js';
2424
import { UIStateManager } from '@cms/modules/ui-state.js';
2525
import { updateStateButton } from '@cms/modules/manager-ui.js';
2626
import { EventBus } from '@cms/modules/event-bus.js';
@@ -33,13 +33,14 @@ frameMessenger.on('load', (payload) => {
3333
document.addEventListener("DOMContentLoaded", function () {
3434
//PreviewHistory.init("/");
3535
//updateStateButton();
36+
activatePreviewOverlay();
3637
const intervalId = window.setInterval(() => {
3738
var token = createCSRFToken({});
3839
token.then((token) => {
3940
setCSRFToken(token.result);
4041
});
4142
}, 5 * 60 * 1000);
42-
const iframe = document.getElementById('contentPreview');
43+
const iframe = getPreviewFrame();
4344
iframe.addEventListener("load", previewLoadedHandler);
4445
const urlParams = new URLSearchParams(window.location.search);
4546
const pageUrl = urlParams.get('page');
@@ -64,9 +65,8 @@ document.addEventListener("DOMContentLoaded", function () {
6465
initMessageHandlers();
6566
});
6667
const previewLoadedHandler = () => {
67-
EventBus.emit("preview:loaded", {});
6868
try {
69-
const iframe = document.getElementById('contentPreview');
69+
const iframe = getPreviewFrame();
7070
const currentUrl = iframe.contentWindow.location.href;
7171
const url = new URL(currentUrl);
7272
const preview_url = url.pathname + url.search;
@@ -76,6 +76,7 @@ const previewLoadedHandler = () => {
7676
};
7777
UIStateManager.setTabState("preview", preview_update);
7878
updateStateButton();
79+
EventBus.emit("preview:loaded", {});
7980
}
8081
catch (e) {
8182
console.log(e);

0 commit comments

Comments
 (0)