-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added an self-mounting components example.
These replicate much of the behaviour that was formerly available in python-react.
- Loading branch information
1 parent
056ca70
commit 72dda6c
Showing
16 changed files
with
413 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,4 +54,4 @@ docs/_build/ | |
target/ | ||
|
||
node_modules | ||
example/static/webpack | ||
.webpack_build_cache |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
static |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
python + react - self mounting components | ||
========================================= | ||
|
||
This example illustrates a workflow where webpack is used to generate bundles so that the root React | ||
component can immediately mount itself over the markup that was pre-rendered with the same data. | ||
|
||
This workflow is similar to what was provided in older versions of python-react. It can be useful | ||
if you want to add a little interactivity to an otherwise backend-heavy site. | ||
|
||
Be aware that while this workflow can be initially convenient, it tends to rely on components maintaining | ||
large amounts of state. A better workflow is for your components to minimize state by delegating all | ||
data storage to external services. If you're looking for something to handle your data, the multitude | ||
of Flux implementations are a reasonable starting point. | ||
|
||
|
||
### Running the example | ||
|
||
Install the dependencies | ||
|
||
``` | ||
pip install -r requirements.txt | ||
npm install | ||
``` | ||
|
||
Start the server | ||
|
||
``` | ||
node server.js | ||
``` | ||
|
||
Start the python server | ||
|
||
``` | ||
python example.py | ||
``` | ||
|
||
And visit [http://127.0.0.1:5000](http://127.0.0.1:5000) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
|
||
class Comment extends React.Component { | ||
render() { | ||
return ( | ||
<div> | ||
<h3>{this.props.name}</h3> | ||
{this.props.text} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default Comment; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
h2 { | ||
border-bottom: 1px solid #eee; | ||
} | ||
|
||
form label { | ||
display: block; | ||
} | ||
|
||
form button { | ||
margin-left: 5px; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// CSS dependencies | ||
import 'bootstrap/dist/css/bootstrap.css'; | ||
import './CommentBox.css'; | ||
|
||
import React from 'react'; | ||
import CommentList from './CommentList.jsx'; | ||
import CommentForm from './CommentForm.jsx'; | ||
import $ from 'jquery'; | ||
|
||
class CommentBox extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.state = {comments: props.comments}; | ||
} | ||
submitComment(name, text) { | ||
$.ajax({ | ||
url: this.props.url, | ||
method: 'post', | ||
data: { | ||
name, | ||
text | ||
}, | ||
success: (obj) => { | ||
this.setState({ | ||
comments: obj.comments | ||
}); | ||
}, | ||
error: (err) => { | ||
console.error(err); | ||
} | ||
}); | ||
} | ||
render() { | ||
return ( | ||
<div> | ||
<CommentList comments={this.state.comments} /> | ||
<CommentForm submitComment={this.submitComment.bind(this)} /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default CommentBox; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
|
||
class CommentForm extends React.Component { | ||
handleSubmit(event) { | ||
event.preventDefault(); | ||
|
||
var name = this.refs.name.getDOMNode().value.trim(); | ||
var text = this.refs.text.getDOMNode().value.trim(); | ||
|
||
this.props.submitComment(name, text); | ||
} | ||
render() { | ||
return ( | ||
<form onSubmit={this.handleSubmit.bind(this)}> | ||
<h2>Submit a comment</h2> | ||
<div className="form-group"> | ||
<label> | ||
Your name | ||
<input ref="name" type="text" className="form-control" placeholder="..." /> | ||
</label> | ||
</div> | ||
<div className="form-group"> | ||
<label> | ||
Say something... | ||
<textarea ref="text" className="form-control" placeholder="..." /> | ||
</label> | ||
</div> | ||
<div className="text-right"> | ||
<button type="reset" className="btn btn-default">Reset</button> | ||
<button type="submit" className="btn btn-primary">Submit</button> | ||
</div> | ||
</form> | ||
); | ||
} | ||
} | ||
|
||
export default CommentForm; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React from 'react'; | ||
import Comment from './Comment.jsx'; | ||
|
||
class CommentList extends React.Component { | ||
render() { | ||
if (!this.props.comments.length) { | ||
return null; | ||
} | ||
return ( | ||
<div> | ||
<h2>Comments</h2> | ||
{this.props.comments.map((comment, index) => { | ||
return <Comment name={comment.name} text={comment.text} key={index} />; | ||
})} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default CommentList; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import os | ||
import json | ||
from flask import Flask, render_template, request, redirect, jsonify | ||
from react.conf import settings as react_settings | ||
from react.render import render_component | ||
from webpack.conf import settings as webpack_settings | ||
from webpack.compiler import webpack | ||
|
||
DEBUG = True | ||
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
|
||
# As a convenience for development, only connect to the | ||
# render server when DEBUG is False | ||
react_settings.configure(RENDER=not DEBUG) | ||
|
||
webpack_settings.configure( | ||
STATIC_ROOT=os.path.join(BASE_DIR, 'static'), | ||
STATIC_URL='/static/', | ||
WATCH=DEBUG, | ||
HMR=DEBUG, | ||
CONFIG_DIRS=BASE_DIR, | ||
CONTEXT={ | ||
'DEBUG': DEBUG, | ||
}, | ||
) | ||
|
||
|
||
app = Flask(__name__) | ||
app.debug = DEBUG | ||
|
||
comments = [] | ||
|
||
|
||
@app.route('/') | ||
def index(): | ||
config_file = os.path.join(BASE_DIR, 'example.webpack.js') | ||
|
||
component = os.path.join(BASE_DIR, 'app', 'CommentBox.jsx') | ||
|
||
props = { | ||
'comments': comments, | ||
'url': '/comment/', | ||
} | ||
|
||
rendered = render_component(component, props) | ||
|
||
webpack_context = { | ||
'component': component, | ||
'props_var': 'window.mountProps', | ||
'container': 'mount-container', | ||
} | ||
|
||
bundle = webpack(config_file, context=webpack_context) | ||
|
||
return render_template( | ||
'index.html', | ||
bundle=bundle, | ||
webpack_context=webpack_context, | ||
rendered=rendered, | ||
) | ||
|
||
|
||
@app.route('/comment/', methods=('POST',)) | ||
def comment(): | ||
comments.append({ | ||
'name': request.form['name'], | ||
'text': request.form['text'], | ||
}) | ||
|
||
if request.is_xhr: | ||
return jsonify(comments=comments) | ||
|
||
return redirect('/') | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
app.run() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
var path = require('path'); | ||
var webpack = require('webpack'); | ||
var autoprefixer = require('autoprefixer-core'); | ||
var ExtractTextPlugin = require('extract-text-webpack-plugin'); | ||
|
||
module.exports = function(opts) { | ||
var config = { | ||
context: __dirname, | ||
entry: './mount', | ||
output: { | ||
filename: '[name]-[hash].js', | ||
pathinfo: opts.context.DEBUG | ||
}, | ||
module: { | ||
loaders: [ | ||
{ | ||
test: /\.jsx?$/, | ||
exclude: /(node_modules|bower_components)/, | ||
loader: (opts.hmr ? 'react-hot-loader!': '') + 'babel-loader' | ||
}, | ||
{ | ||
test: /\.css$/, | ||
loader: opts.hmr ? | ||
'style!css-loader?sourceMap!postcss-loader' : | ||
ExtractTextPlugin.extract('style', 'css-loader?sourceMap!postcss-loader') | ||
}, | ||
{ | ||
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, | ||
loader: 'url-loader?limit=10000&mimetype=application/font-woff' | ||
}, | ||
{ | ||
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, | ||
loader: 'file-loader' | ||
} | ||
] | ||
}, | ||
postcss: [autoprefixer], | ||
resolve: { | ||
alias: { | ||
__react_mount_component__: opts.context.component | ||
} | ||
}, | ||
plugins: [ | ||
// Define the variables in `./mount.js` that webpack will replace with data from python | ||
new webpack.DefinePlugin({ | ||
__react_mount_props_variable__: opts.context.props_var, | ||
__react_mount_container__: JSON.stringify(opts.context.container) | ||
}), | ||
new webpack.optimize.OccurrenceOrderPlugin(), | ||
new webpack.NoErrorsPlugin(), | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
NODE_ENV: JSON.stringify( | ||
opts.context.DEBUG ? 'development' : 'production' | ||
) | ||
} | ||
}) | ||
], | ||
devtool: opts.context.DEBUG ? 'eval-source-map' : 'source-map' | ||
}; | ||
|
||
if (!opts.hmr) { | ||
// Move css assets into separate files | ||
config.plugins.push(new ExtractTextPlugin('[name]-[contenthash].css')); | ||
} | ||
|
||
if (!opts.context.DEBUG) { | ||
// Remove duplicates and activate compression | ||
config.plugins.push( | ||
new webpack.optimize.DedupePlugin(), | ||
new webpack.optimize.UglifyJsPlugin() | ||
); | ||
} | ||
|
||
return 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
|
||
// During the build process webpack aliases this import to the desired component | ||
import Component from '__react_mount_component__'; | ||
|
||
// During the build process webpack will replace these variable with | ||
// the names passed from the python process | ||
const props = __react_mount_props_variable__; | ||
const container = document.getElementById(__react_mount_container__); | ||
|
||
const element = React.createElement(Component, props); | ||
React.render(element, container); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"private": true, | ||
"dependencies": { | ||
"autoprefixer-core": "^5.2.1", | ||
"babel": "^5.6.14", | ||
"babel-core": "^5.6.17", | ||
"babel-loader": "^5.3.1", | ||
"body-parser": "^1.13.2", | ||
"bootstrap": "^3.3.5", | ||
"css-loader": "^0.15.2", | ||
"express": "^4.13.1", | ||
"extract-text-webpack-plugin": "^0.8.2", | ||
"file-loader": "^0.8.4", | ||
"jquery": "^2.1.4", | ||
"node-libs-browser": "^0.5.2", | ||
"postcss-loader": "^0.5.1", | ||
"react": "^0.13.3", | ||
"react-hot-loader": "^1.2.8", | ||
"react-render": "^0.3.0", | ||
"style-loader": "^0.12.3", | ||
"url-loader": "^0.5.6", | ||
"webpack": "^1.10.1", | ||
"webpack-build": "^0.13.0" | ||
}, | ||
"scripts": { | ||
"webpack-build": "webpack-build" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
flask==0.10.1 | ||
optional-django==0.3.0 | ||
requests==2.7.0 | ||
-e git+ssh://git@github.com/markfinger/python-webpack.git@5ace0f26cdfd345c14ef8f608352d128511edc31#egg=webpack | ||
react |
Oops, something went wrong.