diff --git a/.travis.yml b/.travis.yml index 2308405..a61f73b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,16 @@ language: python python: - "2.7" - - "3.4" + - "3.5" + - "3.7" + - "3.8" env: - DJANGO_VERSION=1.7.8 - DJANGO_VERSION=1.8.1 + - DJANGO_VERSION=2.2.16 + - DJANGO_VERSION=3.1.1 + - DJANGO_VERSION=1.8.19 install: # Install node 6 (current LTS as of January 2017) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07f3f60..2d309cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,33 @@ Changelog ========= + +### 4.3.0 (8/10/2018) + +- Add option to pass a URL explicitly instead of reading from settings. + ([jchen-eb](https://github.com/jchen-eb)) + https://github.com/markfinger/python-react/pull/88 + + +### 4.2.1 (17/6/2018) + +- Fix for a missing argument bug that could occur with rendering deactivated. + + +### 4.2.0 (17/6/2018) + +- API for returning extra items returned by render server. + ([Sassan Haradji](https://github.com/sassanh)) + https://github.com/markfinger/python-react/pull/87 + + +### 4.1.1 (9/8/2017) + +- Update timeout in render_server.py. + ([Mike Plis](https://github.com/mplis)) + https://github.com/markfinger/python-react/pull/81 + + ### 4.1.0 (1/3/2017) - `render_component` now accepts a `timeout` keyword argument which is passed to `RenderServer.render`. @@ -19,6 +46,7 @@ Changelog rendering. - Documentation updates regarding `RenderServer` API. + ### 3.0.1 (6/4/2016) - Documentation updates. @@ -44,6 +72,7 @@ Changelog ([Pringels](https://github.com/Pringels)) https://github.com/markfinger/python-react/pull/55 + ### 2.0.0 (22/9/2015) - **Breaking change** The base renderer's __init__ no longer accepts the RENDER_URL setting as an argument. @@ -68,6 +97,7 @@ Changelog - Fixed a potential path issue in config files - Replaced the webpack-service dependency with webpack-wrapper. + ### 0.8.0 (26/1/2015) - Boosting render performance by using a dedicated render server. @@ -76,6 +106,7 @@ Changelog render server, 'django_react.render_server.ReactRenderServer'. The legacy renderer is useable by setting DJANGO_REACT['RENDERER'] = 'django_react.renderer.ReactRenderer'. + ### 0.7.0 (2/1/2015) - Changed `django_react.exceptions.ReactComponentMissingSourceAttribute` to `django_react.exceptions.ReactComponentMissingSource` @@ -86,10 +117,12 @@ Changelog - The Python<->JS bridge used to render components now relies on a `--serialized-props-file` argument, formerly it was `--serialized-props`. - Switched the JSX loader to a fork which improves the debug information provided during error handling + ### 0.6.0 (24/12/2014) - The NODE_ENV environment setting is now controlled by the `DJANGO_REACT['DEBUG']` setting. Activating it will provides some improvements to the rendering performance. + ### 0.5.0 (14/12/2014) - Renamed `django_react.exceptions.PropSerialisationError` to `django_react.exceptions.PropSerializationError`. @@ -111,6 +144,7 @@ Changelog - Added a test suite and harness. - Added basic documentation. + ### 0.4.0 (11/12/2014) - Fixed a bug where errors caused during a component's prop serialization could silently fail. @@ -123,6 +157,7 @@ Changelog - `ReactComponent.get_component_variable` is now `ReactComponent.get_library`. - Moved the Webpack configuration into the ReactComponent class. + ### 0.3.0 (3/12/2014) - `django_react.exceptions.ReactComponentSourceFileNotFound` is now `django_react.exceptions.SourceFileNotFound` @@ -133,10 +168,12 @@ Changelog - `django_react.utils.render` no longer accepts a `ReactComponent` as an argument, it now takes `path_to_source`, `serialised_props`, and `to_static_markup`. - `django_react/render.js` no longer accepts the `--path-to-component` argument, instead it takes `--path-to-source`. + ### 0.2.0 (3/12/2014) - Replaced the post-install step in setup.py with django-node's dependency and package resolver. + ### 0.1.0 (2/12/2014) - Initial release diff --git a/README.md b/README.md index da12786..b73e30c 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,11 @@ rendered = render_component('path/to/component.jsx', {'foo': 'bar'}) print(rendered) ``` -The object returned has two properties: +The object returned has three properties: - `markup` - the rendered markup - `props` - the JSON-serialized props + - `data` - the data returned by the render server If the object is coerced to a string, it will emit the value of the `markup` attribute. @@ -255,7 +256,7 @@ from react.conf import settings DEBUG = True settings.configure( - RENDER=not DEBUG, + RENDER=not DEBUG, RENDER_URL='http://127.0.0.1:9009/render', ) ``` @@ -270,7 +271,7 @@ INSTALLED_APPS = ( ) REACT = { - 'RENDER': not DEBUG, + 'RENDER': not DEBUG, 'RENDER_URL': 'http://127.0.0.1:8001/render', } ``` @@ -300,6 +301,22 @@ Default: `'http://127.0.0.1:9009/render'` Frequently Asked Questions -------------------------- +### How do I return extra data from the render server? + +You can edit the render server's code and annotate the returned payload with whatever data +that you like. The payload provided by the render server is available under the `data` attribute +of the response object. + +For example: + +```python +from react.render import render_component + +rendered = render_component('path/to/component.js') + +print(rendered.data) +``` + ### Can python-react integrate with Django? python-react can integrate with Django's settings and the renderer integration can diff --git a/examples/frontend-rendering-with-webpack/README.md b/examples/frontend-rendering-with-webpack/README.md index f7b9908..05f9421 100644 --- a/examples/frontend-rendering-with-webpack/README.md +++ b/examples/frontend-rendering-with-webpack/README.md @@ -1,7 +1,7 @@ Running the example =================== -As mentioned in the ***Using React on the front-end*** section, [Webpack](https://webpack.github.io/) is used to bundle the respective js files into `dist.js` and included in `index.html`. To make React attributes like `onClick` etc. work, the app has to be re-rendered (along with all the props passed down) when it loads on the browswer. React is intelligent enough to not re-paint the browser and only update the changes, thus adding all the component properties. +As mentioned in the ***Using React on the front-end*** section, [Webpack](https://webpack.github.io/) is used to bundle the respective js files into `dist.js` and included in `index.html`. To make React attributes like `onClick` etc. work, the app has to be re-rendered (along with all the props passed down) when it loads on the browser. React is intelligent enough to not re-paint the browser and only update the changes, thus adding all the component properties. In this example, the basic_rendering example is modified to submit the Comment Form through ajax and update the Comment List by fetching the updated comments and rendering the application with new props. diff --git a/react/__init__.py b/react/__init__.py index 5e58b2f..66cf931 100644 --- a/react/__init__.py +++ b/react/__init__.py @@ -1,3 +1,3 @@ -__version__ = '4.1.0' +__version__ = '4.3.0' default_app_config = 'react.apps.ReactConfig' \ No newline at end of file diff --git a/react/render_server.py b/react/render_server.py index a7b1907..b7d7d48 100644 --- a/react/render_server.py +++ b/react/render_server.py @@ -8,9 +8,10 @@ class RenderedComponent(object): - def __init__(self, markup, props): + def __init__(self, markup, props, data): self.markup = markup self.props = props + self.data = data def __str__(self): return self.markup @@ -20,8 +21,9 @@ def __unicode__(self): class RenderServer(object): - def render(self, path, props=None, to_static_markup=False, request_headers=None, timeout=None): - url = conf.settings.RENDER_URL + def render(self, path, props=None, to_static_markup=False, request_headers=None, timeout=None, url=None): + if not url: + url = conf.settings.RENDER_URL if props is not None: serialized_props = json.dumps(props, cls=JSONEncoder) @@ -29,7 +31,7 @@ def render(self, path, props=None, to_static_markup=False, request_headers=None, serialized_props = None if not conf.settings.RENDER: - return RenderedComponent('', serialized_props) + return RenderedComponent('', serialized_props, {}) options = { 'path': path, @@ -47,7 +49,7 @@ def render(self, path, props=None, to_static_markup=False, request_headers=None, # Add a send/receive timeout with the request if not specified if not isinstance(timeout, (tuple, int, float)): - timeout = (5, 5) + timeout = 5.0 try: res = requests.post( @@ -67,8 +69,9 @@ def render(self, path, props=None, to_static_markup=False, request_headers=None, obj = res.json() - markup = obj.get('markup', None) - err = obj.get('error', None) + markup = obj.pop('markup', None) + err = obj.pop('error', None) + data = obj if err: if 'message' in err and 'stack' in err: @@ -80,7 +83,7 @@ def render(self, path, props=None, to_static_markup=False, request_headers=None, if markup is None: raise ReactRenderingError('Render server failed to return markup. Returned: {}'.format(obj)) - return RenderedComponent(markup, serialized_props) + return RenderedComponent(markup, serialized_props, data) render_server = RenderServer()