Translate JS code in listings and forms

This commit is contained in:
Tautvidas Sipavičius
2016-03-23 18:59:01 +02:00
parent 7f6eed6d66
commit 53eb9cd2ae
16 changed files with 236 additions and 107 deletions

View File

@ -167,7 +167,7 @@ define(
<input
className="button button-primary"
type="submit"
value="Save"
value={MailPoet.I18n.t('save')}
disabled={this.state.loading} />
);
}

View File

@ -15,7 +15,7 @@ define('i18n',
translations[key] = value;
},
t: function(key) {
return translations[key] || 'TRANSLATION NOT FOUND';
return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace("%$1s", key);
},
all: function() {
return translations;

View File

@ -1,8 +1,10 @@
define([
'react'
'react',
'mailpoet'
],
function(
React
React,
MailPoet
) {
var ListingBulkActions = React.createClass({
getInitialState: function() {
@ -104,7 +106,7 @@ function(
<input
onClick={ this.handleApplyAction }
type="submit"
defaultValue="Apply"
defaultValue={MailPoet.I18n.t('apply')}
className="button action" />
{ this.state.extra }

View File

@ -1,10 +1,12 @@
define([
'react',
'jquery'
'jquery',
'mailpoet'
],
function(
React,
jQuery
jQuery,
MailPoet
) {
var ListingFilters = React.createClass({
handleFilterAction: function() {
@ -69,7 +71,7 @@ function(
id="post-query-submit"
onClick={ this.handleFilterAction }
type="submit"
defaultValue="Filter"
defaultValue={MailPoet.I18n.t('filter')}
className="button" />
);
}
@ -80,7 +82,7 @@ function(
<input
onClick={ this.handleEmptyTrash }
type="submit"
value="Empty Trash"
value={MailPoet.I18n.t('emptyTrash')}
className="button"
/>
);

View File

@ -1,4 +1,12 @@
define(['react', 'classnames'], function(React, classNames) {
define([
'react',
'classnames',
'mailpoet'
], function(
React,
classNames,
MailPoet
) {
var ListingHeader = React.createClass({
handleSelectItems: function() {
@ -28,7 +36,7 @@ define(['react', 'classnames'], function(React, classNames) {
<th
className="manage-column column-cb check-column">
<label className="screen-reader-text">
{ 'Select All' }
{MailPoet.I18n.t('selectAll')}
</label>
<input
type="checkbox"

View File

@ -98,7 +98,7 @@ define(
null,
this.props.item.id
) }>
Trash
{MailPoet.I18n.t('trash')}
</a>
</span>
);
@ -145,7 +145,7 @@ define(
} else {
item_actions = (
<span className="edit">
<Link to={ `/edit/${ this.props.item.id }` }>Edit</Link>
<Link to={ `/edit/${ this.props.item.id }` }>{MailPoet.I18n.t('edit')}</Link>
</span>
);
}
@ -161,7 +161,7 @@ define(
null,
this.props.item.id
)}
>Restore</a>
>{MailPoet.I18n.t('restore')}</a>
</span>
{ ' | ' }
<span className="delete">
@ -172,13 +172,13 @@ define(
null,
this.props.item.id
)}
>Delete permanently</a>
>{MailPoet.I18n.t('deletePermanently')}</a>
</span>
</div>
<button
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
className="toggle-row" type="button">
<span className="screen-reader-text">Show more details</span>
<span className="screen-reader-text">{MailPoet.I18n.t('showMoreDetails')}</span>
</button>
</div>
);
@ -191,7 +191,7 @@ define(
<button
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
className="toggle-row" type="button">
<span className="screen-reader-text">Show more details</span>
<span className="screen-reader-text">{MailPoet.I18n.t('showMoreDetails')}</span>
</button>
</div>
);
@ -678,12 +678,12 @@ define(
bulk_actions = [
{
name: 'restore',
label: 'Restore',
label: MailPoet.I18n.t('restore'),
onSuccess: this.props.messages.onRestore
},
{
name: 'delete',
label: 'Delete permanently',
label: MailPoet.I18n.t('deletePermanently'),
onSuccess: this.props.messages.onDelete
}
];

View File

@ -1,4 +1,12 @@
define(['react', 'classnames'], function(React, classNames) {
define([
'react',
'classnames',
'mailpoet'
], function(
React,
classNames,
MailPoet
) {
var ListingPages = React.createClass({
getInitialState: function() {
@ -72,7 +80,7 @@ define(['react', 'classnames'], function(React, classNames) {
<a href="javascript:;"
onClick={ this.setPreviousPage }
className="prev-page">
<span className="screen-reader-text">Previous page</span>
<span className="screen-reader-text">{MailPoet.I18n.t('previousPage')}</span>
<span aria-hidden="true"></span>
</a>
);
@ -83,7 +91,7 @@ define(['react', 'classnames'], function(React, classNames) {
<a href="javascript:;"
onClick={ this.setFirstPage }
className="first-page">
<span className="screen-reader-text">First page</span>
<span className="screen-reader-text">{MailPoet.I18n.t('firstPage')}</span>
<span aria-hidden="true">«</span>
</a>
);
@ -94,7 +102,7 @@ define(['react', 'classnames'], function(React, classNames) {
<a href="javascript:;"
onClick={ this.setNextPage }
className="next-page">
<span className="screen-reader-text">Next page</span>
<span className="screen-reader-text">{MailPoet.I18n.t('nextPage')}</span>
<span aria-hidden="true"></span>
</a>
);
@ -105,7 +113,7 @@ define(['react', 'classnames'], function(React, classNames) {
<a href="javascript:;"
onClick={ this.setLastPage }
className="last-page">
<span className="screen-reader-text">Last page</span>
<span className="screen-reader-text">{MailPoet.I18n.t('lastPage')}</span>
<span aria-hidden="true">»</span>
</a>
);
@ -125,7 +133,7 @@ define(['react', 'classnames'], function(React, classNames) {
<span className="paging-input">
<label
className="screen-reader-text"
htmlFor="current-page-selector">Current Page</label>
htmlFor="current-page-selector">{MailPoet.I18n.t('currentPage')}</label>
<input
type="text"
onChange={ this.handleChangeManualPage }
@ -138,7 +146,7 @@ define(['react', 'classnames'], function(React, classNames) {
name="paged"
id="current-page-selector"
className="current-page" />
&nbsp;of&nbsp;
&nbsp;{MailPoet.I18n.t('pageOutOf')}&nbsp;
<span className="total-pages">
{Math.ceil(this.props.count / this.props.limit)}
</span>
@ -158,7 +166,9 @@ define(['react', 'classnames'], function(React, classNames) {
return (
<div className={ classes }>
<span className="displaying-num">{ this.props.count } items</span>
<span className="displaying-num">{
MailPoet.I18n.t('numberOfItems').replace('%$1d', this.props.count)
}</span>
{ pagination }
</div>
);

View File

@ -24,7 +24,7 @@ define([
<form name="search" onSubmit={this.handleSearch}>
<p className="search-box">
<label htmlFor="search_input" className="screen-reader-text">
Search
{MailPoet.I18n.t('searchLabel')}
</label>
<input
type="search"

View File

@ -15,22 +15,22 @@ define(
let fields = [
{
name: 'name',
label: 'Name',
label: MailPoet.I18n.t('name'),
type: 'text'
},
{
name: 'description',
label: 'Description',
label: MailPoet.I18n.t('description'),
type: 'textarea'
}
];
const messages = {
onUpdate: function() {
MailPoet.Notice.success('Segment successfully updated!');
MailPoet.Notice.success(MailPoet.I18n.t('segmentUpdated'));
},
onCreate: function() {
MailPoet.Notice.success('Segment successfully added!');
MailPoet.Notice.success(MailPoet.I18n.t('segmentAdded'));
}
};
@ -42,7 +42,7 @@ define(
return (
<div>
<h2 className="title">
Segment
{MailPoet.I18n.t('segment')}
</h2>
<Form

View File

@ -10,32 +10,32 @@ import Listing from 'listing/listing.jsx'
var columns = [
{
name: 'name',
label: 'Name',
label: MailPoet.I18n.t('name'),
sortable: true
},
{
name: 'description',
label: 'Description',
label: MailPoet.I18n.t('description'),
sortable: false
},
{
name: 'subscribed',
label: 'Subscribed',
label: MailPoet.I18n.t('subscribed'),
sortable: false
},
{
name: 'unconfirmed',
label: 'Unconfirmed',
label: MailPoet.I18n.t('unconfirmed'),
sortable: false
},
{
name: 'unsubscribed',
label: 'Unsubscribed',
label: MailPoet.I18n.t('unsubscribed'),
sortable: false
},
{
name: 'created_at',
label: 'Created on',
label: MailPoet.I18n.t('createdOn'),
sortable: true
}
];
@ -47,11 +47,11 @@ const messages = {
if(count === 1) {
message = (
'1 segment was moved to the trash.'
MailPoet.I18n.t('oneSegmentTrashed')
);
} else {
message = (
'%$1d segments were moved to the trash.'
MailPoet.I18n.t('multipleSegmentsTrashed')
).replace('%$1d', count);
}
MailPoet.Notice.success(message);
@ -62,11 +62,11 @@ const messages = {
if(count === 1) {
message = (
'1 segment was permanently deleted.'
MailPoet.I18n.t('oneSegmentDeleted')
);
} else {
message = (
'%$1d segments were permanently deleted.'
MailPoet.I18n.t('multipleSegmentsDeleted')
).replace('%$1d', count);
}
MailPoet.Notice.success(message);
@ -77,11 +77,11 @@ const messages = {
if(count === 1) {
message = (
'1 segment has been restored from the trash.'
MailPoet.I18n.t('oneSegmentRestored')
);
} else {
message = (
'%$1d segments have been restored from the trash.'
MailPoet.I18n.t('multipleSegmentsRestored')
).replace('%$1d', count);
}
MailPoet.Notice.success(message);
@ -91,10 +91,10 @@ const messages = {
const item_actions = [
{
name: 'edit',
label: 'Edit',
label: MailPoet.I18n.t('edit'),
link: function(item) {
return (
<Link to={ `/edit/${item.id}` }>Edit</Link>
<Link to={ `/edit/${item.id}` }>{MailPoet.I18n.t('edit')}</Link>
);
},
display: function(segment) {
@ -111,7 +111,7 @@ const item_actions = [
data: item.id
}).done(function(response) {
MailPoet.Notice.success(
('List "%$1s" has been duplicated.').replace('%$1s', response.name)
(MailPoet.I18n.t('listDuplicated')).replace('%$1s', response.name)
);
refresh();
});
@ -122,7 +122,7 @@ const item_actions = [
},
{
name: 'synchronize_segment',
label: 'Update',
label: MailPoet.I18n.t('update'),
className: 'update',
onClick: function(item, refresh) {
MailPoet.Modal.loading(true);
@ -133,7 +133,7 @@ const item_actions = [
MailPoet.Modal.loading(false);
if(response === true) {
MailPoet.Notice.success(
('List "%$1s" has been synchronized.').replace('%$1s', item.name)
(MailPoet.I18n.t('listSynchronized')).replace('%$1s', item.name)
);
refresh();
}
@ -147,7 +147,7 @@ const item_actions = [
name: 'view_subscribers',
link: function(item) {
return (
<a href={ item.subscribers_url }>View subscribers</a>
<a href={ item.subscribers_url }>{MailPoet.I18n.t('viewSubscribers')}</a>
);
}
},
@ -199,7 +199,7 @@ const SegmentList = React.createClass({
return (
<div>
<h2 className="title">
Segments <Link className="add-new-h2" to="/new">New</Link>
{MailPoet.I18n.t('pageTitle')} <Link className="add-new-h2" to="/new">{MailPoet.I18n.t('new')}</Link>
</h2>
<Listing

View File

@ -14,34 +14,34 @@ define(
var fields = [
{
name: 'email',
label: 'E-mail',
label: MailPoet.I18n.t('email'),
type: 'text'
},
{
name: 'first_name',
label: 'Firstname',
label: MailPoet.I18n.t('firstname'),
type: 'text'
},
{
name: 'last_name',
label: 'Lastname',
label: MailPoet.I18n.t('lastname'),
type: 'text'
},
{
name: 'status',
label: 'Status',
label: MailPoet.I18n.t('status'),
type: 'select',
values: {
'unconfirmed': 'Unconfirmed',
'subscribed': 'Subscribed',
'unsubscribed': 'Unsubscribed'
'unconfirmed': MailPoet.I18n.t('unconfirmed'),
'subscribed': MailPoet.I18n.t('subscribed'),
'unsubscribed': MailPoet.I18n.t('unsubscribed')
}
},
{
name: 'segments',
label: 'Lists',
label: MailPoet.I18n.t('lists'),
type: 'selection',
placeholder: "Select a list",
placeholder: MailPoet.I18n.t('selectList'),
endpoint: "segments",
multiple: true,
selected: function(subscriber) {
@ -69,7 +69,11 @@ define(
if (subscription.status === 'unsubscribed') {
const unsubscribed_at = MailPoet.Date
.format(subscription.updated_at);
label += ' (Unsubscribed on '+unsubscribed_at+')';
label += ' ';
label += MailPoet.I18n.t('unsubscribedOn').replace(
'%$1s',
unsubscribed_at
);
}
}
});
@ -99,10 +103,10 @@ define(
var messages = {
onUpdate: function() {
MailPoet.Notice.success('Subscriber successfully updated!');
MailPoet.Notice.success(MailPoet.I18n.t('subscriberUpdated'));
},
onCreate: function() {
MailPoet.Notice.success('Subscriber successfully added!');
MailPoet.Notice.success(MailPoet.I18n.t('subscriberAdded'));
}
};
@ -116,7 +120,7 @@ define(
return (
<div>
<h2 className="title">
Subscriber
{MailPoet.I18n.t('subscriber')}
</h2>
<Form

View File

@ -11,28 +11,28 @@ import Selection from 'form/fields/selection.jsx'
const columns = [
{
name: 'email',
label: 'Subscriber',
label: MailPoet.I18n.t('subscriber'),
sortable: true
},
{
name: 'status',
label: 'Status',
label: MailPoet.I18n.t('status'),
sortable: true
},
{
name: 'segments',
label: 'Lists',
label: MailPoet.I18n.t('lists'),
sortable: false
},
{
name: 'created_at',
label: 'Subscribed on',
label: MailPoet.I18n.t('subscribedOn'),
sortable: true
},
{
name: 'updated_at',
label: 'Last modified on',
label: MailPoet.I18n.t('lastModifiedOn'),
sortable: true
},
];
@ -43,11 +43,11 @@ const messages = {
var message = null;
if(~~response === 1) {
message = (
'1 subscriber was moved to the trash.'
MailPoet.I18n.t('oneSubscriberTrashed')
);
} else if(~~response > 1) {
message = (
'%$1d subscribers were moved to the trash.'
MailPoet.I18n.t('multipleSubscribersTrashed')
).replace('%$1d', ~~response);
}
@ -61,11 +61,11 @@ const messages = {
var message = null;
if(~~response === 1) {
message = (
'1 subscriber was permanently deleted.'
MailPoet.I18n.t('oneSubscriberDeleted')
);
} else if(~~response > 1) {
message = (
'%$1d subscribers were permanently deleted.'
MailPoet.I18n.t('multipleSubscribersDeleted')
).replace('%$1d', ~~response);
}
@ -79,11 +79,11 @@ const messages = {
var message = null;
if(~~response === 1) {
message = (
'1 subscriber has been restored from the trash.'
MailPoet.I18n.t('oneSubscriberRestored')
);
} else if(~~response > 1) {
message = (
'%$1d subscribers have been restored from the trash.'
MailPoet.I18n.t('multipleSubscribersRestored')
).replace('%$1d', ~~response);
}
@ -97,7 +97,7 @@ const messages = {
const bulk_actions = [
{
name: 'moveToList',
label: 'Move to list...',
label: MailPoet.I18n.t('moveToList'),
onSelect: function() {
let field = {
id: 'move_to_segment',
@ -120,7 +120,7 @@ const bulk_actions = [
},
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d subscribers were moved to list <strong>%$2s</strong>.'
MailPoet.I18n.t('multipleSubscribersMovedToList')
.replace('%$1d', ~~response.subscribers)
.replace('%$2s', response.segment)
);
@ -128,7 +128,7 @@ const bulk_actions = [
},
{
name: 'addToList',
label: 'Add to list...',
label: MailPoet.I18n.t('addToList'),
onSelect: function() {
let field = {
id: 'add_to_segment',
@ -151,7 +151,7 @@ const bulk_actions = [
},
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d subscribers were added to list <strong>%$2s</strong>.'
MailPoet.I18n.t('multipleSubscribersAddedToList')
.replace('%$1d', ~~response.subscribers)
.replace('%$2s', response.segment)
);
@ -159,7 +159,7 @@ const bulk_actions = [
},
{
name: 'removeFromList',
label: 'Remove from list...',
label: MailPoet.I18n.t('removeFromList'),
onSelect: function() {
let field = {
id: 'remove_from_segment',
@ -182,7 +182,7 @@ const bulk_actions = [
},
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d subscribers were removed from list <strong>%$2s</strong>.'
MailPoet.I18n.t('multipleSubscribersRemovedFromList')
.replace('%$1d', ~~response.subscribers)
.replace('%$2s', response.segment)
);
@ -190,37 +190,37 @@ const bulk_actions = [
},
{
name: 'removeFromAllLists',
label: 'Remove from all lists',
label: MailPoet.I18n.t('removeFromAllLists'),
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d subscribers were removed from all lists.'
MailPoet.I18n.t('multipleSubscribersRemovedFromAllLists')
.replace('%$1d', ~~response)
);
}
},
{
name: 'confirmUnconfirmed',
label: 'Confirm unconfirmed',
label: MailPoet.I18n.t('confirmUnconfirmed'),
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d subscribers have been confirmed.'
MailPoet.I18n.t('multipleSubscribersConfirmed')
.replace('%$1d', ~~response)
);
}
},
{
name: 'sendConfirmationEmail',
label: 'Resend confirmation email',
label: MailPoet.I18n.t('resendConfirmationEmail'),
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d confirmation emails have been sent.'
MailPoet.I18n.t('multipleConfirmationEmailsSent')
.replace('%$1d', ~~response)
);
}
},
{
name: 'trash',
label: 'Trash',
label: MailPoet.I18n.t('trash'),
onSuccess: messages.onTrash
}
];
@ -228,10 +228,10 @@ const bulk_actions = [
const item_actions = [
{
name: 'edit',
label: 'Edit',
label: MailPoet.I18n.t('edit'),
link: function(item) {
return (
<Link to={ `/edit/${item.id}` }>Edit</Link>
<Link to={ `/edit/${item.id}` }>{MailPoet.I18n.t('edit')}</Link>
);
}
},
@ -262,15 +262,15 @@ const SubscriberList = React.createClass({
switch(subscriber.status) {
case 'subscribed':
status = 'Subscribed';
status = MailPoet.I18n.t('subscribed');
break;
case 'unconfirmed':
status = 'Unconfirmed';
status = MailPoet.I18n.t('unconfirmed');
break;
case 'unsubscribed':
status = 'Unsubscribed';
status = MailPoet.I18n.t('unsubscribed');
break;
}
@ -302,7 +302,7 @@ const SubscriberList = React.createClass({
</span>
<span
className="mailpoet_segments_unsubscribed"
title="Lists to which the subscriber was subscribed."
title={MailPoet.I18n.t('listsToWhichSubscriberWasSubscribed')}
>
{ unsubscribed_segments.join(', ') }
</span>
@ -334,16 +334,16 @@ const SubscriberList = React.createClass({
</p>
{ actions }
</td>
<td className="column" data-colname="Status">
<td className="column" data-colname={MailPoet.I18n.t('status')}>
{ status }
</td>
<td className="column" data-colname="Lists">
<td className="column" data-colname={MailPoet.I18n.t('lists')}>
{ segments }
</td>
<td className="column-date" data-colname="Subscribed on">
<td className="column-date" data-colname={MailPoet.I18n.t('subscribedOn')}>
<abbr>{ MailPoet.Date.full(subscriber.created_at) }</abbr>
</td>
<td className="column-date" data-colname="Last modified on">
<td className="column-date" data-colname={MailPoet.I18n.t('lastModifiedOn')}>
<abbr>{ MailPoet.Date.full(subscriber.updated_at) }</abbr>
</td>
</div>
@ -356,9 +356,9 @@ const SubscriberList = React.createClass({
return (
<div>
<h2 className="title">
Subscribers <Link className="add-new-h2" to="/new">New</Link>
<a className="add-new-h2" href="?page=mailpoet-import#step1">Import</a>
<a id="mailpoet_export_button" className="add-new-h2" href="?page=mailpoet-export">Export</a>
{MailPoet.I18n.t('pageTitle')} <Link className="add-new-h2" to="/new">{MailPoet.I18n.t('new')}</Link>
<a className="add-new-h2" href="?page=mailpoet-import#step1">{MailPoet.I18n.t('import')}</a>
<a id="mailpoet_export_button" className="add-new-h2" href="?page=mailpoet-export">{MailPoet.I18n.t('export')}</a>
</h2>
<Listing

View File

@ -24,6 +24,12 @@
'selectBulkAction': __('Select bulk action'),
'bulkActions': __('Bulk Actions'),
'apply': __('Apply'),
'filter': __('Filter'),
'emptyTrash': __('Empty Trash'),
'selectAll': __('Select All'),
'restore': __('Restore'),
'deletePermanently': __('Delete Permanently'),
'numberOfItems': __('%$1d items'),
'formName': __('Name'),
'segments': __('Lists'),

View File

@ -25,6 +25,19 @@
'selectBulkAction': __('Select bulk action'),
'bulkActions': __('Bulk Actions'),
'apply': __('Apply'),
'filter': __('Filter'),
'emptyTrash': __('Empty Trash'),
'selectAll': __('Select All'),
'restore': __('Restore'),
'deletePermanently': __('Delete Permanently'),
'showMoreDetails': __('Show more details'),
'previousPage': __('Previous page'),
'firstPage': __('First page'),
'nextPage': __('Next page'),
'lastPage': __('Last page'),
'currentPage': __('Current Page'),
'pageOutOf': __('of'),
'numberOfItems': __('%$1d items'),
'selectType': __('Select type'),
'template': __('Template'),

View File

@ -11,5 +11,33 @@
'loadingItems': __('Loading segments...'),
'noItemsFound': __('No segments found.'),
'permanentlyDeleted': __('%d segments permanently deleted.'),
'name': __('Name'),
'description': __('Description'),
'segmentUpdated': __('Segment successfully updated!'),
'segmentAdded': __('Segment successfully added!'),
'segment': __('Segment'),
'subscribed': __('Subscribed'),
'unconfirmed': __('Unconfirmed'),
'unsubscribed': __('Unsubscribed'),
'createdOn': __('Created on'),
'oneSegmentTrashed': __('1 segment was moved to the trash.'),
'multipleSegmentsTrashed': __('%$1d segments were moved to the trash.'),
'oneSegmentDeleted': __('1 segment was permanently deleted.'),
'multipleSegmentsDeleted': __('%$1d segments were permanently deleted.'),
'oneSegmentRestored': __('1 segment has been restored from the trash.'),
'multipleSegmentsRestored': __('%$1d segments have been restored from the trash.'),
'listDuplicated': __('List "%$1s" has been duplicated.'),
'update': __('Update'),
'listSynchronized': __('List "%$1s" has been synchronized.'),
'viewSubscribers': __('View subscribers'),
'new': __('New'),
'edit': __('Edit'),
'trash': __('Trash'),
'emptyTrash': __('Empty Trash'),
'restore': __('Restore'),
'deletePermanently': __('Delete Permanently'),
'numberOfItems': __('%$1d items'),
}) %>
<% endblock %>

View File

@ -25,5 +25,61 @@
'selectBulkAction': __('Select bulk action'),
'bulkActions': __('Bulk Actions'),
'apply': __('Apply'),
'filter': __('Filter'),
'emptyTrash': __('Empty Trash'),
'selectAll': __('Select All'),
'edit': __('Edit'),
'restore': __('Restore'),
'trash': __('Trash'),
'deletePermanently': __('Delete Permanently'),
'showMoreDetails': __('Show more details'),
'previousPage': __('Previous page'),
'firstPage': __('First page'),
'nextPage': __('Next page'),
'lastPage': __('Last page'),
'currentPage': __('Current Page'),
'pageOutOf': __('of'),
'numberOfItems': __('%$1d items'),
'email': __('E-mail'),
'firstname': __('Firstname'),
'lastname': __('Lastname'),
'status': __('Status'),
'unconfirmed': __('Unconfirmed'),
'subscribed': __('Subscribed'),
'unsubscribed': __('Unsubscribed'),
'selectList': __('Select a list'),
'unsubscribedAt': __('(Unsubscribed on %$1s)'),
'subscriberUpdated': __('Subscriber successfully updated!'),
'subscriberAdded': __('Subscriber successfully added!'),
'subscriber': __('Subscriber'),
'status': __('Status'),
'lists': __('Lists'),
'subscribedOn': __('Subscribed on'),
'lastModifiedOn': __('Last modified on'),
'oneSubscriberTrashed': __('1 subscriber was moved to the trash.'),
'multipleSubscribersTrashed': __('%$1d subscribers were moved to the trash.'),
'oneSubscriberDeleted': __('1 subscriber was permanently deleted.'),
'multipleSubscribersDeleted': __('%$1d subscribers were permanently deleted.'),
'oneSubscriberRestored': __('1 subscriber has been restored from the trash.'),
'multipleSubscribersRestored': __('%$1d subscribers have been restored from the trash.'),
'moveToList': __('Move to list...'),
'multipleSubscribersMovedToList': __('%$1d subscribers were moved to list <strong>%$2s</strong>.'),
'addToList': __('Add to list...'),
'multipleSubscribersAddedToList': __('%$1d subscribers were added to list <strong>%$2s</strong>.'),
'removeFromList': __('Remove from list...'),
'multipleSubscribersRemovedFromList': __('%$1d subscribers were removed from list <strong>%$2s</strong>.'),
'removeFromAllLists': __('Remove from all lists'),
'multipleSubscribersRemovedFromAllLists': __('%$1d subscribers were removed from all lists.'),
'confirmUnconfirmed': __('Confirm unconfirmed'),
'multipleSubscribersConfirmed': __('%$1d subscribers have been confirmed.'),
'resendConfirmationEmail': __('Resend confirmation email'),
'multipleConfirmationEmailsSent': __('%$1d confirmation emails have been sent.'),
'listsToWhichSubscriberWasSubscribed': __('Lists to which the subscriber was subscribed.'),
'new': __('New'),
'import': __('Import'),
'export': __('Export'),
'save': __('Save'),
}) %>
<% endblock %>