You can use DM Editor for edit in admin site and view in admin and frontend.
Below is a sample code of loading and saving data in DM Editor.
import {registerDefaultWidgets, setDMEditorConfig, DMEData, DMEditor, DMEditorRefType} from 'dmeditor';
//Note: it's a good practise to put initialization to a separate file. eg. initDMEditor.ts
registerDefaultWidgets();
setDMEditorConfig({});
export App = ()=>{
const editorRef = useRef<DMEditorRefType>(null);
const data= [
{
id: `N-LAQWihvfZv1SmUAPoQx`,
data: {
value: 'This is a heading',
level: 2,
settings: {
align: 'left',
},
},
type: 'heading',
}]
const initData = ()=>{
const editor = editorRef.current;
if (editor) {
editor.setData(data);
}
};
useEffect(() => {
initData();
}, []);
const save(data: DMEData.SavedData)=>{
console.log(data);
window.alert('Saved');
}
const cancel()=>{
//redirect
}
return (
<div>
<DMEditor ref={editorRef} onSave={save} onCancel={cancel} />
</div>
);
}
OnSave is invoked when editor clicks 'Save' button. The parameter data contains 2 properties:
- data: an Array of blocks
- page: an object of page settings.
Below is an example of data in onSave callback:
{
data: [
{
id: `N-LAQWihvfZv1SmUAPoQx`,
data: {
value: "This is a heading",
level: 2,
settings: {
align: "left",
},
},
type: "heading",
},
],
page: {title:'New page', cover_image: 'https://test.com/sample.jpg'}
}
Same parameter as onSave, just invoked when there is any change(eg. typing). It can be used for eg. autosaving. Use it carefully for performance reason since it's invoked quite frequently - on every change.
Invoked when cancel button is clicked.
editor.setData(data)
sets existing data to the editor.
It's possible to customize page settings like below.
!!! note
`title` is always the first one, and there is no need to configure `title`.
const pageSettings: Array<DME.PageSetting> = [
{ identifier: "cover_image", name: "Cover image", type: "image" },
{ identifier: "meta_key", name: "Meta key", type: "text" },
{
identifier: "meta_description",
name: "Meta description",
type: "multitext",
},
];
editor.setPageSettings(pageSettings);
editor.setPageData({ title: "New page", cover_image: "" });
Page settings looks like this:
Supports types: text
, multitext
, checkbox
, image
Here is an example of viewing DM Editor data - just use component DMEditorView
import {registerDefaultWidgets, setDMEditorConfig, DMEditorView} from 'dmeditor';
//Note: it's a good practise to put initialization to a separate file. eg. initDMEditor.ts
registerDefaultWidgets();
setDMEditorConfig({});
export const View = ()=>{
const data = [[
{
id: `N-LAQWihvfZv1SmUAPoQx`,
data: {
value: 'This is a heading',
level: 2,
settings: {
align: 'left',
// value: '',
},
},
type: 'heading',
}];
return <div><DMEditorView data={data} /></div>;
}
SSR view is same way using DMEditorView. Just need additional action: invoke DM Editor's api so widgets can fetch dynamic data before the page is loaded. Eg. a NewsList widget can fetch list data first in this case.
See SSR prefetch for more.
!!! sample "Nextjs sample"
Check out nextjs [sample project](https://github.com/dmeditor/dmeditor-server) .
It's needed to initial some css settings by set css variables.
--dme=container-width
and --dme-main-width
A DMEditorView has a container and a rendering area, where container's width is set in css variable --dme-container-width
and the actual block list width is set by --dme-main-width
.
Some widgets rely on the 2 values to implement 'full screen width', eg. 'full screen width image', 'full screen width background', 'full screen width carousel'. Below illustrate the different width.
Here is typical setting sample:
:root {
--dme-container-width: 100vw;
--dme-main-width: 1200px;
}
.dme-viewmode-mobile,
.dme-viewmode-tablet {
--dme-main-width: 100vw;
}
!!! note
Both values should be absolute or calculated value (meaning value like `100%` is not allowed, but `100vw`, `1200px`, `calc(100vw * 0.8)` are allowed).
!!! note "CSS frameworks"
DM Editor can work with all mainstream CSS/react frameworks, eg. bootstrap, css-in-js(emotion, mui), tailwind, etc.
Tailwind's utility based approache gives high performance and good resuse of styles, thus is a very good match for DM Editor.
Put below in global css so some widget's full width can work (eg. nextjs+tailwind's globals.css):
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--dme-container-width: 100vw;
}
/*optional to remove horizontal scrollbar*/
body {
overflow-x: hidden;
}
@media screen(md) {
:root {
--dme-main-width: theme(screens.md);
}
}
@media screen(lg) {
:root {
--dme-main-width: theme(screens.lg);
}
}
@media screen(xl) {
:root {
--dme-main-width: theme(screens.xl);
}
}
@media screen(2xl) {
:root {
--dme-main-width: theme(screens.2xl);
}
}