Last active
October 8, 2016 21:33
-
-
Save asmagin/707e25fd2c0617a4b7b271f89569de00 to your computer and use it in GitHub Desktop.
Sitecore + React
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
'use strict'; | |
let path = require('path'); | |
let webpack = require('webpack'); | |
let baseConfig = require('./base'); | |
let defaultSettings = require('./defaults'); | |
// Add needed plugins here | |
let BowerWebpackPlugin = require('bower-webpack-plugin'); | |
let config = Object.assign({}, baseConfig, { | |
entry: { | |
app: path.join(__dirname, '../src/index'), | |
components: path.join(__dirname, '../src/server.js') | |
}, | |
output: { | |
path: path.join(__dirname, '/../dist/assets'), | |
filename: '[name].js', | |
publicPath: defaultSettings.publicPath | |
}, | |
cache: false, | |
devtool: 'eval-source-map', | |
plugins: [ | |
new webpack.HotModuleReplacementPlugin(), | |
new webpack.NoErrorsPlugin(), | |
new BowerWebpackPlugin({ | |
searchResolveModulesDirectories: false | |
}) | |
], | |
module: defaultSettings.getDefaultModules() | |
}); | |
// Add needed loaders to the defaults here | |
config.module.loaders.push({ | |
test: /\.(js|jsx)$/, | |
loader: 'babel', | |
include: [].concat( | |
config.additionalPaths, | |
[ path.join(__dirname, '/../src') ] | |
) | |
}); | |
module.exports = config; |
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
module.exports = { | |
// All the components you'd like to render server-side | |
HeaderComponent: require('./HeaderComponent'), | |
SimpleContentComponent: require('./SimpleContentComponent') | |
}; |
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
var Components = require('expose?Components!./components/common'); |
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
'use strict'; | |
import React from 'react'; | |
import { Grid, Row, Col } from 'react-bootstrap' | |
require('styles/common/SimpleContent.css'); | |
let yeomanImage = require('../../images/yeoman.png'); | |
var SimpleContentComponent = React.createClass({ | |
propTypes: { | |
data: React.PropTypes.shape({ | |
image: React.PropTypes.string, | |
title: React.PropTypes.string, | |
text: React.PropTypes.string | |
}).isRequired , | |
placeholders: React.PropTypes.shape({ | |
leftColumn: React.PropTypes.string, | |
rightColumn: React.PropTypes.string | |
}).isRequired | |
}, | |
getDefaultProps: function() { | |
return { | |
data: { | |
image: '<img src="' + yeomanImage + '">', | |
title: 'SAMPLE: My First Sc.React Component', | |
text: 'SAMPLE: When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc.) into reusable components with well-defined interfaces. <br/> That way, the next time you need to build some UI, you can write much less code. This means faster development time, fewer bugs, and fewer bytes down the wire.text' | |
}, | |
placeholders: { | |
leftColumn: '', | |
rightColumn: '' | |
} | |
}; | |
}, | |
// this function would be called by ReactJS.NET to identify placeholders avaliable in a component. | |
getPlaceholders: function() { | |
return 'leftColumn|rightColumn'; | |
}, | |
render: function() { | |
return ( | |
<Grid> | |
<Row> | |
<Col xs={12} md={4}><div dangerouslySetInnerHTML={{ __html: this.props.data.image }} /></Col> | |
<Col xs={12} md={8}> | |
<h1><div dangerouslySetInnerHTML={{ __html: this.props.data.title }} /></h1> | |
<div className='rte'> | |
<div dangerouslySetInnerHTML={{ __html: this.props.data.text }} /> | |
</div> | |
</Col> | |
</Row> | |
<Row> | |
<Col xs={12} md={6}><div dangerouslySetInnerHTML={{ __html: this.props.placeholders.leftColumn }} /></Col> | |
<Col xs={12} md={6}><div dangerouslySetInnerHTML={{ __html: this.props.placeholders.rightColumn }} /></Col> | |
</Row> | |
</Grid> | |
) | |
} | |
}); | |
module.exports = SimpleContentComponent; |
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
using System; | |
using System.Collections.Generic; | |
using System.Dynamic; | |
using System.IO; | |
using System.Web.Mvc; | |
using Epam.Sc.EngX.CodeGeneration.Domain; | |
using Glass.Mapper.Sc; | |
using React; | |
using Sitecore.Data; | |
using Sitecore.Diagnostics; | |
using Sitecore.Mvc.Controllers; | |
using Sitecore.Mvc.Pipelines; | |
using Sitecore.Mvc.Pipelines.Response.RenderPlaceholder; | |
using Sitecore.Mvc.Presentation; | |
namespace Smagin.Common.Sc.Mvc.Controllers | |
{ | |
public class SitecoreReactController : SitecoreController | |
{ | |
private const string JsFunctionToGetPlaceholdersInfo = @" | |
(function(obj){{ | |
if (typeof obj === 'undefined' | |
|| typeof obj.prototype.getPlaceholders !== 'function' ) {{ | |
return []; | |
}} | |
return obj.prototype.getPlaceholders(); | |
}})({0}) | |
"; | |
protected readonly ISitecoreContext Context; | |
public SitecoreReactController() : this(new SitecoreContext()) | |
{ | |
} | |
public SitecoreReactController(ISitecoreContext context) | |
{ | |
Context = context; | |
} | |
/// <summary> | |
/// Get current data source object and cast it to a specific model | |
/// </summary> | |
/// <typeparam name="T">Class, that implements IGlassBase interface</typeparam> | |
/// <returns>Retunrs and instance of T type</returns> | |
public T DataSource<T>() where T : class, IGlassBase | |
{ | |
var datasourceId = RenderingContext.Current.Rendering.DataSource; | |
if (ID.IsID(datasourceId)) | |
{ | |
return Context.GetItem<T>(new Guid(datasourceId)); | |
} | |
return Context.GetCurrentItem<T>(); | |
} | |
/// <summary> | |
/// Generate a content of a placeholder into a string | |
/// </summary> | |
/// <param name="placeholderName">Name of a placeholder</param> | |
/// <param name="rendering">Rendering definition object</param> | |
/// <returns>Returns string with a rendered placeholder content</returns> | |
protected virtual string Placeholder(string placeholderName, Rendering rendering) | |
{ | |
Assert.ArgumentNotNull(placeholderName, "placeholderName"); | |
var stringWriter = new StringWriter(); | |
PipelineService.Get() | |
.RunPipeline("mvc.renderPlaceholder", | |
new RenderPlaceholderArgs(placeholderName, stringWriter, rendering)); | |
return stringWriter.ToString(); | |
} | |
/// <summary> | |
/// Generate component ReactJS action results | |
/// </summary> | |
/// <param name="componentName">Name of a component exposed from a js package</param> | |
/// <param name="model">Data to be passed into a component</param> | |
/// <param name="renderContainerOnly">Render only container flag</param> | |
/// <param name="renderServerOnly">Use only server-side rendering code</param> | |
/// <returns>ActionResult object</returns> | |
public virtual ActionResult React(string componentName, object model, bool renderContainerOnly = false, | |
bool renderServerOnly = false) | |
{ | |
return React(componentName, model, RenderingContext.Current.Rendering, renderContainerOnly, renderServerOnly); | |
} | |
/// <summary> | |
/// Generate component ReactJS action results | |
/// </summary> | |
/// <param name="componentName">Name of a component exposed from a js package</param> | |
/// <param name="model">Data to be passed into a component</param> | |
/// <param name="rendering">Rendering definition object</param> | |
/// <param name="renderContainerOnly">Render only container flag</param> | |
/// <param name="renderServerOnly">Use only server-side rendering code</param> | |
/// <returns>ActionResult object</returns> | |
public virtual ActionResult React(string componentName, object model, Rendering rendering, | |
bool renderContainerOnly = false, bool renderServerOnly = false) | |
{ | |
// Get placeholders meta information from a React Component. List of placeholders separated by pipe | |
var placeholderKeys = | |
ReactEnvironment.Current.Execute<string>(string.Format(JsFunctionToGetPlaceholdersInfo, componentName)) ?? ""; | |
// Create dynamic object to convert dictionary keys into object properties | |
dynamic placeholders = new ExpandoObject(); | |
var placeholdersDictionary = (IDictionary<string, object>) placeholders; | |
foreach (var placeholderKey in placeholderKeys.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries)) | |
{ | |
placeholdersDictionary.Add(placeholderKey, Placeholder(placeholderKey, rendering)); | |
} | |
// Create ReactJS component props object | |
var reactComponent = ReactEnvironment.Current.CreateComponent(componentName, new | |
{ | |
data = model, | |
placeholders | |
}); | |
// Render ReactJS component | |
return Content(reactComponent.RenderHtml(renderContainerOnly, renderServerOnly)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment