- Forests are intimately linked to Romania's cultural,
- economic, social and historical development. The country
- is located in the continental temperate region, with a
- varied relief ranging from seaside to mountain.
-
-
-
-
-
-
-
-
-
-
Tree species lost
-
-
12
-
- species threatened by extinction
-
-
-
-
- Conifer
- 8 species
-
-
- Broadleaved
- 4 species
-
-
-
Integer magna nunc, scelerisque in lacinia nec.
-
-
- From 2001 to 2018, Romania lost 336kha of tree cover.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Species Coverage
-
- Vestibulum eget est ac lorem dapibus lacinia.
- Integer magna nunc, scelerisque in lacinia nec,
- laoreet non augue. Nunc quis pharetra magna, in
- convallis ligula.
-
-
-
- From 2001 to 2018, Romania lost 336kha of tree cover.
-
-
- Forests are rich in biodiversity and valuable for recreation,
- water regulation and soil protection. As well as for providing
- timber and other non-wood forest products, forests are important
- for mitigating climate change and for the renewable energy
- sector.
-
-
-
-
-
-
Other reports and publications
-
-
-
-
- State of Europe’s Forests 2018 Report
-
-
-
-
-
- Romania: National Forest Data 2017
-
-
-
-
-
- State of Europe’s Forests 2017 Report
-
-
-
-
-
- Romania: Lorem ipsum documentarium 2014
-
-
-
-
-
- Romania: National Forest Data 2017
-
-
-
-
-
- State of Europe’s Forests 2017 Report
-
-
-
-
-
- Romania: Lorem ipsum documentarium 2014
-
-
-
-
-
-
-
- ) : (
-
- {content.description && (
-
{content.description}
- )}
- {content.image && (
-
- )}
- {content.remoteUrl && (
-
- The link address is:
- {content.remoteUrl}
-
- )}
- {content.text && (
-
- )}
-
- );
- }
-}
-
-export default connect(
- (state) => ({
- tabs: state.folder_tabs.items,
- parent: state.parent_folder_data.items,
- }),
- mapDispatchToProps,
-)(CountryPageView);
diff --git a/src/customizations/volto/actions/content/content.js b/src/customizations/volto/actions/content/content.js
index 1df077c..fab0dd7 100644
--- a/src/customizations/volto/actions/content/content.js
+++ b/src/customizations/volto/actions/content/content.js
@@ -11,6 +11,8 @@ import {
ORDER_CONTENT,
RESET_CONTENT,
UPDATECOLUMNS_CONTENT,
+ LOCK_CONTENT,
+ UNLOCK_CONTENT,
} from '@plone/volto/constants/ActionTypes';
import { nestContent } from '@plone/volto/helpers';
import config from '@plone/volto/registry';
@@ -199,3 +201,45 @@ export function updateColumnsContent(url, index) {
indexcolumns: index,
};
}
+
+/**
+ * Lock content function.
+ * @function lockContent
+ * @param {string} urls Content url(s)
+ * @returns {Object} Lock content action.
+ */
+export function lockContent(urls) {
+ return {
+ type: LOCK_CONTENT,
+ mode: 'serial',
+ request:
+ typeof urls === 'string'
+ ? { op: 'post', path: `${urls}/@lock` }
+ : urls.map((url) => ({ op: 'post', path: `${url}/@lock` })),
+ };
+}
+
+/**
+ * Unlock content function.
+ * @function unlockContent
+ * @param {string|Array} urls Content url(s).
+ * @returns {Object} Unlock content action.
+ */
+export function unlockContent(urls, force = false) {
+ return {
+ type: UNLOCK_CONTENT,
+ mode: 'serial',
+ request:
+ typeof urls === 'string'
+ ? {
+ op: 'del',
+ path: `${urls}/@lock`,
+ data: force ? { force: true } : {},
+ }
+ : urls.map((url) => ({
+ op: 'del',
+ path: `${url}/@lock`,
+ data: force ? { force: true } : {},
+ })),
+ };
+}
diff --git a/src/customizations/volto/helpers/Html/Html.jsx b/src/customizations/volto/helpers/Html/Html.jsx
index 9c1db2e..f448654 100644
--- a/src/customizations/volto/helpers/Html/Html.jsx
+++ b/src/customizations/volto/helpers/Html/Html.jsx
@@ -5,11 +5,33 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { Helmet } from '@plone/volto/helpers';
+import Helmet from '@plone/volto/helpers/Helmet/Helmet';
import serialize from 'serialize-javascript';
import { join } from 'lodash';
-import { BodyClass } from '@plone/volto/helpers';
+import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
import { runtimeConfig } from '@plone/volto/runtime_config';
+import config from '@plone/volto/registry';
+
+const CRITICAL_CSS_TEMPLATE = `function alter() {
+ document.querySelectorAll("head link[rel='prefetch']").forEach(function(el) { el.rel = 'stylesheet'});
+ }
+ if (window.addEventListener) {
+ window.addEventListener('DOMContentLoaded', alter, false)
+ } else {
+ window.onload=alter
+ }`;
+
+export const loadReducers = (state = {}) => {
+ const { settings } = config;
+ return Object.assign(
+ {},
+ ...Object.keys(state).map((name) =>
+ settings.initialReducersBlacklist.includes(name)
+ ? {}
+ : { [name]: state[name] },
+ ),
+ );
+};
/**
* Html class.
@@ -20,6 +42,14 @@ import { runtimeConfig } from '@plone/volto/runtime_config';
* The only thing this component doesn't (and can't) include is the
* HTML doctype declaration, which is added to the rendered output
* by the server.js file.
+ *
+ * Critical.css behaviour: when a file `public/critical.css` is present, the
+ * loading of stylesheets is changed. The styles in critical.css are inlined in
+ * the generated HTML, and the whole story needs to change completely: instead
+ * of treating stylesheets as priority for rendering, we want to defer their
+ * loading as much as possible. So we change the stylesheets to be prefetched
+ * and we switch their rel back to stylesheets at document ready event.
+ *
* @function Html
* @param {Object} props Component properties.
* @param {Object} props.assets Assets to be rendered.
@@ -57,11 +87,16 @@ class Html extends Component {
* @returns {string} Markup for the component.
*/
render() {
- const { extractor, markup, store } = this.props;
+ const {
+ extractor,
+ markup,
+ store,
+ criticalCss,
+ apiPath,
+ publicURL,
+ } = this.props;
const head = Helmet.rewind();
const bodyClass = join(BodyClass.rewind(), ' ');
- const pathName = store.getState()?.router.location.pathname;
- const renderScripts = ['/header', '/head', '/footer'].includes(pathName);
return (
@@ -69,32 +104,79 @@ class Html extends Component {
{head.base.toComponent()}
{head.title.toComponent()}
{head.meta.toComponent()}
- {!renderScripts && head.link.toComponent()}
- {!renderScripts && head.script.toComponent()}
+ {head.link.toComponent()}
+ {head.script.toComponent()}
-
-
+
+
+
+
+
+ {process.env.NODE_ENV === 'production' && criticalCss && (
+
+ )}
{/* Add the crossorigin while in development */}
- {!renderScripts &&
- extractor.getLinkElements().map((elem) =>
- React.cloneElement(elem, {
- crossOrigin:
- process.env.NODE_ENV === 'production' ? undefined : 'true',
- }),
- )}
- {/* Styles in development are loaded with Webpack's style-loader, in production,
- they need to be static*/}
- {!renderScripts && process.env.NODE_ENV === 'production' && (
- <>{extractor.getStyleElements()}>
+ {extractor.getLinkElements().map((elem) =>
+ React.cloneElement(elem, {
+ crossOrigin:
+ process.env.NODE_ENV === 'production' ? undefined : 'true',
+ rel: !criticalCss
+ ? elem.props.rel
+ : elem.props.as === 'style'
+ ? 'prefetch'
+ : elem.props.rel,
+ }),
)}
+ {/* Styles in development are loaded with Webpack's style-loader, in production,
+ they need to be static*/}
+ {process.env.NODE_ENV === 'production' ? (
+ criticalCss ? (
+ <>
+
+ {extractor.getStyleElements().map((elem) => (
+
+ ))}
+ >
+ ) : (
+ extractor.getStyleElements()
+ )
+ ) : undefined}
@@ -102,12 +184,14 @@ class Html extends Component {
{/* Add the crossorigin while in development */}
- {!renderScripts && this.props.extractScripts !== false
+ {this.props.extractScripts !== false
? extractor.getScriptElements().map((elem) =>
React.cloneElement(elem, {
crossOrigin:
@@ -120,4 +204,5 @@ class Html extends Component {
);
}
}
+
export default Html;