Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated docs: Feature branches, Recipes #624

Merged
merged 1 commit into from
May 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ forked repo, check that it meets these guidelines:
* [Squash](http://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see it, in the left pane. Interesting

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand you what do you mean?

your commits into one for each PR.
* Run `npm test` to make sure that your code style is OK and there are no any regression bugs.
* When contributing to an opt-in feature, apply the `[feature/...]` tag as a prefix to your PR title

#### Style Guide

Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ expenses via [OpenCollective](https://opencollective.com/react-starter-kit) or
<img src="https://opencollective.com/static/images/become_backer.svg" width="64" height="64" alt="">
</a>

### Feature branches

Some features aren't provided by default, but you can optionally add them.
To do so, simply merge the corresponding feature branch.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with git, but I don't think this is a good idea. Not everyone can merge well. And is confusing.

Best to have a separate repo that is posted to NPM to add via package.json. Branches are used traditionally for development or versons (eg 2.x branch).

These branches should be in sync with master and all other features branches
so there should not be any merging conflicts.
If conflicts occur, please [report to us](https://github.com/kriasoft/react-starter-kit/issues).

* [feature/redux](https://github.com/kriasoft/react-starter-kit/tree/feature/redux) – isomorphic redux support.
Use [`connect()`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)
higher order component to access state in redux store and to get actions mapped on dispatch.
You can see [LanguageSwitcher](https://github.com/kriasoft/react-starter-kit/blob/86eadfd3d11d804cf858aa21f657022fcc098752/src/components/LanguageSwitcher/LanguageSwitcher.js) component how to use `connect()`
<br/>
[Read full recipe](./docs/recipes/feature-redux.md)

* [feature/react-intl](https://github.com/kriasoft/react-starter-kit/tree/feature/react-intl) – [`react-intl`](https://github.com/yahoo/react-intl#react-intl) integration based on `feature/redux`
<br/>
[Read full recipe](./docs/recipes/feature-react-intl.md)

### Learn More

* [Getting Started with React.js](http://facebook.github.io/react/)
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
### Recipes

* [How to Implement Routing and Navigation](./recipes/how-to-implement-routing.md)
* [How to Integrate Redux](./recipes/feature-redux.md)
* [How to Integrate React-Intl](./recipes/feature-react-intl.md)
* [How to Integrate Disqus](./recipes/how-to-integrate-disqus.md)
122 changes: 122 additions & 0 deletions docs/recipes/feature-react-intl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
## Integrating [React-Intl](https://github.com/yahoo/react-intl#react-intl)

1. Merge `feature/react-intl` branch with git.
Because react-intl integration is built on top of `feature/redux`, you'll also get all the features.

2. Adjust `INTL_REQUIRE_DESCRIPTIONS` constant in `tools/webpack.config.js` around line 17:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in line instead of around line

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'... around line 17' Around there means it can vary. It's config file, almost everyone altering things there.
'* on line 17*' will fit better for exact position.

```js
const INTL_REQUIRE_DESCRIPTIONS = true;
```
When this boolean is set to true, the build will only succeed if a `description` is set for every message descriptor.

3. Adjust `locales` settings in `src/config.js`:
```js
// default locale is the first one
export const locales = ['en-GB', 'cs-CZ'];
```
Note that you should follow
[BCP 47](https://tools.ietf.org/html/bcp47)
([RFC 5646](https://tools.ietf.org/html/rfc5646)).

4. Add locale support in `src/client.js`:
```js
import en from 'react-intl/locale-data/en';
import cs from 'react-intl/locale-data/cs';
...

[en, cs].forEach(addLocaleData);
```

5. Execute `npm run extractMessages` or `npm start` to strip out messages.
Message files are created in `src/messages` directory.

6. Edit `src/messages/*.json` files, change only `message` property.

7. Execute `npm run build`,
your translations should be copied to `build/messages/` directory.


## How to write localizable components

Just import the appropriate [component](https://github.com/yahoo/react-intl/wiki#the-react-intl-module) from `react-intl`

- For localizable text use
[`<FormattedMessage>`](https://github.com/yahoo/react-intl/wiki/Components#formattedmessage).
- You can also use it with
the [`defineMessages()`](https://github.com/yahoo/react-intl/wiki/API#definemessages) helper.

- For date and time:
[`<FormattedDate>`](https://github.com/yahoo/react-intl/wiki/Components#formatteddate)
[`<FormattedTime>`](https://github.com/yahoo/react-intl/wiki/Components#formattedtime)
[`<FormattedRelative>`](https://github.com/yahoo/react-intl/wiki/Components#formattedrelative)

- For numbers and currencies:
[`<FormattedNumber>`](https://github.com/yahoo/react-intl/wiki/Components#formattednumber)
[`<FormattedPlural>`](https://github.com/yahoo/react-intl/wiki/Components#formattedplural)

- If possible, do not use `<FormattedHTMLMessage>`, see how to use *Rich Text Formatting* with
[`<FormattedMessage>`](https://github.com/yahoo/react-intl/wiki/Components#formattedmessage)

- When you need an imperative formatting API, use the [`injectIntl`](https://github.com/yahoo/react-intl/wiki/API#injectintl) High-Order Component.

### Example

```jsx
import { defineMessages, FormattedMessage, injectIntl, intlShape } from 'react-intl';

const messages = defineMessages({
text: {
id: 'example.text',
defaultMessage: 'Example text',
description: 'Hi Pavel',
},
textTemplate: {
id: 'example.text.template',
defaultMessage: 'Example text template',
description: 'Hi {name}',
},
});

function Example(props) {
const text = props.intl.formatMessage(messages.textTemplate, { name: 'Pavel'});
return (
<div>
<FormattedMessage
id="example.text.inlineDefinition"
defaultMessage="Hi Pavel"
description="Example of usage without defineMessages"
/>
<FormattedMessage {...messages.text} />
<FormattedMessage
{...messages.textTemplate}
values={{
name: <b>Pavel</b>
}}
/>
</div>
);
}

Example.propTypes = {
intl: intlShape,
}

export default injectIntl(Example);
```

## Updating translations

When running the development server, every source file is watched and parsed for changed messages.

Messages files are updated on the fly.
If a new definition is found, this definition is added to the end of every used `src/messages/xx-XX.json` file so when commiting, new translations will be at the tail of file.

When an untranslated message is removed and its `message` field is empty as well, the message will be deleted from all translation files. This is why the `files` array is present.

When editiong a translation file, it should be copied to `build/messages/` directory.

## Other References

* [`Intl documentation on MDN`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl)
* [express-request-language](https://github.com/tinganho/express-request-language#readme)
– for more details how initial language negotiation works.
56 changes: 56 additions & 0 deletions docs/recipes/feature-redux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## Integrating [Redux](http://redux.js.org/index.html)

Merge `feature/redux` branch with git.
If you are interested in `feature/react-intl`,
merge that branch instead as it also includes Redux.

**If you don't know redux well, you should [read about it first](http://redux.js.org/docs/basics/index.html).**


## Creating Actions

1. Go to `src/constants/index.js` and define action name there.

2. Go to `src/actions/` and create file with appropriate name.
You can copy `src/actions/runtime.js` as a template.

3. If you need async actions, use [`redux-thunk`](https://github.com/gaearon/redux-thunk#readme).
For inspiration on how to create async actions you can look at
[`setLocale`](https://github.com/kriasoft/react-starter-kit/blob/feature/react-intl/src/actions/intl.js)
action from `feature/react-intl`.
See [Async Flow](http://redux.js.org/docs/advanced/AsyncFlow.html) for more information on this topic.


## Creating Reducer (aka Store)

1. Go to [`src/reducers/`](https://github.com/kriasoft/react-starter-kit/tree/feature/redux/src/reducers) and create new file there.

You can copy [`src/reducers/runtime.js`](https://github.com/kriasoft/react-starter-kit/tree/feature/redux/src/reducers/runtime.js) as a template.

- Do not forget to always return `state`.
- Never mutate provided `state`.
If you mutate state, rendering of connected component will not be triggered because of `===` equality.
Always return new value if you perform state update.
You can use this construct: `{ ...state, updatedKey: action.payload.value, }`
- Keep in mind that store state *must* be repeatable by replaying actions on it.
For example, when you store timestamp, pass it into *action payload*.
If you call REST API, do it in action. *Never do this in reducer!*

2. Edit [`src/reducers/index.js`](https://github.com/kriasoft/react-starter-kit/tree/feature/redux/src/reducers/index.js), import your reducer and add it to root reducer created by
[`combineReducers`](http://redux.js.org/docs/api/combineReducers.html)


## Connecting Components

You can use [`connect()`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options) High-Order Component from [`react-redux`](https://github.com/reactjs/react-redux#readme) package.

See [Usage With React](http://redux.js.org/docs/basics/UsageWithReact.html) on redux.js.org.

For an example you can look at
[`<LanguageSwitcher>`](https://github.com/kriasoft/react-starter-kit/blob/feature/react-intl/src/components/LanguageSwitcher/LanguageSwitcher.js)
component from `feature/react-intl` branch. It demonstrates both subscribing to store and dispatching actions.


## Dispatching Actions On Server

See source of `src/server.js`