Created
November 28, 2017 00:21
-
-
Save mattheu/e39544891ac195968c0c3343d4a3ee32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
import PropTypes from 'prop-types'; | |
import classNames from 'classnames'; | |
import _ from 'lodash'; | |
// Simple row block. | |
const Row = ({ children = [] }) => { | |
return <div className="block block-row sun-row-v3"> | |
{ children.map( ( block, i ) => <Block key={ i } {...block} /> ) } | |
</div> | |
} | |
// Simple column block. | |
const Column = ({ span = 1, hspan = 1, children = [] }) => { | |
const colClassName = classNames( 'col', `col-span-${span}`, `col-hspan-${hspan}`, 'block', 'becomes-small' ); | |
return <div className={ colClassName }> | |
{ children.map( ( block, i ) => <Block key={ i } {...block} /> ) } | |
</div> | |
} | |
// Other blocks for demonstration only - these components would come from the component library. | |
const Teaser = props => <p>Teaser { props.postId }</p> | |
const Iframe = props => <p>Iframe { props.src }</p> | |
const Ad = props => <p>Ad</p> | |
/** | |
* Generic Block. | |
* | |
* This component is just a wrapper for the real block component | |
* that handles mapping the block type to a component and flattening the attributes to component props. | |
* If block type is unknown, returns null. | |
*/ | |
const Block = ({ type, attributes = {}, children = [] }) => { | |
const blockComponentMap = { | |
column: Column, | |
row: Row, | |
teaser: Teaser, | |
iframe: Iframe, | |
ad: Ad, | |
} | |
const BlockComponent = _.get( blockComponentMap, type, null ); | |
return BlockComponent && <BlockComponent | |
{...attributes} | |
children={children} | |
/> | |
} | |
// Top level component. | |
const Layout = ({ children = [] }) => { | |
return <div className="sun-customiser-v2"> | |
{ children.map( ( block, i ) => <Block key={ i } {...block} /> ) } | |
</div> | |
} | |
fetch( 'http://www-features.uat-thesun.co.uk/wp-json/nu-wp-customiser/v1/layouts/1613013', { | |
method: 'get' | |
}).then( response => { | |
return response.json(); | |
}).then( layout => { | |
ReactDOM.render(<Layout {...layout}/>, document.getElementById('preview')); | |
}); | |
// Questions. | |
// | |
// Normalizing data. | |
// | |
// The data we return may not match up to exactly what you need to render the component. | |
// EG teasers only store the ID, and only includes other attributes when they are set to override the core post data. | |
// For these blocks you'll need to normalize the data with the post data provided. | |
// This could either be done at the top level before rendering the tree, | |
// Or you could create a wrapper component for the teasers, which handles formatting the data. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment