@plone/volto 16.21.2 → 16.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changelog.draft +28 -3
- package/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +42 -0
- package/cypress/support/commands.js +17 -0
- package/locales/it/LC_MESSAGES/volto.po +1 -1
- package/locales/it.json +1 -1
- package/package.json +1 -1
- package/packages/volto-slate/package.json +1 -1
- package/packages/volto-slate/src/actions/index.js +1 -1
- package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
- package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
- package/packages/volto-slate/src/blocks/Text/index.js +2 -2
- package/packages/volto-slate/src/editor/index.js +4 -4
- package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
- package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
- package/packages/volto-slate/src/editor/ui/index.js +15 -15
- package/packages/volto-slate/src/index.js +2 -2
- package/packages/volto-slate/src/utils/blocks.js +7 -0
- package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
- package/src/components/manage/AnchorPlugin/index.jsx +2 -2
- package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
- package/src/components/manage/Blocks/Block/Style.jsx +2 -2
- package/src/components/manage/Blocks/Listing/getAsyncData.js +7 -2
- package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +3 -4
- package/src/components/manage/Blocks/Search/components/Facets.jsx +6 -2
- package/src/components/manage/Blocks/Search/components/index.js +13 -13
- package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
- package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +2 -2
- package/src/components/manage/Blocks/ToC/Schema.jsx +5 -1
- package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +142 -8
- package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
- package/src/components/manage/Contents/Contents.jsx +8 -6
- package/src/components/manage/UniversalLink/UniversalLink.jsx +2 -6
- package/src/components/manage/UniversalLink/UniversalLink.test.jsx +36 -0
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +1 -1
- package/src/components/theme/Login/Login.jsx +1 -1
- package/src/components/theme/View/AlbumView.jsx +9 -1
- package/src/components/theme/View/EventView.jsx +6 -2
- package/src/components/theme/View/FileView.jsx +23 -18
- package/src/components/theme/View/ImageView.jsx +37 -32
- package/src/components/theme/View/LinkView.jsx +4 -1
- package/src/components/theme/View/ListingView.jsx +33 -27
- package/src/components/theme/View/SummaryView.jsx +47 -38
- package/src/components/theme/View/TabularView.jsx +59 -53
- package/src/config/RichTextEditor/Blocks.jsx +2 -2
- package/src/config/RichTextEditor/FromHTML.jsx +2 -2
- package/src/config/RichTextEditor/Styles.jsx +1 -1
- package/src/config/index.js +1 -0
- package/src/config/server.js +2 -0
- package/src/constants/Indexes.js +3 -1
- package/src/express-middleware/devproxy.js +1 -1
- package/src/express-middleware/files.js +3 -3
- package/src/express-middleware/images.js +4 -4
- package/src/express-middleware/ok.js +16 -0
- package/src/express-middleware/robotstxt.js +1 -1
- package/src/express-middleware/sitemap.js +1 -1
- package/src/express-middleware/static.js +3 -3
- package/src/helpers/Extensions/index.js +2 -1
- package/src/helpers/Url/Url.js +22 -1
- package/src/helpers/Url/Url.test.js +41 -0
- package/src/helpers/index.js +9 -10
- package/src/middleware/index.js +2 -2
- package/src/start-server.js +2 -2
- package/theme/themes/pastanaga/extras/blocks.less +3 -1
- package/theme/themes/pastanaga/extras/main.less +2 -1
- package/theme/themes/pastanaga/extras/toc.less +29 -0
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Segment, Container } from 'semantic-ui-react';
|
|
8
|
+
import { Segment, Container as SemanticContainer } from 'semantic-ui-react';
|
|
9
9
|
import { UniversalLink, PreviewImage } from '@plone/volto/components';
|
|
10
|
+
import config from '@plone/volto/registry';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* List view component class.
|
|
@@ -14,32 +15,37 @@ import { UniversalLink, PreviewImage } from '@plone/volto/components';
|
|
|
14
15
|
* @params {object} content Content object.
|
|
15
16
|
* @returns {string} Markup of the component.
|
|
16
17
|
*/
|
|
17
|
-
const ListingView = ({ content }) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
item
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
18
|
+
const ListingView = ({ content }) => {
|
|
19
|
+
const Container =
|
|
20
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Container id="page-home">
|
|
24
|
+
<section id="content-core">
|
|
25
|
+
{content.items.map((item) => (
|
|
26
|
+
<Segment key={item.url} className="listing-item">
|
|
27
|
+
<Container>
|
|
28
|
+
<h2>
|
|
29
|
+
<UniversalLink item={item} title={item['@type']}>
|
|
30
|
+
{item.title}
|
|
31
|
+
</UniversalLink>
|
|
32
|
+
</h2>
|
|
33
|
+
{item.description && <p>{item.description}</p>}
|
|
34
|
+
</Container>
|
|
35
|
+
{item.image_field && (
|
|
36
|
+
<PreviewImage
|
|
37
|
+
item={item}
|
|
38
|
+
size="thumb"
|
|
39
|
+
alt={item.image_caption ? item.image_caption : item.title}
|
|
40
|
+
className="ui image"
|
|
41
|
+
/>
|
|
42
|
+
)}
|
|
43
|
+
</Segment>
|
|
44
|
+
))}
|
|
45
|
+
</section>
|
|
46
|
+
</Container>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* Property types.
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
9
|
-
import { Container } from 'semantic-ui-react';
|
|
9
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
10
10
|
import { FormattedMessage } from 'react-intl';
|
|
11
11
|
import PreviewImage from '../PreviewImage/PreviewImage';
|
|
12
|
+
import config from '@plone/volto/registry';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Summary view component class.
|
|
@@ -16,43 +17,51 @@ import PreviewImage from '../PreviewImage/PreviewImage';
|
|
|
16
17
|
* @param {Object} content Content object.
|
|
17
18
|
* @returns {string} Markup of the component.
|
|
18
19
|
*/
|
|
19
|
-
const SummaryView = ({ content }) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
20
|
+
const SummaryView = ({ content }) => {
|
|
21
|
+
const Container =
|
|
22
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Container className="view-wrapper summary-view">
|
|
26
|
+
<article id="content">
|
|
27
|
+
<header>
|
|
28
|
+
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
29
|
+
{content.description && (
|
|
30
|
+
<p className="documentDescription">{content.description}</p>
|
|
31
|
+
)}
|
|
32
|
+
</header>
|
|
33
|
+
<section id="content-core">
|
|
34
|
+
{content.items.map((item) => (
|
|
35
|
+
<article key={item.url}>
|
|
36
|
+
<h2>
|
|
37
|
+
<UniversalLink item={item} title={item['@type']}>
|
|
38
|
+
{item.title}
|
|
39
|
+
</UniversalLink>
|
|
40
|
+
</h2>
|
|
41
|
+
{item.image_field && (
|
|
42
|
+
<PreviewImage
|
|
43
|
+
item={item}
|
|
44
|
+
alt={item.image_caption ? item.image_caption : item.title}
|
|
45
|
+
size="thumb"
|
|
46
|
+
className="ui image floated right clear"
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
{item.description && <p>{item.description}</p>}
|
|
50
|
+
<p>
|
|
51
|
+
<UniversalLink item={item}>
|
|
52
|
+
<FormattedMessage
|
|
53
|
+
id="Read More…"
|
|
54
|
+
defaultMessage="Read More…"
|
|
55
|
+
/>
|
|
56
|
+
</UniversalLink>
|
|
57
|
+
</p>
|
|
58
|
+
</article>
|
|
59
|
+
))}
|
|
60
|
+
</section>
|
|
61
|
+
</article>
|
|
62
|
+
</Container>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
56
65
|
|
|
57
66
|
/**
|
|
58
67
|
* Property types.
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
9
|
-
import { Container, Table } from 'semantic-ui-react';
|
|
9
|
+
import { Container as SemanticContainer, Table } from 'semantic-ui-react';
|
|
10
10
|
import { FormattedMessage } from 'react-intl';
|
|
11
|
+
import config from '@plone/volto/registry';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Tabular view component class.
|
|
@@ -15,59 +16,64 @@ import { FormattedMessage } from 'react-intl';
|
|
|
15
16
|
* @param {Object} content Content object.
|
|
16
17
|
* @returns {string} Markup of the component.
|
|
17
18
|
*/
|
|
18
|
-
const TabularView = ({ content }) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<Table.
|
|
35
|
-
<
|
|
36
|
-
id="
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<Table.Row key={item.url}>
|
|
51
|
-
<Table.Cell>
|
|
52
|
-
<UniversalLink
|
|
53
|
-
item={item}
|
|
54
|
-
className="summary url"
|
|
55
|
-
title={item['@type']}
|
|
56
|
-
>
|
|
57
|
-
{item.title}
|
|
58
|
-
</UniversalLink>
|
|
59
|
-
</Table.Cell>
|
|
60
|
-
<Table.Cell>{item.description}</Table.Cell>
|
|
61
|
-
<Table.Cell>{item['@type']}</Table.Cell>
|
|
62
|
-
<Table.Cell>{item.review_state}</Table.Cell>
|
|
19
|
+
const TabularView = ({ content }) => {
|
|
20
|
+
const Container =
|
|
21
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Container className="view-wrapper">
|
|
25
|
+
<article id="content">
|
|
26
|
+
<header>
|
|
27
|
+
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
28
|
+
{content.description && (
|
|
29
|
+
<p className="documentDescription">{content.description}</p>
|
|
30
|
+
)}
|
|
31
|
+
</header>
|
|
32
|
+
<section id="content-core">
|
|
33
|
+
<Table celled padded>
|
|
34
|
+
<Table.Header>
|
|
35
|
+
<Table.Row>
|
|
36
|
+
<Table.HeaderCell>
|
|
37
|
+
<FormattedMessage id="Title" defaultMessage="Title" />
|
|
38
|
+
</Table.HeaderCell>
|
|
39
|
+
<Table.HeaderCell>
|
|
40
|
+
<FormattedMessage
|
|
41
|
+
id="Description"
|
|
42
|
+
defaultMessage="Description"
|
|
43
|
+
/>
|
|
44
|
+
</Table.HeaderCell>
|
|
45
|
+
<Table.HeaderCell>
|
|
46
|
+
<FormattedMessage id="Type" defaultMessage="Type" />
|
|
47
|
+
</Table.HeaderCell>
|
|
48
|
+
<Table.HeaderCell>
|
|
49
|
+
<FormattedMessage id="State" defaultMessage="State" />
|
|
50
|
+
</Table.HeaderCell>
|
|
63
51
|
</Table.Row>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
</Table.Header>
|
|
53
|
+
<Table.Body>
|
|
54
|
+
{content.items.map((item) => (
|
|
55
|
+
<Table.Row key={item.url}>
|
|
56
|
+
<Table.Cell>
|
|
57
|
+
<UniversalLink
|
|
58
|
+
item={item}
|
|
59
|
+
className="summary url"
|
|
60
|
+
title={item['@type']}
|
|
61
|
+
>
|
|
62
|
+
{item.title}
|
|
63
|
+
</UniversalLink>
|
|
64
|
+
</Table.Cell>
|
|
65
|
+
<Table.Cell>{item.description}</Table.Cell>
|
|
66
|
+
<Table.Cell>{item['@type']}</Table.Cell>
|
|
67
|
+
<Table.Cell>{item.review_state}</Table.Cell>
|
|
68
|
+
</Table.Row>
|
|
69
|
+
))}
|
|
70
|
+
</Table.Body>
|
|
71
|
+
</Table>
|
|
72
|
+
</section>
|
|
73
|
+
</article>
|
|
74
|
+
</Container>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
71
77
|
|
|
72
78
|
/**
|
|
73
79
|
* Property types.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default (props)
|
|
1
|
+
export default function Blocks(props) {
|
|
2
2
|
const { draftJs, immutableLib } = props;
|
|
3
3
|
const { DefaultDraftBlockRenderMap } = draftJs;
|
|
4
4
|
const { Map } = immutableLib;
|
|
@@ -27,4 +27,4 @@ export default (props) => {
|
|
|
27
27
|
const listBlockTypes = ['unordered-list-item', 'ordered-list-item'];
|
|
28
28
|
|
|
29
29
|
return { extendedBlockRenderMap, blockStyleFn, listBlockTypes };
|
|
30
|
-
}
|
|
30
|
+
}
|
|
@@ -13,7 +13,7 @@ import orderedListSVG from '@plone/volto/icons/list-numbered.svg';
|
|
|
13
13
|
import blockquoteSVG from '@plone/volto/icons/quote.svg';
|
|
14
14
|
import calloutSVG from '@plone/volto/icons/megaphone.svg';
|
|
15
15
|
|
|
16
|
-
export default function (props) {
|
|
16
|
+
export default function Styles(props) {
|
|
17
17
|
const createInlineStyleButton = props.draftJsCreateInlineStyleButton.default;
|
|
18
18
|
const createBlockStyleButton = props.draftJsCreateBlockStyleButton.default;
|
|
19
19
|
|
package/src/config/index.js
CHANGED
package/src/config/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import imagesMiddleware from '@plone/volto/express-middleware/images';
|
|
2
2
|
import filesMiddleware from '@plone/volto/express-middleware/files';
|
|
3
3
|
import robotstxtMiddleware from '@plone/volto/express-middleware/robotstxt';
|
|
4
|
+
import okMiddleware from '@plone/volto/express-middleware/ok';
|
|
4
5
|
import sitemapMiddleware from '@plone/volto/express-middleware/sitemap';
|
|
5
6
|
import staticsMiddleware from '@plone/volto/express-middleware/static';
|
|
6
7
|
import devProxyMiddleware from '@plone/volto/express-middleware/devproxy';
|
|
@@ -11,6 +12,7 @@ const settings = {
|
|
|
11
12
|
filesMiddleware(),
|
|
12
13
|
imagesMiddleware(),
|
|
13
14
|
robotstxtMiddleware(),
|
|
15
|
+
okMiddleware(),
|
|
14
16
|
sitemapMiddleware(),
|
|
15
17
|
staticsMiddleware(),
|
|
16
18
|
],
|
package/src/constants/Indexes.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module constants/indexes
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const Indexes = {
|
|
7
7
|
sortable_title: { label: 'Title', type: 'string', sort_on: 'sortable_title' },
|
|
8
8
|
review_state: { label: 'Review state', type: 'string' },
|
|
9
9
|
ModificationDate: {
|
|
@@ -35,6 +35,8 @@ export default {
|
|
|
35
35
|
Type: { label: 'Type', type: 'string' },
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
export default Indexes;
|
|
39
|
+
|
|
38
40
|
export const defaultIndexes = [
|
|
39
41
|
'review_state',
|
|
40
42
|
'ModificationDate',
|
|
@@ -9,7 +9,7 @@ const HEADERS = [
|
|
|
9
9
|
'Content-Type',
|
|
10
10
|
];
|
|
11
11
|
|
|
12
|
-
function
|
|
12
|
+
function filesMiddlewareFn(req, res, next) {
|
|
13
13
|
getAPIResourceWithAuth(req)
|
|
14
14
|
.then((resource) => {
|
|
15
15
|
// Just forward the headers that we need
|
|
@@ -24,10 +24,10 @@ function fileMiddleware(req, res, next) {
|
|
|
24
24
|
.catch(next);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export default function () {
|
|
27
|
+
export default function filesMiddleware() {
|
|
28
28
|
const middleware = express.Router();
|
|
29
29
|
|
|
30
|
-
middleware.all(['**/@@download/*', '**/@@display-file/*'],
|
|
30
|
+
middleware.all(['**/@@download/*', '**/@@display-file/*'], filesMiddlewareFn);
|
|
31
31
|
middleware.id = 'filesResourcesProcessor';
|
|
32
32
|
return middleware;
|
|
33
33
|
}
|
|
@@ -3,7 +3,7 @@ import { getAPIResourceWithAuth } from '@plone/volto/helpers';
|
|
|
3
3
|
|
|
4
4
|
const HEADERS = ['content-type', 'content-disposition', 'cache-control'];
|
|
5
5
|
|
|
6
|
-
function
|
|
6
|
+
function imageMiddlewareFn(req, res, next) {
|
|
7
7
|
getAPIResourceWithAuth(req)
|
|
8
8
|
.then((resource) => {
|
|
9
9
|
// Just forward the headers that we need
|
|
@@ -17,11 +17,11 @@ function imageMiddleware(req, res, next) {
|
|
|
17
17
|
.catch(next);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export default function () {
|
|
20
|
+
export default function imagesMiddleware() {
|
|
21
21
|
const middleware = express.Router();
|
|
22
22
|
|
|
23
|
-
middleware.all(['**/@@images/*'],
|
|
24
|
-
middleware.all(['/@portrait/*'],
|
|
23
|
+
middleware.all(['**/@@images/*'], imageMiddlewareFn);
|
|
24
|
+
middleware.all(['/@portrait/*'], imageMiddlewareFn);
|
|
25
25
|
middleware.id = 'imageResourcesProcessor';
|
|
26
26
|
return middleware;
|
|
27
27
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import config from '@plone/volto/registry';
|
|
3
|
+
|
|
4
|
+
const ok = function (req, res, next) {
|
|
5
|
+
res.type('text/plain');
|
|
6
|
+
res.set('Expires', 'Sat, 1 Jan 2000 00:00:00 GMT');
|
|
7
|
+
res.set('Cache-Control', 'max-age=0, must-revalidate, private');
|
|
8
|
+
res.send('ok');
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function () {
|
|
12
|
+
const middleware = express.Router();
|
|
13
|
+
middleware.all(config?.settings?.okRoute || '/ok', ok);
|
|
14
|
+
middleware.id = 'ok';
|
|
15
|
+
return middleware;
|
|
16
|
+
}
|
|
@@ -22,7 +22,7 @@ const envRobots = function (req, res, next) {
|
|
|
22
22
|
res.send(process.env.VOLTO_ROBOTSTXT);
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export default function () {
|
|
25
|
+
export default function robotstxtMiddleware() {
|
|
26
26
|
const middleware = express.Router();
|
|
27
27
|
if (process.env.VOLTO_ROBOTSTXT) {
|
|
28
28
|
middleware.all('**/robots.txt', envRobots);
|
|
@@ -2,7 +2,7 @@ import express from 'express';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import config from '@plone/volto/registry';
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const staticMiddlewareFn = express.static(
|
|
6
6
|
process.env.BUILD_DIR
|
|
7
7
|
? path.join(process.env.BUILD_DIR, 'public')
|
|
8
8
|
: process.env.RAZZLE_PUBLIC_DIR,
|
|
@@ -24,9 +24,9 @@ const staticMiddleware = express.static(
|
|
|
24
24
|
},
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
export default function () {
|
|
27
|
+
export default function staticsMiddleware() {
|
|
28
28
|
const middleware = express.Router();
|
|
29
|
-
middleware.all('*',
|
|
29
|
+
middleware.all('*', staticMiddlewareFn);
|
|
30
30
|
middleware.id = 'staticResourcesProcessor';
|
|
31
31
|
return middleware;
|
|
32
32
|
}
|
package/src/helpers/Url/Url.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module helpers/Url
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { last, memoize } from 'lodash';
|
|
6
|
+
import { last, memoize, isArray, isObject, isString } from 'lodash';
|
|
7
7
|
import { urlRegex, telRegex, mailRegex } from './urlRegex';
|
|
8
8
|
import prependHttp from 'prepend-http';
|
|
9
9
|
import config from '@plone/volto/registry';
|
|
@@ -251,6 +251,27 @@ export function isUrl(url) {
|
|
|
251
251
|
return urlRegex().test(url);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Get field url
|
|
256
|
+
* @method getFieldURL
|
|
257
|
+
* @param {object} data
|
|
258
|
+
* @returns {string | any} URL string value if field is of url type or any.
|
|
259
|
+
*/
|
|
260
|
+
export const getFieldURL = (data) => {
|
|
261
|
+
let url = data;
|
|
262
|
+
const _isObject = data && isObject(data) && !isArray(data);
|
|
263
|
+
if (_isObject && data['@type'] === 'URL') {
|
|
264
|
+
url = data['value'] ?? data['url'] ?? data['href'] ?? data;
|
|
265
|
+
} else if (_isObject) {
|
|
266
|
+
url = data['@id'] ?? data['url'] ?? data['href'] ?? data;
|
|
267
|
+
}
|
|
268
|
+
if (isArray(data)) {
|
|
269
|
+
url = data.map((item) => getFieldURL(item));
|
|
270
|
+
}
|
|
271
|
+
if (isString(url) && isInternalURL(url)) return flattenToAppURL(url);
|
|
272
|
+
return url;
|
|
273
|
+
};
|
|
274
|
+
|
|
254
275
|
/**
|
|
255
276
|
* Normalize URL, adds protocol (if required eg. user has not entered the protocol)
|
|
256
277
|
* @method normalizeUrl
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isCmsUi,
|
|
11
11
|
isInternalURL,
|
|
12
12
|
isUrl,
|
|
13
|
+
getFieldURL,
|
|
13
14
|
normalizeUrl,
|
|
14
15
|
removeProtocol,
|
|
15
16
|
addAppURL,
|
|
@@ -260,6 +261,46 @@ describe('Url', () => {
|
|
|
260
261
|
expect(isUrl(href)).toBe(false);
|
|
261
262
|
});
|
|
262
263
|
});
|
|
264
|
+
describe('getFieldURL', () => {
|
|
265
|
+
it('returns app URL if the field is a string', () => {
|
|
266
|
+
const field = `${settings.apiPath}/foo/bar`;
|
|
267
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
268
|
+
});
|
|
269
|
+
it('returns app URL if the field is an object with "@id"', () => {
|
|
270
|
+
const field = { '@id': '/foo/bar' };
|
|
271
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
272
|
+
});
|
|
273
|
+
it('returns app URL if the field is an object with type URL', () => {
|
|
274
|
+
const field = { '@type': 'URL', value: '/foo/bar' };
|
|
275
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
276
|
+
});
|
|
277
|
+
it('returns app URL if the field is an object with url or href properties', () => {
|
|
278
|
+
const fieldUrl = { url: '/foo/bar' };
|
|
279
|
+
const fieldHref = { href: '/foo/bar' };
|
|
280
|
+
expect(getFieldURL(fieldUrl)).toBe('/foo/bar');
|
|
281
|
+
expect(getFieldURL(fieldHref)).toBe('/foo/bar');
|
|
282
|
+
});
|
|
283
|
+
it('returns array of app URL if the field is an array of strings', () => {
|
|
284
|
+
const field = [
|
|
285
|
+
`${settings.apiPath}/foo/bar/1`,
|
|
286
|
+
`${settings.apiPath}/foo/bar/2`,
|
|
287
|
+
];
|
|
288
|
+
expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']);
|
|
289
|
+
});
|
|
290
|
+
it('returns array of app URL if the field is an array of objects', () => {
|
|
291
|
+
const field = [
|
|
292
|
+
{
|
|
293
|
+
'@type': 'URL',
|
|
294
|
+
value: `${settings.apiPath}/foo/bar/1`,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
'@type': 'URL',
|
|
298
|
+
value: `${settings.apiPath}/foo/bar/2`,
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
263
304
|
describe('normalizeUrl', () => {
|
|
264
305
|
it('normalizeUrl test', () => {
|
|
265
306
|
const href = `www.example.com`;
|
package/src/helpers/index.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// export { injectLazyLibs } from './Loadable/Loadable';
|
|
8
|
-
export Api from '@plone/volto/helpers/Api/Api';
|
|
8
|
+
export { default as Api } from '@plone/volto/helpers/Api/Api';
|
|
9
9
|
export { getAPIResourceWithAuth } from '@plone/volto/helpers/Api/APIResourceWithAuth';
|
|
10
|
-
export Html from '@plone/volto/helpers/Html/Html';
|
|
10
|
+
export { default as Html } from '@plone/volto/helpers/Html/Html';
|
|
11
11
|
export {
|
|
12
12
|
getAuthToken,
|
|
13
13
|
persistAuthToken,
|
|
@@ -59,8 +59,8 @@ export {
|
|
|
59
59
|
buildStyleClassNamesExtenders,
|
|
60
60
|
getPreviousNextBlock,
|
|
61
61
|
} from '@plone/volto/helpers/Blocks/Blocks';
|
|
62
|
-
export BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
|
|
63
|
-
export ScrollToTop from '@plone/volto/helpers/ScrollToTop/ScrollToTop';
|
|
62
|
+
export { default as BodyClass } from '@plone/volto/helpers/BodyClass/BodyClass';
|
|
63
|
+
export { default as ScrollToTop } from '@plone/volto/helpers/ScrollToTop/ScrollToTop';
|
|
64
64
|
export {
|
|
65
65
|
getBoolean,
|
|
66
66
|
getVocabName,
|
|
@@ -70,11 +70,10 @@ export {
|
|
|
70
70
|
getFieldsVocabulary,
|
|
71
71
|
} from '@plone/volto/helpers/Vocabularies/Vocabularies';
|
|
72
72
|
|
|
73
|
-
export langmap from './LanguageMap/LanguageMap';
|
|
74
|
-
export Helmet from './Helmet/Helmet';
|
|
75
|
-
export FormValidation
|
|
76
|
-
|
|
77
|
-
} from './FormValidation/FormValidation';
|
|
73
|
+
export { default as langmap } from './LanguageMap/LanguageMap';
|
|
74
|
+
export { default as Helmet } from './Helmet/Helmet';
|
|
75
|
+
export { default as FormValidation } from './FormValidation/FormValidation';
|
|
76
|
+
export { validateFileUploadSize } from './FormValidation/FormValidation';
|
|
78
77
|
export {
|
|
79
78
|
difference,
|
|
80
79
|
getColor,
|
|
@@ -111,7 +110,7 @@ export { useDetectClickOutside } from './Utils/useDetectClickOutside';
|
|
|
111
110
|
export { useEvent } from './Utils/useEvent';
|
|
112
111
|
export { usePrevious } from './Utils/usePrevious';
|
|
113
112
|
export { usePagination } from './Utils/usePagination';
|
|
114
|
-
export useUndoManager from './UndoManager/useUndoManager';
|
|
113
|
+
export { default as useUndoManager } from './UndoManager/useUndoManager';
|
|
115
114
|
export { getCookieOptions } from './Cookies/cookies';
|
|
116
115
|
export { getWidgetView } from './Widget/widget';
|
|
117
116
|
export {
|