diff --git a/server/.babelrc b/server/.babelrc
index 0a6827e861..3d5fbb9742 100644
--- a/server/.babelrc
+++ b/server/.babelrc
@@ -11,5 +11,5 @@
"views/partials/analytics.js.njk",
"views/partials/hotjar.js.njk"
],
- "plugins": ["transform-flow-strip-types"]
+ "plugins": ["transform-react-jsx", "transform-flow-strip-types"]
}
diff --git a/server/content-model/exhibition.js b/server/content-model/exhibition.js
index 44264c3f95..3c190a023c 100644
--- a/server/content-model/exhibition.js
+++ b/server/content-model/exhibition.js
@@ -1,6 +1,6 @@
// @flow
import {List} from 'immutable';
-import type {ImagePromo, DateRange} from './content-blocks';
+import type {ImagePromo} from './content-blocks';
import type {Picture} from '../model/picture';
import type {BodyPart} from '../model/body-part';
diff --git a/server/extensions/component-jsx.js b/server/extensions/component-jsx.js
new file mode 100644
index 0000000000..11f6c7829c
--- /dev/null
+++ b/server/extensions/component-jsx.js
@@ -0,0 +1,23 @@
+import nunjucks from 'nunjucks';
+import ReactDOMServer from 'react-dom/server';
+import * as components from '../views/components/jsx-components';
+
+export default class Component {
+ constructor(env) {
+ this.tags = ['componentJsx'];
+ this.env = env;
+ }
+
+ parse(parser, nodes, /*lexer*/) {
+ const token = parser.nextToken();
+ const args = parser.parseSignature(null, true);
+ parser.advanceAfterBlockEnd(token.value);
+
+ return new nodes.CallExtension(this, 'run', args);
+ };
+
+ run(_/*context*/, name, model) {
+ const html = ReactDOMServer.renderToString(components[name](model));
+ return new nunjucks.runtime.SafeString(html);
+ };
+};
diff --git a/server/extensions/index.js b/server/extensions/index.js
index 02deb437a1..d4d285a677 100644
--- a/server/extensions/index.js
+++ b/server/extensions/index.js
@@ -1,8 +1,9 @@
import {Map} from 'immutable';
import Component from './component';
import ComponentV2 from './component-v2';
+import ComponentJsx from './component-jsx';
import Icon from './icon';
export default Map({
- Component, ComponentV2, Icon
+ Component, ComponentV2, Icon, ComponentJsx
});
diff --git a/server/package.json b/server/package.json
index 524f581914..e4ec16b468 100644
--- a/server/package.json
+++ b/server/package.json
@@ -24,6 +24,7 @@
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
+ "babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.6.1",
"copy-webpack-plugin": "^4.2.3",
"entities": "^1.1.1",
@@ -45,6 +46,8 @@
"prismic-dom": "^1.2.6",
"prismic-javascript": "^1.3.0",
"raven": "^2.1.2",
+ "react": "^16.2.0",
+ "react-dom": "^16.2.0",
"rimraf": "^2.6.1",
"superagent": "^3.6.0",
"supertest": "^3.0.0",
diff --git a/server/views/components/jsx-components.js b/server/views/components/jsx-components.js
new file mode 100644
index 0000000000..857515d0a4
--- /dev/null
+++ b/server/views/components/jsx-components.js
@@ -0,0 +1,5 @@
+import JsxTestComponent from './jsx-test-component/jsx-test-component.js';
+
+export {
+ JsxTestComponent
+};
diff --git a/server/views/components/jsx-test-component/jsx-test-component.js b/server/views/components/jsx-test-component/jsx-test-component.js
new file mode 100644
index 0000000000..c94361636b
--- /dev/null
+++ b/server/views/components/jsx-test-component/jsx-test-component.js
@@ -0,0 +1,15 @@
+// Generic component to test using JSX with nunjucks
+import React from 'react';
+import cssGridClasses from '../../../filters/css-grid-classes';
+
+export default function JsxTestComponent(props) {
+ return (
+
+
+
+ Hello {props.toWhat}
+
+
+
+ );
+}
diff --git a/server/yarn.lock b/server/yarn.lock
index 8bb5a39df5..2194863c52 100644
--- a/server/yarn.lock
+++ b/server/yarn.lock
@@ -178,7 +178,7 @@ arrify@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
-asap@^2.0.3:
+asap@^2.0.3, asap@~2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
@@ -440,6 +440,14 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
+babel-helper-builder-react-jsx@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
+ dependencies:
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ esutils "^2.0.2"
+
babel-helper-call-delegate@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
@@ -613,6 +621,10 @@ babel-plugin-syntax-flow@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
+babel-plugin-syntax-jsx@^6.8.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+
babel-plugin-syntax-object-rest-spread@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
@@ -846,6 +858,14 @@ babel-plugin-transform-object-rest-spread@^6.22.0:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.26.0"
+babel-plugin-transform-react-jsx@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
+ dependencies:
+ babel-helper-builder-react-jsx "^6.24.1"
+ babel-plugin-syntax-jsx "^6.8.0"
+ babel-runtime "^6.22.0"
+
babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
@@ -1585,6 +1605,10 @@ core-assert@^0.2.0:
buf-compare "^1.0.0"
is-error "^2.2.0"
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+
core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
@@ -2145,6 +2169,18 @@ fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+fbjs@^0.8.16:
+ version "0.8.16"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.9"
+
fclone@1.0.11, fclone@^1:
version "1.0.11"
resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640"
@@ -2891,6 +2927,13 @@ isobject@^2.0.0:
dependencies:
isarray "1.0.0"
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
isomorphic-unfetch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-2.0.0.tgz#f50140a4c163d7582b5f37f1591968c4f809a645"
@@ -3192,7 +3235,7 @@ longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-loose-envify@^1.0.0:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@@ -3575,7 +3618,7 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
-object-assign@^4.0.1, object-assign@^4.1.0:
+object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -4101,12 +4144,26 @@ progress@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ dependencies:
+ asap "~2.0.3"
+
promptly@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/promptly/-/promptly-2.2.0.tgz#2a13fa063688a2a5983b161fff0108a07d26fc74"
dependencies:
read "^1.0.4"
+prop-types@^15.6.0:
+ version "15.6.0"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
prr@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
@@ -4192,6 +4249,24 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
+react-dom@^16.2.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
+react@^16.2.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
read-all-stream@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa"
@@ -4520,7 +4595,7 @@ set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@@ -5011,6 +5086,10 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+ua-parser-js@^0.7.9:
+ version "0.7.17"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
+
uglify-js@^2.8.29:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"