diff options
-rw-r--r-- | locales/en.json | 7 | ||||
-rw-r--r-- | locales/ja.json | 7 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | pnpm-lock.yaml | 11 | ||||
-rwxr-xr-x | src/app.ts | 32 | ||||
-rwxr-xr-x | views/event.handlebars | 4 |
6 files changed, 40 insertions, 22 deletions
diff --git a/locales/en.json b/locales/en.json index 118f139..afa6d5f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -42,6 +42,9 @@ "event.ended": "Ended", "event.enternum": "Enter a number.", "event.hidden": "(hidden from public list)", + "event.hiddenattendee_one": "{{count}} hidden attendee", + "event.hiddenattendee_other": "{{count}} hidden attendees", + "event.hiddenattendee_zero": "No hidden attendee", "event.hostedby": "Hosted by</span> {{eventData.hostName}}", "event.ICSexport": "Export as ICS", "event.locationdesc": "Be specific.", @@ -75,7 +78,9 @@ "event.p.timezone": "Timezone", "event.partof": "<a href='/group/{{eventData.eventGroup.id}}'>{{eventData.eventGroup.name}}</a>", "event.postbutton": "Post comment", - "event.remaining": "{{spotsRemaining}} {{plural spotsRemaining \"spot(s)\"}} remaining - add yourself now!", + "event.remaining_one": "{{count}} spot remaining - add yourself now!", + "event.remaining_other": "{{count}} spots remaining - add yourself now!", + "event.remaining_zero": "This event is at capacity.", "event.remove-attendee": "Remove {{ attendeeName }} from {{eventData.name}}", "event.removeAttendee": "Remove attendee", "event.removeattendeedesc": "Remove attendee from '{{eventData.name}}'", diff --git a/locales/ja.json b/locales/ja.json index a0ae374..f04c342 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -42,6 +42,9 @@ "event.ended": "終了済み", "event.enternum": "人数を入力してください", "event.hidden": "( 匿名 )", + "event.hiddenattendee_one": "匿名 {{count}} 人", + "event.hiddenattendee_other": "匿名 {{count}} 人", + "event.hiddenattendee_zero": "匿名 なし", "event.hostedby": "主催 : </span> {{eventData.hostName}}", "event.ICSexport": "iCalendar ファイル出力", "event.locationdesc": "具体的に。", @@ -75,7 +78,9 @@ "event.p.timezone": "タイムゾーン", "event.partof": "<a href='/group/{{eventData.eventGroup.id}}'>{{eventData.eventGroup.name}}</a> グループのイベント", "event.postbutton": "送信", - "event.remaining": "残り {{spotsRemaining}} 枠 - 参加登録しましょう !", + "event.remaining_one": "残り {{count}} 枠 - 参加登録しましょう !", + "event.remaining_other": "残り {{count}} 枠 - 参加登録しましょう !", + "event.remaining_zero": "このイベントは満員です。", "event.remove-attendee": "'{{eventData.name}}' から {{ attendeeName }} を削除", "event.removeAttendee": "参加者を削除", "event.removeattendeedesc": "'{{eventData.name}}' から参加者を削除", diff --git a/package.json b/package.json index e297d10..0182815 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@types/cookie-parser": "^1.4.7", "@types/dompurify": "^3.0.5", "@types/express": "^4.17.21", + "@types/handlebars": "^4.1.0", "@types/i18next-fs-backend": "^1.2.0", "@types/ical": "^0.8.3", "@types/jsdom": "^21.1.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c486f9..c45ff07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,6 +129,9 @@ importers: '@types/express': specifier: ^4.17.21 version: 4.17.21 + '@types/handlebars': + specifier: ^4.1.0 + version: 4.1.0 '@types/i18next-fs-backend': specifier: ^1.2.0 version: 1.2.0 @@ -445,6 +448,10 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/handlebars@4.1.0': + resolution: {integrity: sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==} + deprecated: This is a stub types definition. handlebars provides its own type definitions, so you do not need this installed. + '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -2825,6 +2832,10 @@ snapshots: '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 + '@types/handlebars@4.1.0': + dependencies: + handlebars: 4.7.8 + '@types/http-errors@2.0.4': {} '@types/i18next-fs-backend@1.2.0': @@ -1,5 +1,6 @@ import express from "express"; -import hbs from "express-handlebars"; +import hbs, { ExpressHandlebars } from "express-handlebars"; +import Handlebars from 'handlebars'; import cookieParser from "cookie-parser"; import i18next from "i18next"; import Backend from "i18next-fs-backend"; @@ -98,31 +99,20 @@ async function initializeApp() { }); // View engine // - const hbsInstance = hbs.create({ + const hbsInstance: ExpressHandlebars = hbs.create({ defaultLayout: "main", partialsDir: ["views/partials/"], layoutsDir: "views/layouts/", helpers: { - plural: function (number: number, text: string) { - var singular = number === 1; - // If no text parameter was given, just return a conditional s. - if (typeof text !== "string") return singular ? "" : "s"; - // Split with regex into group1/group2 or group1(group3) - var match = text.match(/^([^()\/]+)(?:\/(.+))?(?:\((\w+)\))?/); - // If no match, just append a conditional s. - if (!match) return text + (singular ? "" : "s"); - // We have a good match, so fire away - return ( - (singular && match[1]) || // Singular case - match[2] || // Plural case: 'bagel/bagels' --> bagels - match[1] + (match[3] || "s") - ); // Plural case: 'bagel(s)' or 'bagel' --> bagels - }, json: function (context: any) { return JSON.stringify(context); }, // i18nextヘルパーを追加 - ...getI18nHelpers() + ...getI18nHelpers(), + plural: function (key: string, count: number, options: any) { // ★plural ヘルパーを登録 + const translation = i18next.t(key, { count: count }); + return translation; + } }, }); @@ -135,6 +125,12 @@ async function initializeApp() { console.error('handlebars-i18next helper is not properly loaded'); } + + (hbsInstance.handlebars as typeof Handlebars).registerHelper('pluralize', function(count: number, key: string, options: any) { + const translation = i18next.t(key, { count: count }); + return translation; + }); + app.engine("handlebars", hbsInstance.engine); app.set("view engine", "handlebars"); app.set("hbsInstance", hbsInstance); diff --git a/views/event.handlebars b/views/event.handlebars index c36ab30..009dfbd 100755 --- a/views/event.handlebars +++ b/views/event.handlebars @@ -149,7 +149,7 @@ {{#if noMoreSpots}} <div class="alert alert-warning text-center" id="attendees-alert">{{t "event.capacity" }}</div> {{else}} - <div class="alert alert-warning text-center" id="attendees-alert">{{t "event.remaining" }}</div> + <div class="alert alert-warning text-center" id="attendees-alert">{{plural "event.remaining" spotsRemaining }}</div> {{/if}} {{/if}} {{#if numberOfAttendees}} @@ -165,7 +165,7 @@ </ul> {{#unless editingEnabled}} {{#if numberOfHiddenAttendees}} - <div class="hidden-attendees-message">{{numberOfHiddenAttendees}} hidden attendee{{plural numberOfHiddenAttendees ""}}</div> + <div class="hidden-attendees-message">{{plural "event.hiddenattendee" numberOfHiddenAttendees }}</div> {{/if}} {{/unless}} {{else}} |