Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import com.condation.cms.content.pipeline.ContentPipelineFactory;
import com.condation.cms.content.views.model.View;
import com.condation.cms.api.content.MapAccess;
import com.condation.cms.api.utils.HTTPUtil;
import com.condation.cms.extensions.hooks.DBHooks;
import com.condation.cms.extensions.hooks.TemplateHooks;
import com.condation.cms.content.template.functions.LinkFunction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private JexlEngine createJexlEngine() {
builder
.cache(512)
.safe(false)
.strict(true)
.strict(false)
.silent(false)
.debug(false);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.condation.cms.templates.functions.JexlTemplateFunction;
import com.condation.cms.templates.functions.impl.DateFunction;
import com.condation.cms.templates.functions.impl.NodeFunction;
import com.condation.cms.templates.functions.impl.NodeMetaFunction;
import com.condation.cms.templates.parser.ASTNode;
import com.condation.cms.templates.renderer.Renderer;
import com.condation.cms.templates.renderer.ScopeStack;
Expand Down Expand Up @@ -75,6 +76,7 @@ private ScopeStack createScope (Map<String, Object> context, DynamicConfiguratio
var scope = new ScopeStack(context);
scope.setVariable(DateFunction.NAME, new JexlTemplateFunction(new DateFunction()));
scope.setVariable(NodeFunction.NAME, new JexlTemplateFunction(new NodeFunction(dynamicConfiguration.requestContext())));
scope.setVariable(NodeMetaFunction.NAME, new JexlTemplateFunction(new NodeMetaFunction(dynamicConfiguration.requestContext())));

dynamicConfiguration.templateFunctions().forEach(tf -> {
scope.setVariable(tf.name(), new JexlTemplateFunction(tf));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.condation.cms.templates.functions.impl;

/*-
* #%L
* cms-templates
* %%
* Copyright (C) 2023 - 2026 CondationCMS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/

import com.condation.cms.api.content.MapAccess;
import com.condation.cms.api.db.ContentNode;
import com.condation.cms.api.db.DB;
import com.condation.cms.api.db.cms.ReadOnlyFile;
import com.condation.cms.api.feature.features.InjectorFeature;
import com.condation.cms.api.request.RequestContext;
import com.condation.cms.api.utils.PathUtil;
import com.condation.cms.core.content.ContentResolvingStrategy;
import com.condation.cms.templates.functions.TemplateFunction;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;

/**
*
* @author thmar
*/
@RequiredArgsConstructor
public abstract class AbstractNodeFunction implements TemplateFunction {
protected final RequestContext requestContext;

protected void extendMap (Map<String, Object> node, ReadOnlyFile contentFile) {

}

@Override
public Object invoke(Object... params) {

if (params == null || params.length == 0 ) {
return null;
}
if (!(params[0] instanceof String)) {
return null;
}
String uri = ContentResolvingStrategy.uriToPath((String)params[0]);

var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
var contentBase = db.getReadOnlyFileSystem().contentBase();

Optional<ReadOnlyFile> contentFileOpt = ContentResolvingStrategy.resolve(uri, db);

if (contentFileOpt.isPresent()) {
var node_uri = PathUtil.toRelativeFile(contentFileOpt.get(), contentBase);
final Optional<ContentNode> nodeByUri = db.getContent().byUri(node_uri);
if (nodeByUri.isPresent()) {
var node = new HashMap<String, Object>();
node.put("meta", new MapAccess(nodeByUri.get().data()));
node.put("uri", PathUtil.toURL(contentFileOpt.get(), contentBase));

extendMap(node, contentFileOpt.get());

return node;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,61 +22,43 @@
* #L%
*/

import com.condation.cms.api.content.MapAccess;
import com.condation.cms.api.db.ContentNode;
import com.condation.cms.api.db.DB;
import com.condation.cms.api.db.cms.ReadOnlyFile;
import com.condation.cms.api.feature.features.DBFeature;
import com.condation.cms.api.feature.features.InjectorFeature;
import com.condation.cms.api.feature.features.RequestFeature;
import com.condation.cms.api.request.RequestContext;
import com.condation.cms.api.utils.PathUtil;
import com.condation.cms.core.content.ContentResolvingStrategy;
import com.condation.cms.templates.functions.TemplateFunction;
import java.util.Date;
import com.condation.cms.content.ContentRenderer;
import com.condation.cms.content.Section;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
*
* @author thorstenmarx
*/
@RequiredArgsConstructor
public class NodeFunction implements TemplateFunction {
@Slf4j
public class NodeFunction extends AbstractNodeFunction {

public static final String NAME = "select_node";

private final RequestContext requestContext;

public NodeFunction(RequestContext requestContext) {
super(requestContext);
}

@Override
public Object invoke(Object... params) {

if (params == null || params.length == 0 ) {
return null;
}
if (!(params[0] instanceof String)) {
return null;
}
String uri = ContentResolvingStrategy.uriToPath((String)params[0]);

var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
var contentBase = db.getReadOnlyFileSystem().contentBase();

Optional<ReadOnlyFile> contentFileOpt = ContentResolvingStrategy.resolve(uri, db);

if (contentFileOpt.isPresent()) {
var node_uri = PathUtil.toRelativeFile(contentFileOpt.get(), contentBase);
final Optional<ContentNode> nodeByUri = db.getContent().byUri(node_uri);
if (nodeByUri.isPresent()) {
return Map.of(
"meta", new MapAccess(nodeByUri.get().data()),
"uri", PathUtil.toURL(contentFileOpt.get(), contentBase)
);
}
protected void extendMap(Map<String, Object> node, ReadOnlyFile contentFile) {
try {
var db = requestContext.get(InjectorFeature.class).injector().getInstance(DB.class);
var contentRenderer = requestContext.get(InjectorFeature.class).injector().getInstance(ContentRenderer.class);
List<ContentNode> sections = db.getContent().listSections(contentFile);

Map<String, List<Section>> renderedSections = contentRenderer.renderSections(sections, requestContext);
node.put("sections", renderedSections);
} catch (IOException iOException) {
log.error("error loading sections", iOException);
}

return null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.condation.cms.templates.functions.impl;

/*-
* #%L
* cms-templates
* %%
* Copyright (C) 2023 - 2026 CondationCMS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/

import com.condation.cms.api.db.ContentNode;
import com.condation.cms.api.db.DB;
import com.condation.cms.api.db.cms.ReadOnlyFile;
import com.condation.cms.api.feature.features.InjectorFeature;
import com.condation.cms.api.request.RequestContext;
import com.condation.cms.content.ContentRenderer;
import com.condation.cms.content.Section;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;

/**
*
* @author thorstenmarx
*/
@Slf4j
public class NodeMetaFunction extends AbstractNodeFunction {

public static final String NAME = "select_node_meta";

public NodeMetaFunction(RequestContext requestContext) {
super(requestContext);
}

@Override
public String name() {
return NAME;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void test_invalid_template() {
}

@Test
@Disabled("because disabling the strict mode")
public void test_unknown_variable() {
Assertions.assertThatCode(
() -> {
Expand Down
5 changes: 2 additions & 3 deletions modules/ui-module/src/main/resources/manager/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
baseUrl: '{{ managerBaseURL }}',
contextPath: '{{ contextPath }}',
siteId: '{{ siteId }}',
previewUrl: "{{ links.createUrl('/?preview=manager&preview-token22=' + previewToken) | raw }}"
previewUrl: "{{ links.createUrl('/?preview=manager') | raw }}"
}
</script>
<link rel="stylesheet" href="{{ links.createUrl('/manager/css/manager.css') }}" />
Expand Down Expand Up @@ -211,8 +211,7 @@
</div>
<div id="content" class="flex-grow-1 d-flex flex-column overflow-hidden">
<div id="previewWrapper" class="flex-grow-1 position-relative">
<iframe id="contentPreview" class="position-absolute top-0 start-0 w-100 h-100 border-0"
srcalt="{{ links.createUrl('/?preview=manager&preview-token22=' + previewToken) | raw }}"></iframe>
<iframe id="contentPreview" class="position-absolute top-0 start-0 w-100 h-100 border-0"></iframe>

<!-- Overlay -->
<div id="previewOverlay"
Expand Down
9 changes: 5 additions & 4 deletions modules/ui-module/src/main/resources/manager/js/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* #L%
*/
import frameMessenger from '@cms/modules/frameMessenger.js';
import { loadPreview } from '@cms/modules/preview.utils.js';
import { activatePreviewOverlay, getPreviewFrame, loadPreview } from '@cms/modules/preview.utils.js';
import { UIStateManager } from '@cms/modules/ui-state.js';
import { updateStateButton } from '@cms/modules/manager-ui.js';
import { EventBus } from '@cms/modules/event-bus.js';
Expand All @@ -33,13 +33,14 @@ frameMessenger.on('load', (payload) => {
document.addEventListener("DOMContentLoaded", function () {
//PreviewHistory.init("/");
//updateStateButton();
activatePreviewOverlay();
const intervalId = window.setInterval(() => {
var token = createCSRFToken({});
token.then((token) => {
setCSRFToken(token.result);
});
}, 5 * 60 * 1000);
const iframe = document.getElementById('contentPreview');
const iframe = getPreviewFrame();
iframe.addEventListener("load", previewLoadedHandler);
const urlParams = new URLSearchParams(window.location.search);
const pageUrl = urlParams.get('page');
Expand All @@ -64,9 +65,8 @@ document.addEventListener("DOMContentLoaded", function () {
initMessageHandlers();
});
const previewLoadedHandler = () => {
EventBus.emit("preview:loaded", {});
try {
const iframe = document.getElementById('contentPreview');
const iframe = getPreviewFrame();
const currentUrl = iframe.contentWindow.location.href;
const url = new URL(currentUrl);
const preview_url = url.pathname + url.search;
Expand All @@ -76,6 +76,7 @@ const previewLoadedHandler = () => {
};
UIStateManager.setTabState("preview", preview_update);
updateStateButton();
EventBus.emit("preview:loaded", {});
}
catch (e) {
console.log(e);
Expand Down
9 changes: 5 additions & 4 deletions modules/ui-module/src/main/ts/dist/js/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* #L%
*/
import frameMessenger from '@cms/modules/frameMessenger.js';
import { loadPreview } from '@cms/modules/preview.utils.js';
import { activatePreviewOverlay, getPreviewFrame, loadPreview } from '@cms/modules/preview.utils.js';
import { UIStateManager } from '@cms/modules/ui-state.js';
import { updateStateButton } from '@cms/modules/manager-ui.js';
import { EventBus } from '@cms/modules/event-bus.js';
Expand All @@ -33,13 +33,14 @@ frameMessenger.on('load', (payload) => {
document.addEventListener("DOMContentLoaded", function () {
//PreviewHistory.init("/");
//updateStateButton();
activatePreviewOverlay();
const intervalId = window.setInterval(() => {
var token = createCSRFToken({});
token.then((token) => {
setCSRFToken(token.result);
});
}, 5 * 60 * 1000);
const iframe = document.getElementById('contentPreview');
const iframe = getPreviewFrame();
iframe.addEventListener("load", previewLoadedHandler);
const urlParams = new URLSearchParams(window.location.search);
const pageUrl = urlParams.get('page');
Expand All @@ -64,9 +65,8 @@ document.addEventListener("DOMContentLoaded", function () {
initMessageHandlers();
});
const previewLoadedHandler = () => {
EventBus.emit("preview:loaded", {});
try {
const iframe = document.getElementById('contentPreview');
const iframe = getPreviewFrame();
const currentUrl = iframe.contentWindow.location.href;
const url = new URL(currentUrl);
const preview_url = url.pathname + url.search;
Expand All @@ -76,6 +76,7 @@ const previewLoadedHandler = () => {
};
UIStateManager.setTabState("preview", preview_update);
updateStateButton();
EventBus.emit("preview:loaded", {});
}
catch (e) {
console.log(e);
Expand Down
Loading