Skip to content

Commit

Permalink
Merge pull request #3 from rohberg/volto-16a15-slate-from-volto-core
Browse files Browse the repository at this point in the history
Update for Volto 16 with Slate integration
  • Loading branch information
ksuess authored Jul 26, 2022
2 parents 2d213c5 + d7be71f commit 9280d1e
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 73 deletions.
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
# Volto Add-On @rohberg/volto-slate-glossary
# @rohberg/volto-slate-glossary

## Add tooltips for glossary terms of [collective.glossary](https://github.com/collective/collective.glossary)
Volto Add-On `@rohberg/volto-slate-glossary` adds tooltips for glossary terms of [collective.glossary](https://github.com/collective/collective.glossary)

![Tooltips @rohberg/volto-slate-glossary](https://github.com/rohberg/volto-slate-glossary/blob/6deebe7ecfa5a6265e2ead8f5902cfd2243329ca/public/tooltips.png)
![Tooltips @rohberg/volto-slate-glossary](https://github.com/rohberg/volto-slate-glossary/raw/main/public/volto-slate-glossary-tooltips.png)

## work-in-progress

Include in your project with
Determine where to apply tooltips in your project by match configuration:

import { Tooltips } from '@rohberg/volto-slate-glossary/components';

// All your imports required for the config here BEFORE this line
import '@plone/volto/config';

export default function applyConfig(config) {
config.settings = {
...config.settings,
appExtras: [
...config.settings.appExtras,
{
match: '',
match: '/documentation',
component: Tooltips,
},
{
match: '/news',
component: Tooltips,
},
],
Expand All @@ -28,9 +27,8 @@ Include in your project with
return config;
}

Hack: Use the customized *serializeNodes* in *TextBlockView* instead of that from volto-slate. **TODO** Find a way to hook into rendering of blocks. A block tranformer is not appropriate as it manipulates the block data permanently. We want the blocks data to be untouched.

Install Plone Add-On [collective.glossary branch Plone5.2](https://github.com/collective/collective.glossary) in your backend.
Install Plone Add-On [collective.glossary](https://github.com/collective/collective.glossary) in your backend.


User can opt-out by setting glossarytooltips to false. Add a member field *glossarytooltips*.
3 changes: 2 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
## TODO

- Restrict to collective.glossary settings portal types
- Restrict to collective.glossary settings portal types
- Support global switch of collective.glossary
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
"i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon"
},
"addons": [
"volto-slate:asDefault"
],
"dependencies": {
"@plone/scripts": "*",
"volto-slate": "*"
"@plone/scripts": "*"
}
}
Binary file removed public/tooltips.png
Binary file not shown.
Binary file added public/volto-slate-glossary-tooltips.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/GlossaryView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const GlossaryView = ({ content }) => {
</header>
<section id="content-core" className="glossary">
{Object.keys(glossaryentries || {})?.map((letter) => (
<div>
<div key={letter}>
<h2 className="letter">{letter}</h2>
{glossaryentries[letter].map((item) => (
<article className="term" key={item['@id']}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/TermView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const TermView = ({ content }) => {
{content.definition && (
<p
dangerouslySetInnerHTML={{
__html: content.definition?.data || [],
__html: content.definition?.data || '',
}}
/>
)}
Expand Down
9 changes: 4 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { serializeNodes } from './utils';
import GlossaryView from './components/GlossaryView';
import TermView from './components/TermView';
import { glossarytermsReducer, glossarytooltiptermsReducer } from './reducers';

// TODO restrict tooltips to paths and portal_types
import { TextWithGlossaryTooltips } from './utils';

export default (config) => {
config.settings.slate.leafs = {
text: ({ children }) => <TextWithGlossaryTooltips text={children} />,
};
config.views = {
...config.views,
contentTypesViews: {
Expand All @@ -23,5 +24,3 @@ export default (config) => {

return config;
};

export { serializeNodes };
59 changes: 9 additions & 50 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
/**
* customization of serializeNodes from volto-slate to apply glossary tooltips in text blocks
* TODO find better solution without overriding serializeNodes. Something like a configurable Leaf.
* See https://community.plone.org/t/slate-rendering/13787/4
*/

import React from 'react';
import { useSelector } from 'react-redux';
import { flatten, isEqual } from 'lodash';
import { flatten } from 'lodash';
import { Popup } from 'semantic-ui-react';
import { Node, Text } from 'slate';

import { Element, Leaf } from 'volto-slate/editor/render';
import { useLocation } from 'react-router-dom';

const TextWithGlossaryTooltips = ({ text }) => {
export const TextWithGlossaryTooltips = ({ text }) => {
const glossaryterms = useSelector(
(state) => state.glossarytooltipterms?.result?.items,
);
const location = useLocation();

// no tooltips if user opted out
const currentuser = useSelector((state) => state.users?.user);
const glossarytooltips = currentuser?.glossarytooltips ?? true;
if (!glossarytooltips) {
return <span>{text}</span>;
return text;
}
const isEditMode = location.pathname.slice(-5) === '/edit';
if (isEditMode || location.pathname === '/' || !__CLIENT__) {
return text;
}

let result = [{ type: 'text', val: text }];
Expand Down Expand Up @@ -63,7 +60,6 @@ const TextWithGlossaryTooltips = ({ text }) => {
} else {
let idx = glossaryterms.findIndex((variant) => variant.term === el.val);
let definition = glossaryterms[idx]?.definition || '';
// TODO convert definition to ul
switch (definition.length) {
case 0:
definition = '';
Expand Down Expand Up @@ -96,40 +92,3 @@ const TextWithGlossaryTooltips = ({ text }) => {
}
});
};

const serializeData = (node) => {
return JSON.stringify({ type: node.type, data: node.data });
};

export const serializeNodes = (nodes, getAttributes) => {
const editor = { children: nodes || [] };

const _serializeNodes = (nodes) => {
return (nodes || []).map(([node, path], i) => {
return Text.isText(node) ? (
<Leaf path={path} leaf={node} text={node} mode="view" key={path}>
<TextWithGlossaryTooltips text={node.text} />
</Leaf>
) : (
<Element
path={path}
element={node}
mode="view"
key={path}
data-slate-data={node.data ? serializeData(node) : null}
attributes={
isEqual(path, [0])
? getAttributes
? getAttributes(node, path)
: null
: null
}
>
{_serializeNodes(Array.from(Node.children(editor, path)))}
</Element>
);
});
};

return _serializeNodes(Array.from(Node.children(editor, [])));
};

0 comments on commit 9280d1e

Please sign in to comment.