Skip to content

Commit

Permalink
Initialize multiple language and start translations (mrvautin#91)
Browse files Browse the repository at this point in the history
* Initialize multiple language and start translations

* continue with translation

* end translations for en and it

* fix json syntax en translation, otherwise i18n reset the file

* add language info in config

* fix json format invalid

* solve review comments
  • Loading branch information
anddimario authored and mrvautin committed Nov 6, 2019
1 parent 161be30 commit d3abc37
Show file tree
Hide file tree
Showing 47 changed files with 891 additions and 438 deletions.
100 changes: 64 additions & 36 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const { runIndexing } = require('./lib/indexing');
const { addSchemas } = require('./lib/schema');
const { initDb } = require('./lib/db');
let handlebars = require('express-handlebars');
const i18n = require('i18n');

// Validate our settings schema
const Ajv = require('ajv');
Expand Down Expand Up @@ -68,6 +69,20 @@ const authorizenet = require('./routes/payments/authorizenet');

const app = express();

// Language initialize
i18n.configure({
locales: config.availableLanguages,
defaultLocale: config.defaultLocale,
cookie: 'locale',
queryParameter: 'lang',
directory: `${__dirname}/locales`,
directoryPermissions: '755',
api: {
__: '__', // now req.__ becomes req.__
__n: '__n' // and req.__n can be called as req.__n
}
});

// view engine setup
app.set('views', path.join(__dirname, '/views'));
app.engine('hbs', handlebars({
Expand All @@ -81,6 +96,16 @@ app.set('view engine', 'hbs');
// helpers for the handlebar templating platform
handlebars = handlebars.create({
helpers: {
// Language helper
__: () => { return i18n.__(this, arguments); },
__n: () => { return i18n.__n(this, arguments); },
availableLanguages: (block) => {
let total = ''
for(const lang of i18n.getLocales()){
total += block.fn(lang);
}
return total;
},
perRowClass: (numProducts) => {
if(parseInt(numProducts) === 1){
return'col-md-12 col-xl-12 col m12 xl12 product-item';
Expand Down Expand Up @@ -123,22 +148,22 @@ handlebars = handlebars.create({
},
getStatusColor: (status) => {
switch(status){
case'Paid':
return'success';
case'Approved':
return'success';
case'Approved - Processing':
return'success';
case'Failed':
return'danger';
case'Completed':
return'success';
case'Shipped':
return'success';
case'Pending':
return'warning';
default:
return'danger';
case'Paid':
return'success';
case'Approved':
return'success';
case'Approved - Processing':
return'success';
case'Failed':
return'danger';
case'Completed':
return'success';
case'Shipped':
return'success';
case'Pending':
return'warning';
default:
return'danger';
}
},
checkProductOptions: (opts) => {
Expand Down Expand Up @@ -194,26 +219,26 @@ handlebars = handlebars.create({
},
ifCond: (v1, operator, v2, options) => {
switch(operator){
case'==':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'!=':
return(v1 !== v2) ? options.fn(this) : options.inverse(this);
case'===':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'<':
return(v1 < v2) ? options.fn(this) : options.inverse(this);
case'<=':
return(v1 <= v2) ? options.fn(this) : options.inverse(this);
case'>':
return(v1 > v2) ? options.fn(this) : options.inverse(this);
case'>=':
return(v1 >= v2) ? options.fn(this) : options.inverse(this);
case'&&':
return(v1 && v2) ? options.fn(this) : options.inverse(this);
case'||':
return(v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
case'==':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'!=':
return(v1 !== v2) ? options.fn(this) : options.inverse(this);
case'===':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'<':
return(v1 < v2) ? options.fn(this) : options.inverse(this);
case'<=':
return(v1 <= v2) ? options.fn(this) : options.inverse(this);
case'>':
return(v1 > v2) ? options.fn(this) : options.inverse(this);
case'>=':
return(v1 >= v2) ? options.fn(this) : options.inverse(this);
case'&&':
return(v1 && v2) ? options.fn(this) : options.inverse(this);
case'||':
return(v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
},
isAnAdmin: (value, options) => {
Expand Down Expand Up @@ -262,6 +287,9 @@ app.use(session({
store: store
}));

// Set locales from session
app.use(i18n.init);

// serving static content
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views', 'themes')));
Expand Down
6 changes: 6 additions & 0 deletions config/baseSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@
},
"secretSession": {
"type": "string"
},
"availableLanguages": {
"type": "array"
},
"defaultLocale": {
"type": "string"
}
},
"required": [
Expand Down
4 changes: 3 additions & 1 deletion config/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@
"databaseConnectionString": "mongodb://127.0.0.1:27017/expresscart",
"theme": "Cloth",
"trackStock": false,
"orderHook": ""
"orderHook": "",
"availableLanguages": ["en", "it"],
"defaultLocale": "en"
}
164 changes: 164 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
{
"Languages": "Languages",
"en": "English",
"it": "Italiano",
"Cart": "Cart",
"Name": "Name",
"New": "New",
"Settings": "Settings",
"General settings": "General settings",
"Address 1": "Address 1",
"Address 2": "Address 2",
"Country": "Country",
"State": "State",
"Postcode": "Postcode",
"Phone number": "Phone number",
"Creation date": "Creation date",
"Customers can be filtered by: email, name or phone number": "Customers can be filtered by: email, name or phone number",
"Customers": "Customers",
"Filtered term": "Filtered term",
"No orders found": "No orders found",
"Email address": "Email address",
"Please enter your email address": "Please enter your email address",
"Reset": "Reset",
"Please sign in": "Please sign in",
"Sign in": "Sign in",
"Update status": "Update status",
"Go Back": "Go Back",
"Order date": "Order date",
"Order ID": "Order ID",
"Payment Gateway ref": "Payment Gateway ref",
"Payment Gateway": "Payment Gateway",
"Order total amount": "Order total amount",
"First name": "First name",
"Last name": "Last name",
"Order comment": "Order comment",
"Products ordered": "Products ordered",
"Options": "Options",
"Filter": "Filter",
"By status": "By status",
"Orders can be filtered by: surname, email address or postcode/zipcode": "Orders can be filtered by: surname, email address or postcode/zipcode",
"Completed": "Completed",
"Paid": "Paid",
"Created": "Created",
"Cancelled": "Cancelled",
"Declined": "Declined",
"Shipped": "Shipped",
"Pending": "Pending",
"Orders": "Orders",
"Recent orders": "Recent orders",
"Status": "Status",
"Upload image": "Upload image",
"Save product": "Save product",
"Edit product": "Edit product",
"Product title": "Product title",
"Product price": "Product price",
"Published": "Published",
"Draft": "Draft",
"Stock level": "Stock level",
"Product description": "Product description",
"Validate": "Validate",
"This sets a readable URL for the product": "This sets a readable URL for the product",
"Product options": "Product options",
"Label": "Label",
"Type": "Type",
"Add": "Add",
"Remove": "Remove",
"Here you can set options for your product. Eg: Size, color, style": "Here you can set options for your product. Eg: Size, color, style",
"Allow comment": "Allow comment",
"Allow free form comments when adding products to cart": "Allow free form comments when adding products to cart",
"Product tag words": "Product tag words",
"Tag words used to indexed products, making them easier to find and filter.": "Tag words used to indexed products, making them easier to find and filter.",
"Product images": "Product images",
"Delete": "Delete",
"main image": "main image",
"Set as main image": "Set as main image",
"No images have been uploaded for this product": "No images have been uploaded for this product",
"Product image upload": "Product image upload",
"Select file": "Select file",
"Upload": "Upload",
"New product": "New product",
"Products can be filtered by: product title or product description keywords": "Products can be filtered by: product title or product description keywords",
"Products": "Products",
"Recent products": "Recent products",
"Confirm": "Confirm",
"Update": "Update",
"Setting_menu_explain": "Here you can setup a menu to displayed on your shopping cart. You can use this menu to filter your products by specifying a keyword in the \"link\" field. Eg: To show products with a keyword (or tag) of boots you would set the menu field to \"Backpacks\" and a link value \"backpack\". You can also use this menu to link to static pages, Eg: shipping, returns, help, about, contact etc.",
"Static page": "Static page",
"Page name": "Page name",
"A friendly name to manage the static page.": "A friendly name to manage the static page.",
"Page slug": "Page slug",
"Page_Slug_Description": "This is the relative URL of the page. Eg: A setting of \"about\" would make the page available at: mydomain.com/about",
"Page Enabled": "Page Enabled",
"Page content": "Page content",
"Here you can enter the content you wish to be displayed on your static page.": "Here you can enter the content you wish to be displayed on your static page.",
"New page": "New page",
"Static pages": "Static pages",
"Static_Pages_Info": "Here you can setup and manage static pages for your shopping cart. You may want to setup a page with a little bit about your business called \"About\" or \"Contact Us\" etc.",
"Edit": "Edit",
"There are currently no static pages setup. Please setup a static page.": "There are currently no static pages setup. Please setup a static page.",
"Create new": "Create new",
"Search": "Search",
"Cart name": "Cart name",
"This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.": "This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.",
"Cart description": "Cart description",
"This description shows when your website is listed in search engine results.": "This description shows when your website is listed in search engine results.",
"Cart image/logo": "Cart image/logo",
"Cart URL": "Cart URL",
"This URL is used in sitemaps and when your customer returns from completing their payment.": "This URL is used in sitemaps and when your customer returns from completing their payment.",
"This is used as the \"from\" email when sending receipts to your customers.": "This is used as the \"from\" email when sending receipts to your customers.",
"Flat shipping rate": "Flat shipping rate",
"A flat shipping rate applied to all orders.": "A flat shipping rate applied to all orders.",
"Free shipping threshold": "Free shipping threshold",
"Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.",
"Payment gateway": "Payment gateway",
"Payment_Gateway_Info": "You will also need to configure your payment gateway credentials in the `/config/&lt;gateway_name&gt;.json` file.",
"Currency symbol": "Currency symbol",
"Set this to your currency symbol. Eg: $, £, €": "Set this to your currency symbol. Eg: $, £, €",
"Theme": "Theme",
"Theme_Info": "Themes are loaded from `/public/themes/`",
"Products per row": "Products per row",
"The number of products to be displayed across the page.": "The number of products to be displayed across the page.",
"Products per page": "Products per page",
"The number of products to be displayed on each page.": "The number of products to be displayed on each page.",
"Menu Enabled": "Menu Enabled",
"Menu_Enabled_Info": "If a menu is set you can set it up <a href=\"/admin/settings/menu\">here</a>.",
"Menu header": "Menu header",
"The heading text for your menu.": "The heading text for your menu.",
"Menu location": "Menu location",
"The location of your menu.": "The location of your menu.",
"Google_Analytics_Info": "Your Google Analytics code. Please also inlude the \"script\" tags - <a href=\"https://support.google.com/analytics/answer/1032385?hl=en\" target=\"_blank\">Help</a>",
"Custom CSS": "Custom CSS",
"Send test email": "Send test email",
"Users name": "Users name",
"User email": "User email",
"Password confirm": "Password confirm",
"User password": "User password",
"Complete setup": "Complete setup",
"User is admin?": "User is admin?",
"Generate": "Generate",
"New User": "New User",
"Create": "Create",
"Role": "Role",
"User": "User",
"No products found": "No products found",
"Category": "Category",
"Search results": "Search results",
"Add to cart": "Add to cart",
"Pay now": "Pay now",
"Customer details": "Customer details",
"Existing customer": "Existing customer",
"Forgotten": "Forgotten",
"Change customer": "Change customer",
"Enter a password to create an account for next time": "Enter a password to create an account for next time",
"Create account": "Create account",
"Your payment has been successfully processed": "Your payment has been successfully processed",
"Your payment has failed. Please try again or contact us.": "Your payment has failed. Please try again or contact us.",
"Please retain the details above as a reference of payment.": "Please retain the details above as a reference of payment.",
"Quantity": "Quantity",
"Leave a comment?": "Leave a comment?",
"Cart contents": "Cart contents",
"Shipping": "Shipping:",
"Empty cart": "Empty cart",
"List": "List"
}
Loading

0 comments on commit d3abc37

Please sign in to comment.