Skip to content

Instantly share code, notes, and snippets.

@mattheu
Created November 28, 2017 00:21
Show Gist options
  • Save mattheu/e39544891ac195968c0c3343d4a3ee32 to your computer and use it in GitHub Desktop.
Save mattheu/e39544891ac195968c0c3343d4a3ee32 to your computer and use it in GitHub Desktop.
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