apostrophe 3.6.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +4 -0
- package/.github/workflows/main.yml +45 -0
- package/CHANGELOG.md +92 -3
- package/README.md +2 -3
- package/index.js +104 -3
- package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +5 -1
- package/modules/@apostrophecms/area/ui/apos/apps/AposAreas.js +15 -10
- package/modules/@apostrophecms/asset/index.js +105 -15
- package/modules/@apostrophecms/attachment/index.js +1 -4
- package/modules/@apostrophecms/db/index.js +5 -6
- package/modules/@apostrophecms/doc/index.js +2 -0
- package/modules/@apostrophecms/doc-type/index.js +39 -16
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocContextMenu.vue +13 -1
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +0 -1
- package/modules/@apostrophecms/i18n/i18n/en.json +23 -4
- package/modules/@apostrophecms/i18n/i18n/es.json +1 -2
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +0 -1
- package/modules/@apostrophecms/i18n/i18n/sk.json +3 -4
- package/modules/@apostrophecms/i18n/index.js +36 -6
- package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +6 -3
- package/modules/@apostrophecms/image-widget/index.js +2 -1
- package/modules/@apostrophecms/image-widget/views/widget.html +12 -2
- package/modules/@apostrophecms/job/index.js +165 -220
- package/modules/@apostrophecms/login/index.js +0 -15
- package/modules/@apostrophecms/migration/index.js +1 -1
- package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +151 -61
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalConfirm.vue +8 -6
- package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +12 -15
- package/modules/@apostrophecms/module/index.js +1 -4
- package/modules/@apostrophecms/notification/index.js +116 -8
- package/modules/@apostrophecms/notification/ui/apos/components/AposNotification.vue +89 -11
- package/modules/@apostrophecms/notification/ui/apos/components/TheAposNotifications.vue +1 -1
- package/modules/@apostrophecms/page/index.js +84 -52
- package/modules/@apostrophecms/page-type/index.js +5 -1
- package/modules/@apostrophecms/piece-type/index.js +183 -61
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +180 -50
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +1 -3
- package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerSelectBox.vue +141 -0
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +35 -6
- package/modules/@apostrophecms/schema/index.js +81 -25
- package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +9 -3
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputAttachment.vue +11 -160
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputPassword.vue +11 -4
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputRange.vue +2 -2
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +24 -6
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +0 -4
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +0 -7
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +0 -2
- package/modules/@apostrophecms/schema/ui/apos/components/AposLogo.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposLogoIcon.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposLogoPadless.vue +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +0 -1
- package/modules/@apostrophecms/search/index.js +53 -33
- package/modules/@apostrophecms/task/index.js +7 -3
- package/modules/@apostrophecms/template/index.js +7 -11
- package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +5 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposCellContextMenu.vue +1 -1
- package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +205 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposMinMaxCount.vue +9 -3
- package/modules/@apostrophecms/ui/ui/apos/lib/i18next.js +16 -2
- package/modules/@apostrophecms/ui/ui/apos/mixins/AposPublishMixin.js +3 -2
- package/modules/@apostrophecms/ui/ui/apos/scss/global/_tables.scss +4 -3
- package/modules/@apostrophecms/util/ui/src/util.js +15 -0
- package/modules/@apostrophecms/widget-type/index.js +1 -1
- package/modules/@apostrophecms/widget-type/ui/apos/mixins/AposWidgetMixin.js +5 -19
- package/package.json +2 -2
- package/test/job.js +224 -0
- package/test/pieces.js +34 -0
- package/test-lib/util.js +32 -0
- package/.circleci/config.yml +0 -94
- package/.scratch.md +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// This module establishes `apos.db`, the
|
|
1
|
+
// This module establishes `apos.db`, the MongoDB database object.
|
|
2
2
|
//
|
|
3
3
|
// ## Options
|
|
4
4
|
//
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
//
|
|
21
21
|
// ### `client`
|
|
22
22
|
//
|
|
23
|
-
// An existing MongoDB connection (MongoClient) object. If present,
|
|
24
|
-
// connection instance is created that reuses the same sockets,
|
|
23
|
+
// An existing MongoDB connection (MongoClient) object. If present, it is used
|
|
25
24
|
// and `uri`, `host`, `connect`, etc. are ignored.
|
|
26
25
|
//
|
|
27
26
|
// ### `versionCheck`
|
|
@@ -40,7 +39,7 @@
|
|
|
40
39
|
// allow other modules to drop related non-MongoDB resources at the
|
|
41
40
|
// same time, if desired.
|
|
42
41
|
//
|
|
43
|
-
// Note that `apos.db` is the
|
|
42
|
+
// Note that `apos.db` is the MongoDB database object, not this module.
|
|
44
43
|
// You shouldn't need to talk to this module after startup, but you can
|
|
45
44
|
// access it as `apos.modules['@apostrophecms/db']` if you wish. You can
|
|
46
45
|
// also access `apos.dbClient` if you need the MongoClient object.
|
|
@@ -81,8 +80,8 @@ module.exports = {
|
|
|
81
80
|
},
|
|
82
81
|
methods(self) {
|
|
83
82
|
return {
|
|
84
|
-
// Open the database connection. Always
|
|
85
|
-
// sensible defaults.
|
|
83
|
+
// Open the database connection. Always uses MongoClient with its
|
|
84
|
+
// sensible defaults. Builds a URI if necessary, so we can call it
|
|
86
85
|
// in a consistent way.
|
|
87
86
|
//
|
|
88
87
|
// One default we override: if the connection is lost, we keep
|
|
@@ -439,6 +439,7 @@ module.exports = {
|
|
|
439
439
|
await self.insertBody(req, doc, options);
|
|
440
440
|
await m.emit('afterInsert', req, doc, options);
|
|
441
441
|
await m.emit('afterSave', req, doc, options);
|
|
442
|
+
// TODO: Remove `afterLoad` in next major version. Deprecated.
|
|
442
443
|
await m.emit('afterLoad', req, [ doc ]);
|
|
443
444
|
return doc;
|
|
444
445
|
},
|
|
@@ -474,6 +475,7 @@ module.exports = {
|
|
|
474
475
|
await self.updateBody(req, doc, options);
|
|
475
476
|
await m.emit('afterUpdate', req, doc, options);
|
|
476
477
|
await m.emit('afterSave', req, doc, options);
|
|
478
|
+
// TODO: Remove `afterLoad` in next major version. Deprecated.
|
|
477
479
|
await m.emit('afterLoad', req, [ doc ]);
|
|
478
480
|
return doc;
|
|
479
481
|
},
|
|
@@ -389,7 +389,7 @@ module.exports = {
|
|
|
389
389
|
self.schema = self.apos.schema.compose({
|
|
390
390
|
addFields: self.apos.schema.fieldsToArray(`Module ${self.__meta.name}`, self.fields),
|
|
391
391
|
arrangeFields: self.apos.schema.groupsToArray(self.fieldsGroups)
|
|
392
|
-
});
|
|
392
|
+
}, self);
|
|
393
393
|
if (self.options.slugPrefix) {
|
|
394
394
|
if (self.options.slugPrefix === 'deduplicate-') {
|
|
395
395
|
const req = self.apos.task.getReq();
|
|
@@ -545,8 +545,11 @@ module.exports = {
|
|
|
545
545
|
|
|
546
546
|
await self.apos.schema.convert(req, schema, input, doc);
|
|
547
547
|
|
|
548
|
-
doc.copyOfId = copyOf && copyOf._id;
|
|
549
548
|
if (copyOf) {
|
|
549
|
+
if (copyOf._id) {
|
|
550
|
+
doc.copyOfId = copyOf._id;
|
|
551
|
+
}
|
|
552
|
+
|
|
550
553
|
self.apos.schema.regenerateIds(req, fullSchema, doc);
|
|
551
554
|
}
|
|
552
555
|
},
|
|
@@ -554,17 +557,9 @@ module.exports = {
|
|
|
554
557
|
// taking into account issues like relationship fields keeping their data in
|
|
555
558
|
// a separate ids property, etc.
|
|
556
559
|
fieldsPresent(input) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
if (field.type.name.substring(0, 5) === '_relationship') {
|
|
561
|
-
if (_.has(input, field.idsStorage)) {
|
|
562
|
-
output.push(field.name);
|
|
563
|
-
}
|
|
564
|
-
} else {
|
|
565
|
-
output.push(field.name);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
560
|
+
return self.schema
|
|
561
|
+
.filter((field) => _.has(input, field.name))
|
|
562
|
+
.map((field) => field.name);
|
|
568
563
|
},
|
|
569
564
|
// Returns a query that finds docs the current user can edit. Unlike
|
|
570
565
|
// find(), this query defaults to including docs in the archive. Subclasses
|
|
@@ -738,7 +733,7 @@ module.exports = {
|
|
|
738
733
|
},
|
|
739
734
|
// Localize (export) the given draft to another locale, creating the document in the
|
|
740
735
|
// other locale if necessary. By default, if the document already exists in the
|
|
741
|
-
// other locale, it is not
|
|
736
|
+
// other locale, it is not overwritten. Use the `update: true` option to change that.
|
|
742
737
|
// You can localize starting from either draft or published content. Either way what
|
|
743
738
|
// gets created or updated in the other locale is a draft.
|
|
744
739
|
async localize(req, draft, toLocale, options = { update: false }) {
|
|
@@ -1217,6 +1212,21 @@ module.exports = {
|
|
|
1217
1212
|
// cursors.
|
|
1218
1213
|
|
|
1219
1214
|
project: {
|
|
1215
|
+
launder (p) {
|
|
1216
|
+
// check that project is an object
|
|
1217
|
+
if (!p || typeof p !== 'object' || Array.isArray(p)) {
|
|
1218
|
+
return {};
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
const projection = Object.entries(p).reduce((acc, [ key, val ]) => {
|
|
1222
|
+
return {
|
|
1223
|
+
...acc,
|
|
1224
|
+
[key]: self.apos.launder.boolean(val)
|
|
1225
|
+
};
|
|
1226
|
+
}, {});
|
|
1227
|
+
|
|
1228
|
+
return projection;
|
|
1229
|
+
},
|
|
1220
1230
|
finalize() {
|
|
1221
1231
|
let projection = query.get('project') || {};
|
|
1222
1232
|
// Keys beginning with `_` are computed values
|
|
@@ -1259,6 +1269,14 @@ module.exports = {
|
|
|
1259
1269
|
if (query.get('search')) {
|
|
1260
1270
|
// MongoDB mandates this if we want to sort on search result quality
|
|
1261
1271
|
projection.textScore = { $meta: 'textScore' };
|
|
1272
|
+
} else if (projection.textScore) {
|
|
1273
|
+
// Gracefully elide the textScore projection when it is not useful and
|
|
1274
|
+
// would cause an error anyway.
|
|
1275
|
+
//
|
|
1276
|
+
// This allows the reuse of the `project()` value passed to one query
|
|
1277
|
+
// in a second query without worrying about whether the second query
|
|
1278
|
+
// contains a search or not
|
|
1279
|
+
delete projection.textScore;
|
|
1262
1280
|
}
|
|
1263
1281
|
query.set('project', projection);
|
|
1264
1282
|
}
|
|
@@ -1442,9 +1460,14 @@ module.exports = {
|
|
|
1442
1460
|
attachments: {
|
|
1443
1461
|
def: false,
|
|
1444
1462
|
after(results) {
|
|
1445
|
-
|
|
1446
|
-
|
|
1463
|
+
const attachments = query.get('attachments');
|
|
1464
|
+
|
|
1465
|
+
if (attachments) {
|
|
1466
|
+
self.apos.attachment.all(results, { annotate: true });
|
|
1447
1467
|
}
|
|
1468
|
+
},
|
|
1469
|
+
launder(b) {
|
|
1470
|
+
return self.apos.launder.boolean(b);
|
|
1448
1471
|
}
|
|
1449
1472
|
},
|
|
1450
1473
|
|
|
@@ -286,9 +286,21 @@ export default {
|
|
|
286
286
|
apos.bus.$off('content-changed', this.onContentChanged);
|
|
287
287
|
},
|
|
288
288
|
methods: {
|
|
289
|
-
onContentChanged(e) {
|
|
289
|
+
async onContentChanged(e) {
|
|
290
290
|
if (e.doc && (e.doc._id === this.context._id)) {
|
|
291
291
|
this.context = e.doc;
|
|
292
|
+
} else if (e.docIds && e.docIds.includes(this.context._id)) {
|
|
293
|
+
try {
|
|
294
|
+
this.context = await apos.http.get(`${this.moduleOptions.action}/${this.context._id}`, {
|
|
295
|
+
busy: true
|
|
296
|
+
});
|
|
297
|
+
} catch (error) {
|
|
298
|
+
// If not found it is likely that there was an archiving or restoring
|
|
299
|
+
// batch operation.
|
|
300
|
+
if (error.name !== 'notfound') {
|
|
301
|
+
console.error(error);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
292
304
|
}
|
|
293
305
|
},
|
|
294
306
|
menuHandler(action) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"addItem": "Add Item",
|
|
4
4
|
"addWidgetType": "Add {{ label }}",
|
|
5
5
|
"admin": "Admin",
|
|
6
|
+
"affirmativeLabel": "Yes, continue.",
|
|
6
7
|
"altText": "Alt Text",
|
|
7
8
|
"altTextHelp": "Image description used for accessibility",
|
|
8
9
|
"any": "Any",
|
|
@@ -17,6 +18,8 @@
|
|
|
17
18
|
"archiveTypeAffirmativeLabel": "Yes, archive {{ type }}",
|
|
18
19
|
"archiveTypeNote": "You are currently viewing the {{ type }} you want to archive. When it is archived you will be returned to the home page.",
|
|
19
20
|
"archived": "Archived",
|
|
21
|
+
"archivingBatchConfirmation": "Are you sure you want to archive {{ count }} {{ type }}?",
|
|
22
|
+
"archivingBatchConfirmationButton": "Yes, archive content.",
|
|
20
23
|
"archivingDraftChildCount": "{{ count }} of those descendants have never been published.",
|
|
21
24
|
"archivingPageHasChild": "That page has one descendant.",
|
|
22
25
|
"archivingPageHasChild_plural": "That page has {{ count }} descendants.",
|
|
@@ -121,6 +124,7 @@
|
|
|
121
124
|
"errorPageMessage": "An error has occurred",
|
|
122
125
|
"errorPageStatusCode": "500",
|
|
123
126
|
"errorPageTitle": "An error has occurred",
|
|
127
|
+
"errorBatchOperationNoti": "Batch operation {{ operation }} failed.",
|
|
124
128
|
"everythingElse": "Everything Else",
|
|
125
129
|
"exit": "Exit",
|
|
126
130
|
"fetchPublishedVersionFailed": "An error occurred fetching the published version of the document.",
|
|
@@ -173,6 +177,8 @@
|
|
|
173
177
|
"manageDocType": "Manage {{ type }}",
|
|
174
178
|
"manageDraftSubmissions": "Manage Draft Submissions",
|
|
175
179
|
"managePages": "Manage Pages",
|
|
180
|
+
"maxLabel": "Max:",
|
|
181
|
+
"maxUi": "Max: {{ number }}",
|
|
176
182
|
"mediaCreatedDate": "Uploaded: {{ createdDate }}",
|
|
177
183
|
"mediaDimensions": "Dimensions: {{ width }} 𝗑 {{ height }}",
|
|
178
184
|
"mediaFileSize": "File Size: {{ fileSize }}",
|
|
@@ -180,6 +186,8 @@
|
|
|
180
186
|
"mediaMB": "{{ size }}MB",
|
|
181
187
|
"mediaUploadViaDrop": "Drop ’em when you’re ready",
|
|
182
188
|
"mediaUploadViaExplorer": "Or click to open the file explorer",
|
|
189
|
+
"minLabel": "Min:",
|
|
190
|
+
"minUi": "Min: {{ number }}",
|
|
183
191
|
"modify": "Modify",
|
|
184
192
|
"modifyOrDelete": "Modify / Delete",
|
|
185
193
|
"moreOptions": "More Options",
|
|
@@ -204,11 +212,13 @@
|
|
|
204
212
|
"notFoundPageStatusCode": "404",
|
|
205
213
|
"notFoundPageTitle": "404 - Page not found",
|
|
206
214
|
"notInLocale": "The current page doesn’t exist in {{ label }}. Localize the version from {{ currentLocale }}?",
|
|
215
|
+
"notificationClearEventError": "There was an error clearing a registered notification event.",
|
|
207
216
|
"noTypeFound": "No {{ type }} Found",
|
|
208
217
|
"parentNotLocalized": "Localize the parent page first",
|
|
209
218
|
"notYetPublished": "This document hasn't been published yet.",
|
|
210
219
|
"nudgeDown": "Nudge Down",
|
|
211
220
|
"nudgeUp": "Nudge Up",
|
|
221
|
+
"numberAdded": "{{ count }} Added",
|
|
212
222
|
"office": "Office",
|
|
213
223
|
"openGlobal": "Open Global Site Settings",
|
|
214
224
|
"page": "Page",
|
|
@@ -244,6 +254,8 @@
|
|
|
244
254
|
"richTextUndo": "Undo",
|
|
245
255
|
"richTextStyleConfigWarning": "Misconfigured rich text style: label: {{ label }}, {{ tag }}",
|
|
246
256
|
"password": "Password",
|
|
257
|
+
"passwordErrorMin": "Minimum of {{ min }} characters",
|
|
258
|
+
"passwordErrorMax": "Maximum of {{ max }} characters",
|
|
247
259
|
"passwordResetRequest": "Your request to reset your password on {{ site }}",
|
|
248
260
|
"pasteWidget": "Paste {{ widget }}",
|
|
249
261
|
"pending": "Pending",
|
|
@@ -255,12 +267,12 @@
|
|
|
255
267
|
"provideButtonLabel": "Provide a Button Label",
|
|
256
268
|
"previousPage": "Previous Page",
|
|
257
269
|
"public": "Public",
|
|
258
|
-
"modernBuild": "
|
|
259
|
-
"ie11Build": "
|
|
270
|
+
"modernBuild": "Public-facing modern JavaScript and Sass",
|
|
271
|
+
"ie11Build": "Public-facing modern JavaScript and Sass (IE11 build)",
|
|
260
272
|
"publish": "Publish",
|
|
261
273
|
"publishBeforeUsingTooltip": "Publish this content before using it in a relationship",
|
|
262
274
|
"published": "Published",
|
|
263
|
-
"rawCssAndJs": "
|
|
275
|
+
"rawCssAndJs": "Raw CSS and JS",
|
|
264
276
|
"rawHtml": "Raw HTML",
|
|
265
277
|
"rawHtmlCode": "Raw HTML (Code)",
|
|
266
278
|
"rawHtmlCodeHelp": "Be careful when embedding third-party code, as it can break the website editing functionality. If a page becomes unusable, add \"?safe_mode=1\" to the URL to make it work temporarily without the problem code being rendered.",
|
|
@@ -279,6 +291,8 @@
|
|
|
279
291
|
"relatedDocsOnly": "Related documents only",
|
|
280
292
|
"relatedDocsDefinition": "Related documents are documents referenced by this document. This typically includes images, content defined by relationships, etc.",
|
|
281
293
|
"restore": "Restore",
|
|
294
|
+
"restoreBatchConfirmation": "Are you sure you want to restore {{ count }} {{ type }}?",
|
|
295
|
+
"restoreBatchConfirmationButton": "Yes, restore content.",
|
|
282
296
|
"resolveErrorsBeforeSaving": "Resolve errors before saving.",
|
|
283
297
|
"resolveErrorsFirst": "Resolve errors first.",
|
|
284
298
|
"restoreOnlyThisPage": "Restore only this page",
|
|
@@ -307,6 +321,12 @@
|
|
|
307
321
|
"select": "Select",
|
|
308
322
|
"selectedMenuItem": "✓ {{ label }}",
|
|
309
323
|
"selectAll": "Select All",
|
|
324
|
+
"selectBoxMessage": "{{ num }} {{ label }} selected.",
|
|
325
|
+
"selectBoxMessagePage": "{{ num }} {{ label }} on this page selected.",
|
|
326
|
+
"selectBoxMessageAllButton": "Select all {{ num }} {{ label }}.",
|
|
327
|
+
"selectBoxMessageButton": "Select {{ num }} {{ label }}.",
|
|
328
|
+
"selectBoxMessageSelected": "{{ num }} {{ label }} selected.",
|
|
329
|
+
"selectBoxMessageAllSelected": "All {{ num }} {{ label }} selected.",
|
|
310
330
|
"deselectAll": "Deselect All",
|
|
311
331
|
"selectContent": "Select Content",
|
|
312
332
|
"selectContentToLocalize": "What content do you want to localize?",
|
|
@@ -375,7 +395,6 @@
|
|
|
375
395
|
"videoUrlHelp": "Enter the URL for a media source you wish to embed (e.g., YouTube, Vimeo, or other hosted video URL).",
|
|
376
396
|
"view": "View",
|
|
377
397
|
"visibility": "Visibility",
|
|
378
|
-
"visibilityLabel": "Who can view this?",
|
|
379
398
|
"willMoveImageToArchive": "This will move the image to the archive.",
|
|
380
399
|
"yes": "Yes",
|
|
381
400
|
"yesLocalizeAndSwitchLocales": "Yes, localize this page and switch locales",
|
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
"notFoundPageStatusCode": "404",
|
|
205
205
|
"notFoundPageTitle": "404 - Página no encontrada",
|
|
206
206
|
"notInLocale": "La página actual no existe en {{ label }}. ¿Traducir la versión desde la configuración regional {{ currentLocale }}?",
|
|
207
|
-
"noTypeFound": "Ningún {{ type }}
|
|
207
|
+
"noTypeFound": "Ningún {{ type }} Encontrado",
|
|
208
208
|
"parentNotLocalized": "Primero traduzca la configuración regional de la página principal",
|
|
209
209
|
"notYetPublished": "Este documento aún no ha sido publicado.",
|
|
210
210
|
"nudgeDown": "Mover Hacia Arriba",
|
|
@@ -375,7 +375,6 @@
|
|
|
375
375
|
"videoUrlHelp": "Ingresa la dirección URL del video que quiere insertar (e.j., YouTube, Vimeo, o otra dirección URL de video).",
|
|
376
376
|
"view": "Mirar",
|
|
377
377
|
"visibility": "Visibilidad",
|
|
378
|
-
"visibilityLabel": "¿Quién puede mirar esto?",
|
|
379
378
|
"willMoveImageToArchive": "Esto moverá la imagen al archivo de documentos.",
|
|
380
379
|
"yes": "Sí",
|
|
381
380
|
"yesLocalizeAndSwitchLocales": "Sí, traducir esta página y cambiar de configuración regional",
|
|
@@ -372,7 +372,6 @@
|
|
|
372
372
|
"videoUrlHelp": "Insira o URL de uma fonte de mídia que deseja incorporar (por exemplo, YouTube, Vimeo ou outro URL de vídeo).",
|
|
373
373
|
"view": "Visualizar",
|
|
374
374
|
"visibility": "Visibilidade",
|
|
375
|
-
"visibilityLabel": "Quem pode ver isto?",
|
|
376
375
|
"willMoveImageToArchive": "Isso moverá a imagem para o arquivo.",
|
|
377
376
|
"yes": "Sim",
|
|
378
377
|
"yesLocalizeAndSwitchLocales": "Sim, localize esta página e mude de local",
|
|
@@ -253,12 +253,12 @@
|
|
|
253
253
|
"provideButtonLabel": "Poskytnite štítok s tlačidlom",
|
|
254
254
|
"previousPage": "Predchádzajúca strana",
|
|
255
255
|
"public": "Verejné",
|
|
256
|
-
"modernBuild": "
|
|
257
|
-
"ie11Build": "
|
|
256
|
+
"modernBuild": "Verejnosti orientovaný moderný JavaScript a Sass",
|
|
257
|
+
"ie11Build": "Verejný moderný JavaScript a Sass (zostava IE11)",
|
|
258
258
|
"publish": "Publikovať",
|
|
259
259
|
"publishBeforeUsingTooltip": "Pred použitím v kontexte zverejnite tento obsah",
|
|
260
260
|
"published": "Publikovaný",
|
|
261
|
-
"rawCssAndJs": "
|
|
261
|
+
"rawCssAndJs": "Zdrojový CSS a JS",
|
|
262
262
|
"rawHtml": "Zdrojový HTML",
|
|
263
263
|
"rawHtmlCode": "Zdrojový HTML (kód)",
|
|
264
264
|
"rawHtmlCodeHelp": "Pri vkladaní kódu tretej strany buďte opatrní, pretože môže narušiť funkciu úprav webových stránok. Ak sa stránka stane nepoužiteľnou, pridajte \"?safe_mode=1\" na adresu URL, aby dočasne fungovala bez toho, aby sa zobrazil problémový kód.",
|
|
@@ -373,7 +373,6 @@
|
|
|
373
373
|
"videoUrlHelp": "Zadajte webovú adresu zdroja média, ktorý chcete vložiť (napr. YouTube, Vimeo alebo inej adresy URL hosteného videa).",
|
|
374
374
|
"view": "Pozrieť",
|
|
375
375
|
"visibility": "Viditeľnosť",
|
|
376
|
-
"visibilityLabel": "Kto to môže vidieť?",
|
|
377
376
|
"willMoveImageToArchive": "Tým sa obrázok presunie do archívu.",
|
|
378
377
|
"yes": "Áno",
|
|
379
378
|
"yesLocalizeAndSwitchLocales": "Áno, preložte túto stránku a prepnite jazykovú mutáciu",
|
|
@@ -13,11 +13,27 @@ const ExpressSessionCookie = require('express-session/session/cookie');
|
|
|
13
13
|
|
|
14
14
|
const apostropheI18nDebugPlugin = {
|
|
15
15
|
type: 'postProcessor',
|
|
16
|
-
name: '
|
|
16
|
+
name: 'apostropheI18nDebugPlugin',
|
|
17
17
|
process(value, key, options, translator) {
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
18
|
+
// The key is passed as an array (theoretically to include multiple keys).
|
|
19
|
+
// We confirm that and grab the primary one for comparison.
|
|
20
|
+
const l10nKey = Array.isArray(key) ? key[0] : key;
|
|
21
|
+
|
|
22
|
+
if (value === l10nKey) {
|
|
23
|
+
if (l10nKey.match(/^\S+:/)) {
|
|
24
|
+
// The l10n key does not have a value assigned (or the key is
|
|
25
|
+
// actually the same as the phrase). The key seems to have a
|
|
26
|
+
// namespace, so might be from the Apostrophe UI.
|
|
27
|
+
return `❌ ${value}`;
|
|
28
|
+
} else {
|
|
29
|
+
// The l10n key does not have a value assigned (or the key is
|
|
30
|
+
// actually the same as the phrase). It is in the default namespace.
|
|
31
|
+
return `🕳 ${value}`;
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
// The phrase is fully localized.
|
|
35
|
+
return `🌍 ${value}`;
|
|
36
|
+
}
|
|
21
37
|
}
|
|
22
38
|
};
|
|
23
39
|
|
|
@@ -51,9 +67,14 @@ module.exports = {
|
|
|
51
67
|
throw self.apos.error('invalid', `Locale prefixes must not contain more than one forward slash ("/").\nUse hyphens as separators. Check locale "${key}".`);
|
|
52
68
|
}
|
|
53
69
|
}
|
|
70
|
+
const fallbackLng = [ self.defaultLocale ];
|
|
71
|
+
// In case the default locale also has inadequate admin UI phrases
|
|
72
|
+
if (fallbackLng[0] !== 'en') {
|
|
73
|
+
fallbackLng.push('en');
|
|
74
|
+
}
|
|
54
75
|
// Make sure we have our own instance to avoid conflicts with other apos objects
|
|
55
76
|
self.i18next = i18next.createInstance({
|
|
56
|
-
fallbackLng
|
|
77
|
+
fallbackLng,
|
|
57
78
|
// Required to prevent the debugger from complaining
|
|
58
79
|
languages: Object.keys(self.locales),
|
|
59
80
|
// Added later, but required here
|
|
@@ -68,7 +89,12 @@ module.exports = {
|
|
|
68
89
|
if (self.show) {
|
|
69
90
|
self.i18next.use(apostropheI18nDebugPlugin);
|
|
70
91
|
}
|
|
71
|
-
|
|
92
|
+
|
|
93
|
+
const i18nextOptions = self.show ? {
|
|
94
|
+
postProcess: 'apostropheI18nDebugPlugin'
|
|
95
|
+
} : {};
|
|
96
|
+
|
|
97
|
+
await self.i18next.init(i18nextOptions);
|
|
72
98
|
self.addInitialResources();
|
|
73
99
|
self.enableBrowserData();
|
|
74
100
|
},
|
|
@@ -459,6 +485,10 @@ module.exports = {
|
|
|
459
485
|
if (req.locale !== self.defaultLocale) {
|
|
460
486
|
i18n[self.defaultLocale] = self.getBrowserBundles(self.defaultLocale);
|
|
461
487
|
}
|
|
488
|
+
// In case the default locale also has inadequate admin UI phrases
|
|
489
|
+
if (!i18n.en) {
|
|
490
|
+
i18n.en = self.getBrowserBundles('en');
|
|
491
|
+
}
|
|
462
492
|
const result = {
|
|
463
493
|
i18n,
|
|
464
494
|
locale: req.locale,
|
|
@@ -45,10 +45,13 @@
|
|
|
45
45
|
<template #bodyHeader>
|
|
46
46
|
<AposDocsManagerToolbar
|
|
47
47
|
:selected-state="selectAllState"
|
|
48
|
-
:total-pages="totalPages"
|
|
49
|
-
:
|
|
48
|
+
:total-pages="totalPages"
|
|
49
|
+
:current-page="currentPage"
|
|
50
|
+
:filters="toolbarFilters"
|
|
51
|
+
:labels="moduleLabels"
|
|
50
52
|
:disable="relationshipErrors === 'min'"
|
|
51
|
-
:
|
|
53
|
+
:displayed-items="items.length"
|
|
54
|
+
:checked-count="checked.length"
|
|
52
55
|
@page-change="updatePage"
|
|
53
56
|
@select-click="selectClick"
|
|
54
57
|
@search="search"
|
|
@@ -4,15 +4,25 @@
|
|
|
4
4
|
{% set className = data.manager.options.className %}
|
|
5
5
|
{% endif %}
|
|
6
6
|
|
|
7
|
+
{% if data.options.dimensionAttrs %}
|
|
8
|
+
{% set dimensionAttrs = data.options.dimensionAttrs %}
|
|
9
|
+
{% elif data.manager.options.dimensionAttrs %}
|
|
10
|
+
{% set dimensionAttrs = data.manager.options.dimensionAttrs %}
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
7
13
|
{% set attachment = apos.image.first(data.widget._image) %}
|
|
8
14
|
|
|
9
15
|
{% if attachment %}
|
|
10
|
-
<img{% if className %} class="{{ className }}"{% endif %}
|
|
16
|
+
<img {% if className %} class="{{ className }}"{% endif %}
|
|
11
17
|
srcset="{{ apos.image.srcset(attachment) }}"
|
|
12
18
|
src="{{ apos.attachment.url(attachment, { size: data.options.size or 'full' }) }}"
|
|
13
19
|
alt="{{ attachment._alt or '' }}"
|
|
20
|
+
{% if dimensionAttrs %}
|
|
21
|
+
{% if attachment.width %} width="{{ attachment.width }}" {% endif %}
|
|
22
|
+
{% if attachment.height %} height="{{ attachment.height }}" {% endif %}
|
|
23
|
+
{% endif %}
|
|
14
24
|
{% if data.contextOptions and data.contextOptions.sizes %}
|
|
15
25
|
sizes="{{ data.contextOptions.sizes }}"
|
|
16
26
|
{% endif %}
|
|
17
27
|
/>
|
|
18
|
-
{% endif %}
|
|
28
|
+
{% endif %}
|