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

feat: i18n support #94

Closed
wants to merge 9 commits into from
Closed
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
46 changes: 43 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,28 @@ const cors = require('cors');
const routes = require('./routes');
const hbs = require('express-handlebars');
const bodyParser = require('body-parser');
// const i18n = require('i18n');
const { I18n } = require('i18n');

const app = express();

// Configuration //

//app.use(cors());
//app.use(bodyParser.json());
//app.use(session({ secret: 'slartibartfast', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false }));
app.use(session({
secret: 'Py0Bf3aWZC8kYkYTpRztmYMyS22pFFGi'
}));

// Internationalization //
const i18n = new I18n({
locales:['en-US'], //include langs
directory: path.join(__dirname, 'locales'),
defaultLocale: 'en-US'
});
app.use(i18n.init);

// View engine //
hbsInstance = hbs.create({
const hbsInstance = hbs.create({
defaultLayout: 'main',
partialsDir: ['views/partials/'],
layoutsDir: 'views/layouts/',
Expand Down Expand Up @@ -51,4 +61,34 @@ app.use(bodyParser.json({ type: "application/activity+json" })); // support json
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/', routes);

app.use(setLocale);
module.exports = app;

// def setLocale
function setLocale(req, res, next){
var locale;
// Get the locale data in the user data
if(req.user){
locale = req.user.locale;
}
// Get the locale data in the cookie
else if(req.signedCookies['locale']){
locale = req.signedCookies['locale'];
}
// Get the first preferred language of the browser, this function is provided by express
// User-selected languages will be added later
else if(req.acceptsLanguages()){
locale = req.acceptsLanguages();
}
// When there is no language preference, the language used on the website is English
else {
locale = 'en-US';
}
// If the language preference saved in the cookie is different from the language preference used here, update the language preference setting in the cookie
if(req.signedCookies['locale'] !== locale){
res.cookie('locale', locale, { signed: true, httpOnly: true });
}
// Set the language that i18n will use for this request
req.setLocale(locale);
next();
};
3 changes: 2 additions & 1 deletion config/api-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ module.exports = {
'smtpServer': '', // If using Nodemailer, your SMTP server hostname goes here
'smtpPort': '', // If using Nodemailer, your SMTP server port goes here
'smtpUsername': '', // If using Nodemailer, your SMTP server username goes here
'smtpPassword': '' // If using Nodemailer, your SMTP password goes here
'smtpPassword': '', // If using Nodemailer, your SMTP password goes here
'smtpSecure': true // true for 465, false for other ports
};
20 changes: 18 additions & 2 deletions helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const mongoose = require('mongoose');
const Log = mongoose.model('Log');
var moment = require('moment-timezone');
const icalGenerator = require('ical-generator');

var i18n = require('i18n');
// LOGGING

function addToLog(process, status, message) {
Expand Down Expand Up @@ -51,7 +51,23 @@ function exportIcal(events, calendarName) {
return string;
}

function getI18nHelpers() {
var _helpers = {};
// Declare the i18n helper function in the handlebar
// __ Not considering singular and plural
_helpers.__ = function () {
return i18n.__.apply(this, arguments);
};
// __n Considering singular and plural
_helpers.__n = function () {
return i18n.__n.apply(this, arguments);
};

return _helpers;
}

module.exports = {
addToLog,
exportIcal,
}
getI18nHelpers,
}
131 changes: 131 additions & 0 deletions locales/en-US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"notFound": "Event not found!",
"404Desc": "It may have never existed, or if it finished more than a week ago, it's been removed from the server. Don't despair - why not create a new one? I for one would love to come to your ocarina recital.",
"editEvent": "Edit event",
"started": "Started",
"ended": "Ended",
"hostedBy": "Hosted by</span> {{eventData.hostName}}",
"partOf": "Part of</span> <a href='/group/{{eventData.eventGroup.id}}'>{{eventData.eventGroup.name}}</a>",
"copy": "Copy",
"addToGC": "Add to Google Calendar",
"exportAsICS": "Export as ICS",
"showOnGM": "Show on Google Maps",
"showOnOSM": "Show on OpenStreetMap",
"concludedDel": "This event has concluded. It can no longer be edited, and will be automatically deleted <span class='daysToDeletion'></span>.",
"eventWelcome": "Welcome to your event!",
"eventPasswordAlert": "Your secret editing password for this event is: <strong>{{eventData.editToken}}</strong>. It's been saved in your browser storage, and if you supplied your email, it's also been sent to you. If you didn't supply your email, you <strong>must save it somewhere safe</strong>, because it won't be shown again!",
"eventShare": "To share your event, use the link you can see just above this message - that way your attendees won't be able to edit or delete your event!",
"about": "About",
"attendees": "Attendees",
"addMe": "Add me",
"removeMe": "Remove me",
"eventAtCapacity": "This event is at capacity.",
"remaining": "remaining - add yourself now!",
"removeUser": "Remove user from event",
"noAttendees": "No attendees yet!",
"addSelfTitle": "Add yourself to '{{eventData.name}}'",
"yourName": "Your name",
"peopleNum": "How many people in your party?",
"yourEmail": "Your email",
"joinEmailDesc": "If you provide your email, you will receive updates to the event.",
"optional": "Optional.",
"delPassword": "Deletion password",
"delPasswordDesc": "You will need this password if you want to remove yourself from the list of event attendees. If you provided your email, you'll receive it by email. Otherwise, write it down now because it will <strong>not be shown again</strong>.",
"close": "Close",
"addSelf": "Add myself",
"removeSelfTitle": "Remove yourself from '{{eventData.name}}'",
"lostPassword": "Lost your password? Get in touch with the event organiser.",
"removeSelf": "Remove myself",
"removeAttendeeTitle": "Remove attendee from '{{eventData.name}}'",
"confirmRemoveAttendee": "Are you sure you want to remove this attendee from the event? This action cannot be undone.",
"removeAttendee": "Remove attendee",
"discussion": "Discussion",
"send": "Send",
"reply": "Reply",
"del": "Delete",
"editPassword": "Enter editing password",
"editPasswordDesc": "Enter the editing password you received by email or were shown when the event was created.",
"confirmDelEvent": "Are you sure you want to delete this event? This action cannot be undone.",
"delEvent": "Delete event",
"copied": "Copied!",
"incorrectPassword": "That editing password is incorrect. Try again.",
"numValidation": "Please enter a number between 1 and ${response.data.freeSpots}",
"editGroup": "Edit group",
"groupWelcome": "Welcome to your event group! We've just sent you an email with your secret editing link, which you can also see in the address bar above. Haven't got the email? Check your spam or junk folder. To share your event group, use the link you can see just below this message - that way your attendees won't be able to edit or delete your event group!",
"urlPaste": "Paste this URL into your calendar app to subscribe to a live feed of events from this group.",
"subscribe": "Subscribe to updates",
"groupAddEvent": "To add an event to this group, copy and paste the two codes below into the \"Event Group\" box when creating a new event or editing an existing event.",
"eventGroupId": "Event group ID",
"eventGroupEditPassword": "Event group editing password",
"upcomingEvents": "Upcoming events",
"noEvents": "No events!",
"groupDelConfirm": "Are you sure you want to delete this event group? This action cannot be undone.",
"groupDelDesc": "This will <strong>not</strong> delete the individual events contained in this group. They can be linked to another group later.",
"groupDel": "Delete event group",
"groupSub": "Subscribe to '{{eventGroupData.name}}'",
"receiveGroupUpdates": "Enter your email address to receive updates whenever a new event is created in this group.",
"sub": "Subscribe",
"homeIntro": "A quick and easy way to make and share events which respects your privacy.",
"homeDescription": "You don't need to sign up for an account. When you create an event, we generate a password which allows you to edit the event. Send all your guests the public link, and all your co-hosts the secret editing link containing the password. A week after the event finishes, it's deleted from our servers for ever, and your email goes with it.",
"homePrivacy": "Also, we don't show you ads, don't sell your data, and never send you unnecessary emails.",
"homeVisibility": "But remember: all our events are visible to anyone who knows the link, so probably don't use <strong>gath<span class='text-muted'>io</span></strong> to plot your surprise birthday party or revolution. Or whatever, you do you.",
"homeSupport": "If you find yourself using and enjoying <strong>gath<span class='text-muted'>io</span></strong>, consider buying me a coffee. It'll help keep the site running!",
"homeKofi": "Support Me on Ko-fi",
"newEvent": "New event",
"newEventDesc": "Events are visible to anyone who knows the link.",
"createEvent": "Create a new event",
"importEvent": "Import an existing event",
"createGroup": "Create a new event group",
"options": "Options",
"usersCanAttend": "Users can mark themselves as attending this event",
"usersCanComment": "Users can post comments on this event",
"listdisplay": "Display the list of attendees",
"edit": "Edit",
"groupName": "Group name",
"description": "Description",
"link": "Link",
"host": "Host or organisation name",
"coverImage": "Cover image",
"recommendedDimensions": "Recommended dimensions (w x h): 920px by 300px.",
"delGroup": "Delete event group",
"save": "Save changes",
"eventName": "Event name",
"location": "Location",
"starts": "Starts",
"ends": "Ends",
"timezone": "Timezone",
"markdownSupported": "<a href='https://commonmark.org/help/'>Markdown</a> formatting supported.",
"hostName": "Host name",
"chooseFile": "Choose file",
"delImage": "Delete image",
"partOfEventGroup": "This event is part of an event group",
"linkToEventGroup": "Link this event to an event group",
"shortStringDesc": "You can find this short string of characters in the event group's link, in your confirmation email, or on the event group's page.",
"groupSecretCode": "Event group secret editing code",
"longStringDesc": "You can find this long string of characters in the confirmation email you received when you created the event group.",
"setAttendeeLimit": "Set a limit on the maximum number of attendees",
"attendeeLimit": "Attendee limit",
"importDesc": "Upload an .ics file here to instantly create an event. You can save a Facebook event as an .ics file by clicking on the context menu next to the \"Import\" and \"Edit\" buttons on the event page and choosing the \"Export Event\" option. Then select the \"Save to calendar\" option and save the file on your computer.",
"selectFile": "Select file",
"import": "Import",
"emailDesc": "If you provide your email, we will send your secret editing password here, and use it to notify you of updates to the event.",
"emailDescGroup": "If you provide your email, we will send your secret editing password here.",
"changeFile": "Change file",
"groupDesc": "An event group is a holding area for a set of linked events, like a series of film nights, a festival, or a band tour. You can share a public link to your event group just like an individual event link, and people who know the secret editing code (sent in an email when you create the event group) will be able to add future events to the group.",
"groupRemovalNotice": "Event groups do not get automatically removed like events do, but events which have been removed from {{siteName}} will of course not show up in an event group.",
"nicerEvents": "Nicer events",
"create": "Create",
"orAlias": "Or an alias, perhaps...",
"commentPlaceholder": "What would you like to ask?",
"replyPlaceholder": "What would you like to reply?",
"right": "Get it right!",
"snappy": "Make it snappy.",
"linkDescGroup": "For tickets or a page with more information (optional).",
"willBeShownGroup": "Will be shown on the event group page (optional).",
"specific": "Be specific.",
"linkDesc": "For tickets or another event page (optional).",
"willBeShownEvent": "Will be shown on the event page (optional).",
"enterNumber": "Enter a number.",
"click": "Click me!",
"editLater": "You can always edit it later."
}
Loading