Build a headless CMS content editing interface using the File Manager and Code Editor as embedded widgets. Create content pages with frontmatter metadata, preview rendered HTML, and organize content in a structured directory.
<iframe id="cms-demo" src="/online/webapp/file-manager" width="100%" height="650" frameborder="0" style="border:1px solid #ccc; border-radius:4px;"></iframe>
<script>window._wsConnect('cms-demo', 'cmsSocket');
window._cmsSeq = function (cmds, done) {
var s = window._ws('cmsSocket');
if (!s) return;
var i = 0;
var next = function () {
if (i >= cmds.length) { if (done) done(); return; }
var cmd = cmds[i++];
var args = cmd.concat([function () { setTimeout(next, 5); }]);
s.fire.apply(s, ['webapp::instance::request'].concat(args));
};
next();};
window._cmsAppCode = function (renderFnStr) {
return 'module.exports = function () {\n' +
'var app = new ApplicationPrototype();\n' +
'var node = document.createElement("div");\n' +
'var win = null;\n' +
'var ready = new Application.Promise();\n' +
'app.bind("node", function () { return node; }, "");\n' +
'app.bind("window", function () { return win; }, "");\n' +
'app.bind("ready", function () { return ready; });\n' +
'app.bind("handleWindow", function (w) {\n' +
' win = w;\n' +
' w.emit("api-request::attached", []);\n' +
' w.on("api-request::ready", function (cb) { cb(ready); });\n' +
'});\n' +
'app.bind("render", function (cb) {\n' +
' (' + renderFnStr + ')(app, win, node, cb);\n' +
'});\n' +
'app.bind("destroy", function () {});\n' +
'app.bind("init", function () {\n' +
' app.render(function (err) {\n' +
' if (err) return ready.reject(err);\n' +
' ready.resolve(app);\n' +
' });\n' +
' return app;\n' +
'});\n' +
'return app;\n' +
'};';};
window._cmsSetup = function () {
// Page Preview app - renders frontmatter + markdown content as a styled page
var previewAppCode = window._cmsAppCode((function (app, win, node, cb) {
win.title('Page Preview'); win.icon('paper/icons/apps/internet-web-browser');
win.height(500); win.width(700);
var args = app.window().env().args || [];
if (!args[0]) { cb(); return; }
node.innerHTML = 'Rendering page...
';
Application.require('/files/api/modules/fs.js').then(function (fsModule) {
fsModule().read(args[0], null, true).response('text').then(function (text) {
var frontmatter = {};
var content = text;
var fmMatch = text.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
if (fmMatch) {
fmMatch[1].split('\n').forEach(function (line) {
var parts = line.split(':');
if (parts.length >= 2) frontmatter[parts[0].trim()] = parts.slice(1).join(':').trim();
});
content = fmMatch[2];
}
var html = content
.replace(/^### (.+)$/gm, '$1
')
.replace(/^## (.+)$/gm, '$1
')
.replace(/^# (.+)$/gm, '$1
')
.replace(/\*\*(.+?)\*\*/g, '$1')
.replace(/\*(.+?)\*/g, '$1')
.replace(/`([^`]+)`/g, '$1')
.replace(/^- (.+)$/gm, '$1 ')
.replace(/\n\n/g, '')
.replace(/\n/g, '
');
var page = '
';
if (frontmatter.title) {
page += '';
page += '' + frontmatter.title + '
';
if (frontmatter.description) page += '' + frontmatter.description + '
';
if (frontmatter.author || frontmatter.date) page += '' + (frontmatter.author || '') + (frontmatter.author && frontmatter.date ? ' · ' : '') + (frontmatter.date || '') + '';
page += '';
}
page += '' + html + '
';
if (frontmatter.tags) page += 'Tags: ' + frontmatter.tags.split(',').map(function(t){return ''+t.trim()+''}).join(' ') + '';
page += '';
node.innerHTML = page;
});
});
cb();
}).toString());// Content pages
var homePage = [
'---',
'title: Welcome to Our Platform',
'description: The fastest way to build modern web applications',
'author: SGApps Team',
'date: 2026-04-03',
'tags: home, landing, featured',
'status: published',
'---',
'',
'## Build Something Amazing',
'',
'Our platform provides everything you need to create, deploy, and scale modern web applications.',
'',
'## Key Features',
'',
'- **Fast Development** — Go from idea to prototype in minutes',
'- **Cloud Native** — Deploys automatically to our global CDN',
'- **API First** — RESTful APIs generated from your schema',
'- **Real-time** — Built-in WebSocket support for live features',
'',
'## Getting Started',
'',
'Create your first project with `npx create-app my-project` and start building immediately.',
'',
'Check out our documentation for tutorials, API reference, and best practices.'
].join('\n');var aboutPage = [
'---',
'title: About Us',
'description: Learn about our team and mission',
'author: SGApps Team',
'date: 2026-03-15',
'tags: about, team, company',
'status: published',
'---',
'',
'## Our Mission',
'',
'We believe that building web applications should be **accessible to everyone**. Our tools remove complexity so you can focus on what matters — your users.',
'',
'## The Team',
'',
'Founded in 2020, we are a small team of developers and designers passionate about developer experience.',
'',
'- *Engineering* — Building the platform core',
'- *Design* — Crafting intuitive interfaces',
'- *Community* — Supporting our users'
].join('\n');var blogPost = [
'---',
'title: Introducing Archive Support',
'description: View and edit ZIP, TAR, and 7Z archives directly in the browser',
'author: Sergiu Gordienco',
'date: 2026-04-01',
'tags: feature, archive, release',
'status: draft',
'---',
'',
'## What is New',
'',
'We are excited to announce **full archive support** in the File Manager. You can now open, browse, and edit ZIP, TAR, TAR.GZ, and 7Z archives directly in the browser.',
'',
'## How It Works',
'',
'When you double-click an archive file, the Archive Viewer:',
'',
'- Extracts all files to **browser memory** (no server upload)',
'- Shows them in the familiar File Manager interface',
'- Lets you **edit, add, and delete** files',
'- Rebuilds the archive with one click',
'',
'## Supported Formats',
'',
'- ZIP (read + write)',
'- TAR (read + write)',
'- TAR.GZ (read + write)',
'- 7Z (read + write)',
'- RAR (read only)',
'',
'## Try It Now',
'',
'Open any archive file in the File Manager or use the Archive Viewer webapp at `/online/webapp/archive-viewer`.'
].join('\n');var siteConfig = JSON.stringify({
site: { name: "My Platform", url: "https://example.com", language: "en" },
navigation: [
{ label: "Home", path: "/", page: "pages/home.md" },
{ label: "About", path: "/about", page: "pages/about.md" },
{ label: "Blog", path: "/blog", page: "blog/" }
],
theme: { primary: "#4a6cf7", font: "Inter, sans-serif" },
build: { output: "dist/", minify: true }
}, null, 2);window._cmsSeq([
['gui:specialPaths:clear'],
['fs:mkdirp', 'input://apps/'],
['fs:mkdirp', 'input://cms/pages/'],
['fs:mkdirp', 'input://cms/blog/'],
['fs:mkdirp', 'input://cms/assets/'],
['fs:write', 'input://apps/page-preview.js', previewAppCode],
['fs:write', 'input://cms/site.json', siteConfig],
['fs:write', 'input://cms/pages/home.md', homePage],
['fs:write', 'input://cms/pages/about.md', aboutPage],
['fs:write', 'input://cms/blog/2026-04-01-archive-support.md', blogPost],
['apps:register', {
'page-preview': { path: 'input://apps/page-preview.js', name: 'Page Preview', icon: 'paper/icons/apps/internet-web-browser', comment: 'Preview content pages with frontmatter', mimetypes: ['text/markdown', 'text/x-markdown'], args: ['%U'] }
}],
['gui:specialPaths:add', { path: 'input://cms/', name: 'CMS Content', icon: 'breeze/icons/places/64/folder-documents', paths: [{ rule: 'pages\\/', name: 'Pages' }, { rule: 'blog\\/', name: 'Blog Posts' }, { rule: 'assets\\/', name: 'Assets' }], bookmark: { category: 'cms', name: 'CMS Content', icon: 'breeze/icons/places/64/folder-documents' } }],
['gui:sidebar:toggle', true],
['fs:cwd', 'input://cms/']
], function () {
alert('CMS workspace ready!\n\nTry:\n- Double-click home.md or about.md to preview the page\n- Double-click the blog post to see it as a draft\n- Double-click site.json to view config (opens in Code Editor)\n- Check the breadcrumbs: CMS Content > Pages, Blog Posts');
});};</script>
<button onclick="window._cmsSetup()" style="padding:10px 20px;font-size:15px;cursor:pointer">Setup CMS Content Editor</button>
Creates a headless CMS structure with a custom Page Preview app that understands frontmatter metadata:
input://cms/
site.json ← opens with JSON Viewer (if registered) or Code Editor
pages/
home.md ← opens with Page Preview (renders frontmatter header + markdown)
about.md ← opens with Page Preview
blog/
2026-04-01-*.md ← opens with Page Preview (shows "draft" status)
assets/ ← for images, CSS, etc.Parses YAML-like frontmatter between --- delimiters:
---
title: Page Title
description: A brief description
author: Author Name
date: 2026-04-03
tags: tag1, tag2, tag3
status: published
---
## Content starts here
Regular **markdown** content...The preview renders:
pages/ and blog/ directories.md file to see the rendered page// Setup the CMS workspace
socket.fire("webapp::instance::request", "fs:mkdirp", "input://cms/pages/");
socket.fire("webapp::instance::request", "fs:mkdirp", "input://cms/blog/");
// Write content pages
socket.fire("webapp::instance::request", "fs:write",
"input://cms/pages/home.md",
"---\ntitle: Home\n---\n\n## Welcome\n\nYour content here."
);
// Register the page preview app
socket.fire("webapp::instance::request", "apps:register", {
"page-preview": {
path: "input://apps/page-preview.js",
name: "Page Preview",
mimetypes: ["text/markdown"],
args: ["%U"]
}
});
// Configure sidebar navigation
socket.fire("webapp::instance::request", "gui:specialPaths:add", {
path: "input://cms/",
name: "Content",
paths: [
{ rule: "pages\\/", name: "Pages" },
{ rule: "blog\\/", name: "Blog" }
],
bookmark: { category: "cms", name: "Content", icon: "breeze/icons/places/64/folder-documents" }
});This CMS demo works alongside the other use cases:
site.json previewassets/ folder