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"