Move component strings into views

Handle localization and string loading in views only. Components should just of default text, but not the actual text for the page itself – all text handling should be at the view level.
This commit is contained in:
Matthew Taylor 2016-01-07 09:57:34 -05:00
parent 21668d6915
commit 398f9cb95a
6 changed files with 95 additions and 83 deletions

View file

@ -1,8 +1,5 @@
var omit = require('lodash.omit');
var React = require('react');
var ReactIntl = require('react-intl');
var FormattedMessage = ReactIntl.FormattedMessage;
var FormattedHTMLMessage = ReactIntl.FormattedHTMLMessage;
var Modal = require('../modal/modal.jsx');
var Registration = require('../registration/registration.jsx');
@ -18,7 +15,16 @@ var Intro = React.createClass({
},
getDefaultProps: function () {
return {
projectCount: 10569070
projectCount: 10569070,
messages: {
'intro.aboutScratch': 'ABOUT SCRATCH',
'intro.forEducators': 'FOR EDUCATORS',
'intro.forParents': 'FOR PARENTS',
'intro.joinScratch': 'JOIN SCRATCH',
'intro.seeExamples': 'SEE EXAMPLES',
'intro.tagLine': 'Create stories, games, and animations<br /> Share with others around the world',
'intro.tryItOut': 'TRY IT OUT'
}
};
},
getInitialState: function () {
@ -52,13 +58,7 @@ var Intro = React.createClass({
return (
<div className="intro">
<div className="content">
<h1>
<FormattedHTMLMessage
id='intro.tagLine'
defaultMessage={
'Create stories, games, and animations<br /> ' +
'Share with others around the world'
} />
<h1 dangerouslySetInnerHTML={{__html: this.props.messages['intro.tagLine']}}>
</h1>
<div className="sprites">
<a className="sprite sprite-1" href="/projects/editor/?tip_bar=getStarted">
@ -70,9 +70,7 @@ var Intro = React.createClass({
src="//cdn.scratch.mit.edu/scratchr2/static/images/cat-b.png" />
<div className="circle"></div>
<div className="text">
<FormattedMessage
id='intro.tryItOut'
defaultMessage='TRY IT OUT' />
{this.props.messages['intro.tryItOut']}
</div>
</a>
<a className="sprite sprite-2" href="/starter_projects/">
@ -84,9 +82,7 @@ var Intro = React.createClass({
src="//cdn.scratch.mit.edu/scratchr2/static/images/tera-b.png" />
<div className="circle"></div>
<div className="text">
<FormattedMessage
id='intro.seeExamples'
defaultMessage='SEE EXAMPLES' />
{this.props.messages['intro.seeExamples']}
</div>
</a>
<a className="sprite sprite-3" href="#" onClick={this.handleJoinClick}>
@ -98,9 +94,7 @@ var Intro = React.createClass({
src="//cdn.scratch.mit.edu/scratchr2/static/images/gobo-b.png" />
<div className="circle"></div>
<div className="text">
<FormattedMessage
id='intro.joinScratch'
defaultMessage='JOIN SCRATCH' />
{this.props.messages['intro.joinScratch']}
</div>
<div className="text subtext">( it&rsquo;s free )</div>
</a>
@ -116,19 +110,13 @@ var Intro = React.createClass({
</div>
<div className="links">
<a href="/about/">
<FormattedMessage
id='intro.aboutScratch'
defaultMessage='ABOUT SCRATCH' />
{this.props.messages['intro.aboutScratch']}
</a>
<a href="/educators/">
<FormattedMessage
id='intro.forEducators'
defaultMessage='FOR EDUCATORS' />
{this.props.messages['intro.forEducators']}
</a>
<a className="last" href="/parents/">
<FormattedMessage
id='intro.forParents'
defaultMessage='FOR PARENTS' />
{this.props.messages['intro.forParents']}
</a>
</div>
</div>

View file

@ -1,23 +1,9 @@
var React = require('react');
var ReactIntl = require('react-intl');
var defineMessages = ReactIntl.defineMessages;
var injectIntl = ReactIntl.injectIntl;
var Box = require('../box/box.jsx');
require('./news.scss');
var defaultMessages = defineMessages({
scratchNews: {
id: 'news.scratchNews',
defaultMessage: 'Scratch News'
},
viewAll: {
id: 'general.viewAll',
defaultMessage: 'View All'
}
});
var News = React.createClass({
type: 'News',
propTypes: {
@ -25,16 +11,19 @@ var News = React.createClass({
},
getDefaultProps: function () {
return {
items: require('./news.json')
items: require('./news.json'),
messages: {
'general.viewAll': 'View All',
'news.scratchNews': 'Scratch News'
}
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
<Box
className="news"
title={formatMessage(defaultMessages.scratchNews)}
moreTitle={formatMessage(defaultMessages.viewAll)}
title={this.props.messages['news.scratchNews']}
moreTitle={this.props.messages['general.viewAll']}
moreHref="/discuss/5/">
<ul>
@ -55,4 +44,4 @@ var News = React.createClass({
}
});
module.exports = injectIntl(News);
module.exports = News;

View file

@ -1,8 +1,4 @@
var React = require('react');
var ReactIntl = require('react-intl');
var injectIntl = ReactIntl.injectIntl;
var FormattedMessage = ReactIntl.FormattedMessage;
var Box = require('../box/box.jsx');
@ -13,10 +9,19 @@ var Welcome = React.createClass({
propTypes: {
onDismiss: React.PropTypes.func
},
getDefaultProps: function () {
return {
messages: {
'welcome.welcomeToScratch': 'Welcome to Scratch!',
'welcome.learn': 'Learn how to make a project in Scratch',
'welcome.tryOut': 'Try out starter projects',
'welcome.connect': 'Connect with other Scratchers'
}
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
<Box title={formatMessage({id: 'welcome.welcomeToScratch', defaultMessage: 'Welcome to Scratch!'})}
<Box title={this.props.messages['welcome.welcomeToScratch']}
className="welcome"
moreTitle="x"
moreHref="#"
@ -29,9 +34,7 @@ var Welcome = React.createClass({
<div className="welcome-col blue">
<h4>
<a href="/projects/editor/?tip_bar=getStarted">
<FormattedMessage
id="welcome.learn"
defaultMessage="Learn how to make a project in Scratch" />
{this.props.messages['welcome.learn']}
</a>
</h4>
<a href="/projects/editor/?tip_bar=getStarted">
@ -41,9 +44,7 @@ var Welcome = React.createClass({
<div className="welcome-col green">
<h4>
<a href="/starter_projects/">
<FormattedMessage
id="welcome.tryOut"
defaultMessage="Try out starter projects" />
{this.props.messages['welcome.tryOut']}
</a>
</h4>
<a href="/starter_projects/">
@ -53,9 +54,7 @@ var Welcome = React.createClass({
<div className="welcome-col pink">
<h4>
<a href="/studios/146521/">
<FormattedMessage
id="welcome.connect"
defaultMessage="Connect with other Scratchers" />
{this.props.messages['welcome.connect']}
</a>
</h4>
<a href="/studios/146521/">
@ -67,4 +66,4 @@ var Welcome = React.createClass({
}
});
module.exports = injectIntl(Welcome);
module.exports = Welcome;

View file

@ -53,26 +53,12 @@
"footer.help": "Help Page",
"footer.scratchFamily": "Scratch Family",
"intro.aboutScratch": "ABOUT SCRATCH",
"intro.forEducators": "FOR EDUCATORS",
"intro.forParents": "FOR PARENTS",
"intro.joinScratch": "JOIN SCRATCH",
"intro.seeExamples": "SEE EXAMPLES",
"intro.tagLine": "Create stories, games, and animations<br /> Share with others around the world",
"intro.tryItOut": "TRY IT OUT",
"login.forgotPassword": "Forgot Password?",
"navigation.signOut": "Sign out",
"news.scratchNews": "Scratch News",
"parents.FaqAgeRangeA": "While Scratch is primarily designed for 8 to 16 year olds, it is also used by people of all ages, including younger children with their parents.",
"parents.FaqAgeRangeQ": "What is the age range for Scratch?",
"parents.FaqResourcesQ": "What resources are available for learning Scratch?",
"parents.introDescription": "Scratch is a programming language and an online community where children can program and share interactive media such as stories, games, and animation with people from all over the world. As children create with Scratch, they learn to think creatively, work collaboratively, and reason systematically. Scratch is designed and maintained by the Lifelong Kindergarten group at the MIT Media Lab.",
"welcome.welcomeToScratch": "Welcome to Scratch!",
"welcome.learn": "Learn how to make a project in Scratch",
"welcome.tryOut": "Try out starter projects",
"welcome.connect": "Connect with other Scratchers"
"parents.introDescription": "Scratch is a programming language and an online community where children can program and share interactive media such as stories, games, and animation with people from all over the world. As children create with Scratch, they learn to think creatively, work collaboratively, and reason systematically. Scratch is designed and maintained by the Lifelong Kindergarten group at the MIT Media Lab."
}

View file

@ -9,5 +9,20 @@
"splash.projectsLovedByScratchersFollowing": "Projects Loved by Scratchers I'm Following",
"splash.projectsInStudiosFollowing": "Projects in Studios I'm Following",
"splash.communityRemixing": "What the Community is Remixing",
"splash.communityLoving": "What the Community is Loving"
"splash.communityLoving": "What the Community is Loving",
"intro.aboutScratch": "ABOUT SCRATCH",
"intro.forEducators": "FOR EDUCATORS",
"intro.forParents": "FOR PARENTS",
"intro.joinScratch": "JOIN SCRATCH",
"intro.seeExamples": "SEE EXAMPLES",
"intro.tagLine": "Create stories, games, and animations<br /> Share with others around the world",
"intro.tryItOut": "TRY IT OUT",
"news.scratchNews": "Scratch News",
"welcome.welcomeToScratch": "Welcome to Scratch!",
"welcome.learn": "Learn how to make a project in Scratch",
"welcome.tryOut": "Try out starter projects",
"welcome.connect": "Connect with other Scratchers"
}

View file

@ -179,6 +179,36 @@ var Splash = injectIntl(React.createClass({
this.state.session.user && this.state.session.flags.has_outstanding_email_confirmation &&
this.state.session.flags.confirm_email_banner);
},
getHomepageComponentMessages: function () {
var formatMessage = this.props.intl.formatMessage;
var messages = {};
if (this.state.session.user) {
messages['news'] = {
'general.viewAll': formatMessage({id: 'general.viewAll'}),
'news.scratchNews': formatMessage({id: 'news.scratchNews'})
};
if (this.shouldShowWelcome()) {
messages['welcome'] = {
'welcome.welcomeToScratch': formatMessage({id: 'welcome.welcomeToScratch'}),
'welcome.learn': formatMessage({id: 'welcome.learn'}),
'welcome.tryOut': formatMessage({id: 'welcome.tryOut'}),
'welcome.connect': formatMessage({id: 'welcome.connect'})
};
}
} else {
messages['intro'] = {
'intro.aboutScratch': formatMessage({id: 'intro.aboutScratch'}),
'intro.forEducators': formatMessage({id: 'intro.forEducators'}),
'intro.forParents': formatMessage({id: 'intro.forParents'}),
'intro.joinScratch': formatMessage({id: 'intro.joinScratch'}),
'intro.seeExamples': formatMessage({id: 'intro.seeExamples'}),
'intro.tagLine': formatMessage({id: 'intro.tagLine'}),
'intro.tryItOut': formatMessage({id: 'intro.tryItOut'})
};
}
return messages;
},
renderHomepageRows: function () {
var formatMessage = this.props.intl.formatMessage;
@ -322,6 +352,9 @@ var Splash = injectIntl(React.createClass({
var featured = this.renderHomepageRows();
var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
var homepageCacheState = this.getHomepageRefreshStatus();
var messages = this.getHomepageComponentMessages();
return (
<div className="splash">
{this.shouldShowEmailConfirmation() ? [
@ -345,14 +378,16 @@ var Splash = injectIntl(React.createClass({
{this.state.session.user ? [
<div key="header" className="splash-header">
{this.shouldShowWelcome() ? [
<Welcome key="welcome" onDismiss={this.handleDismiss.bind(this, 'welcome')}/>
<Welcome key="welcome"
onDismiss={this.handleDismiss.bind(this, 'welcome')}
messages={messages['welcome']} />
] : [
<Activity key="activity" items={this.state.activity} />
]}
<News items={this.state.news} />
<News items={this.state.news} messages={messages['news']} />
</div>
] : [
<Intro projectCount={this.state.projectCount} key="intro"/>
<Intro projectCount={this.state.projectCount} messages={messages['intro']} key="intro"/>
]}
{featured}