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

View file

@ -1,23 +1,9 @@
var React = require('react'); var React = require('react');
var ReactIntl = require('react-intl');
var defineMessages = ReactIntl.defineMessages;
var injectIntl = ReactIntl.injectIntl;
var Box = require('../box/box.jsx'); var Box = require('../box/box.jsx');
require('./news.scss'); require('./news.scss');
var defaultMessages = defineMessages({
scratchNews: {
id: 'news.scratchNews',
defaultMessage: 'Scratch News'
},
viewAll: {
id: 'general.viewAll',
defaultMessage: 'View All'
}
});
var News = React.createClass({ var News = React.createClass({
type: 'News', type: 'News',
propTypes: { propTypes: {
@ -25,16 +11,19 @@ var News = React.createClass({
}, },
getDefaultProps: function () { getDefaultProps: function () {
return { return {
items: require('./news.json') items: require('./news.json'),
messages: {
'general.viewAll': 'View All',
'news.scratchNews': 'Scratch News'
}
}; };
}, },
render: function () { render: function () {
var formatMessage = this.props.intl.formatMessage;
return ( return (
<Box <Box
className="news" className="news"
title={formatMessage(defaultMessages.scratchNews)} title={this.props.messages['news.scratchNews']}
moreTitle={formatMessage(defaultMessages.viewAll)} moreTitle={this.props.messages['general.viewAll']}
moreHref="/discuss/5/"> moreHref="/discuss/5/">
<ul> <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 React = require('react');
var ReactIntl = require('react-intl');
var injectIntl = ReactIntl.injectIntl;
var FormattedMessage = ReactIntl.FormattedMessage;
var Box = require('../box/box.jsx'); var Box = require('../box/box.jsx');
@ -13,10 +9,19 @@ var Welcome = React.createClass({
propTypes: { propTypes: {
onDismiss: React.PropTypes.func 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 () { render: function () {
var formatMessage = this.props.intl.formatMessage;
return ( return (
<Box title={formatMessage({id: 'welcome.welcomeToScratch', defaultMessage: 'Welcome to Scratch!'})} <Box title={this.props.messages['welcome.welcomeToScratch']}
className="welcome" className="welcome"
moreTitle="x" moreTitle="x"
moreHref="#" moreHref="#"
@ -29,9 +34,7 @@ var Welcome = React.createClass({
<div className="welcome-col blue"> <div className="welcome-col blue">
<h4> <h4>
<a href="/projects/editor/?tip_bar=getStarted"> <a href="/projects/editor/?tip_bar=getStarted">
<FormattedMessage {this.props.messages['welcome.learn']}
id="welcome.learn"
defaultMessage="Learn how to make a project in Scratch" />
</a> </a>
</h4> </h4>
<a href="/projects/editor/?tip_bar=getStarted"> <a href="/projects/editor/?tip_bar=getStarted">
@ -41,9 +44,7 @@ var Welcome = React.createClass({
<div className="welcome-col green"> <div className="welcome-col green">
<h4> <h4>
<a href="/starter_projects/"> <a href="/starter_projects/">
<FormattedMessage {this.props.messages['welcome.tryOut']}
id="welcome.tryOut"
defaultMessage="Try out starter projects" />
</a> </a>
</h4> </h4>
<a href="/starter_projects/"> <a href="/starter_projects/">
@ -53,9 +54,7 @@ var Welcome = React.createClass({
<div className="welcome-col pink"> <div className="welcome-col pink">
<h4> <h4>
<a href="/studios/146521/"> <a href="/studios/146521/">
<FormattedMessage {this.props.messages['welcome.connect']}
id="welcome.connect"
defaultMessage="Connect with other Scratchers" />
</a> </a>
</h4> </h4>
<a href="/studios/146521/"> <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.help": "Help Page",
"footer.scratchFamily": "Scratch Family", "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?", "login.forgotPassword": "Forgot Password?",
"navigation.signOut": "Sign out", "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.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.FaqAgeRangeQ": "What is the age range for Scratch?",
"parents.FaqResourcesQ": "What resources are available for learning 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.", "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"
} }

View file

@ -9,5 +9,20 @@
"splash.projectsLovedByScratchersFollowing": "Projects Loved by Scratchers I'm Following", "splash.projectsLovedByScratchersFollowing": "Projects Loved by Scratchers I'm Following",
"splash.projectsInStudiosFollowing": "Projects in Studios I'm Following", "splash.projectsInStudiosFollowing": "Projects in Studios I'm Following",
"splash.communityRemixing": "What the Community is Remixing", "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.user && this.state.session.flags.has_outstanding_email_confirmation &&
this.state.session.flags.confirm_email_banner); 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 () { renderHomepageRows: function () {
var formatMessage = this.props.intl.formatMessage; var formatMessage = this.props.intl.formatMessage;
@ -322,6 +352,9 @@ var Splash = injectIntl(React.createClass({
var featured = this.renderHomepageRows(); var featured = this.renderHomepageRows();
var emailConfirmationStyle = {width: 500, height: 330, padding: 1}; var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
var homepageCacheState = this.getHomepageRefreshStatus(); var homepageCacheState = this.getHomepageRefreshStatus();
var messages = this.getHomepageComponentMessages();
return ( return (
<div className="splash"> <div className="splash">
{this.shouldShowEmailConfirmation() ? [ {this.shouldShowEmailConfirmation() ? [
@ -345,14 +378,16 @@ var Splash = injectIntl(React.createClass({
{this.state.session.user ? [ {this.state.session.user ? [
<div key="header" className="splash-header"> <div key="header" className="splash-header">
{this.shouldShowWelcome() ? [ {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} /> <Activity key="activity" items={this.state.activity} />
]} ]}
<News items={this.state.news} /> <News items={this.state.news} messages={messages['news']} />
</div> </div>
] : [ ] : [
<Intro projectCount={this.state.projectCount} key="intro"/> <Intro projectCount={this.state.projectCount} messages={messages['intro']} key="intro"/>
]} ]}
{featured} {featured}