@materializecms/server 0.7.0 → 0.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/src/wordpress.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { newId } from '@materializecms/core/page';
2
2
  import { DomUtils, parseDocument } from 'htmlparser2';
3
+ import { t } from './t.js';
3
4
  export class WordPressError extends Error {
4
5
  }
5
6
  const parse = (html, xml = false) => parseDocument(html, xml ? { xmlMode: true } : { decodeEntities: true });
@@ -40,7 +41,7 @@ export async function readRest(base, fetcher, options = {}) {
40
41
  }
41
42
  }
42
43
  if (!api)
43
- throw new WordPressError('Non trovo l’API di WordPress a questo indirizzo: controlla che sia il sito giusto, oppure usa il file di esportazione.');
44
+ throw new WordPressError(t('Non trovo l’API di WordPress a questo indirizzo: controlla che sia il sito giusto, oppure usa il file di esportazione.'));
44
45
  const endpoint = api;
45
46
  const items = [];
46
47
  for (const kind of ['post', 'page']) {
@@ -56,9 +57,9 @@ export async function readRest(base, fetcher, options = {}) {
56
57
  if (res.status === 400 && page > 1)
57
58
  break;
58
59
  if (res.status === 401 || res.status === 403)
59
- throw new WordPressError('WordPress non dà accesso ai contenuti: controlla utente e password applicativa.');
60
+ throw new WordPressError(t('WordPress non dà accesso ai contenuti: controlla utente e password applicativa.'));
60
61
  if (res.status !== 200)
61
- throw new WordPressError(`WordPress ha risposto ${res.status} leggendo ${route}`);
62
+ throw new WordPressError(t('WordPress ha risposto {status} leggendo {route}', { status: res.status, route }));
62
63
  const list = JSON.parse(res.text);
63
64
  for (const p of list)
64
65
  items.push(fromRest(p, kind));
@@ -118,7 +119,7 @@ export function readWxr(xml) {
118
119
  };
119
120
  const channel = find(doc, 'channel');
120
121
  if (!channel || !find(channel, 'wp:wxr_version'))
121
- throw new WordPressError('Questo non è un file di esportazione di WordPress (Strumenti → Esporta).');
122
+ throw new WordPressError(t('Questo non è un file di esportazione di WordPress (Strumenti → Esporta).'));
122
123
  const child = (node, name) => (node.children ?? []).find((c) => c.name === name);
123
124
  const text = (node) => (node ? textOf(node).trim() : '');
124
125
  const rawItems = (channel.children ?? []).filter((c) => c.name === 'item');
@@ -499,7 +500,7 @@ export function htmlToPage(html, title, ctx) {
499
500
  const sections = [];
500
501
  let current = null;
501
502
  const section = () => {
502
- current = { id: newId(), type: 'frame', name: 'Sezione', layout: 'col', gap: 20, size: 'm', children: [] };
503
+ current = { id: newId(), type: 'frame', name: t('Sezione'), layout: 'col', gap: 20, size: 'm', children: [] };
503
504
  sections.push(current);
504
505
  return current;
505
506
  };
@@ -527,7 +528,7 @@ export function htmlToPage(html, title, ctx) {
527
528
  add({
528
529
  id: newId(),
529
530
  type: 'image',
530
- name: 'Immagine',
531
+ name: t('Immagine'),
531
532
  src: img.src,
532
533
  alt: p.alt || img.alt,
533
534
  ratio: img.width && img.height ? `${img.width}/${img.height}` : '16/9',
@@ -540,7 +541,7 @@ export function htmlToPage(html, title, ctx) {
540
541
  add({
541
542
  id: newId(),
542
543
  type: 'button',
543
- name: 'Pulsante',
544
+ name: t('Pulsante'),
544
545
  text: p.text,
545
546
  href: p.href,
546
547
  variant: 'primary',
@@ -568,12 +569,12 @@ export function htmlToPage(html, title, ctx) {
568
569
  ? p.runs.map((r) => ({ ...r, i: true }))
569
570
  : p.runs;
570
571
  add(text(runs, style, p.style === 'li'
571
- ? 'Punto elenco'
572
+ ? t('Punto elenco')
572
573
  : p.style.startsWith('h')
573
- ? 'Titolo'
574
+ ? t('Titolo')
574
575
  : p.style === 'quote'
575
- ? 'Citazione'
576
- : 'Testo'));
576
+ ? t('Citazione')
577
+ : t('Testo')));
577
578
  }
578
579
  return sections;
579
580
  }
package/src/wpimport.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { slugify } from '@materializecms/core';
2
+ import { t } from './t.js';
2
3
  import { htmlToPage, htmlToRichText, imageAltsIn, mainContent, originalOf, plain, } from './wordpress.js';
3
4
  /** Which sources fit a field of this kind. */
4
5
  export function sourcesFor(f) {
@@ -117,10 +118,10 @@ export async function runImport(site, plan, deps) {
117
118
  };
118
119
  const report = () => deps.onProgress({ ...progress });
119
120
  const targetOf = (item) => (item.kind === 'post' ? plan.posts : plan.pages);
120
- const defOf = (t) => deps.collections.find((c) => c.name === t.collection);
121
+ const defOf = (target) => deps.collections.find((c) => c.name === target.collection);
121
122
  const items = site.items.filter((i) => {
122
- const t = targetOf(i);
123
- return t && defOf(t);
123
+ const target = targetOf(i);
124
+ return target && defOf(target);
124
125
  });
125
126
  // 0. Items the API gave empty (some themes and page builders keep the page elsewhere): their
126
127
  // published page is read instead, between its header and its footer.
@@ -134,8 +135,8 @@ export async function runImport(site, plan, deps) {
134
135
  // 1. Images: each address once, the original size when WordPress has it.
135
136
  const wanted = new Map();
136
137
  for (const item of items) {
137
- const t = targetOf(item);
138
- const fields = Object.values(t.fields);
138
+ const target = targetOf(item);
139
+ const fields = Object.values(target.fields);
139
140
  if (fields.includes('content'))
140
141
  for (const [src, alt] of imageAltsIn(item.html)) {
141
142
  const url = new URL(src, site.url).href;
@@ -171,14 +172,14 @@ export async function runImport(site, plan, deps) {
171
172
  await Promise.all([worker(), worker(), worker()]);
172
173
  // 2. Where every item will live, so links between them point to the new pages.
173
174
  const plans = items.map((item) => {
174
- const t = targetOf(item);
175
- const def = defOf(t);
175
+ const target = targetOf(item);
176
+ const def = defOf(target);
176
177
  const slug = slugify(decodeURIComponent(item.slug)) || slugify(item.title) || item.sourceId;
177
178
  const sample = {};
178
- for (const [name, source] of Object.entries(t.fields))
179
+ for (const [name, source] of Object.entries(target.fields))
179
180
  if (source === 'slug')
180
181
  sample[name] = slug;
181
- return { item, t, def, slug, url: deps.urlOf(def, sample) };
182
+ return { item, target, def, slug, url: deps.urlOf(def, sample) };
182
183
  });
183
184
  const moved = new Map();
184
185
  for (const p of plans) {
@@ -224,7 +225,7 @@ export async function runImport(site, plan, deps) {
224
225
  // Canvas pages filled from the content: the ones the AI may lay out again.
225
226
  const canvas = [];
226
227
  for (const entry of plans) {
227
- const { item, t, def } = entry;
228
+ const { item, target, def } = entry;
228
229
  let { slug, url } = entry;
229
230
  try {
230
231
  const mine = taken.get(def.name) ?? new Set();
@@ -236,23 +237,26 @@ export async function runImport(site, plan, deps) {
236
237
  const before = slug;
237
238
  slug = `${slug}-${n}`;
238
239
  const sample = {};
239
- for (const [name, source] of Object.entries(t.fields))
240
+ for (const [name, source] of Object.entries(target.fields))
240
241
  if (source === 'slug')
241
242
  sample[name] = slug;
242
243
  url = deps.urlOf(def, sample);
243
244
  progress.problems.push({
244
245
  title: item.title,
245
- reason: `indirizzo già usato da un’altra pagina importata: ora è ${url ?? slug}, era ${before}`,
246
+ reason: t('indirizzo già usato da un’altra pagina importata: ora è {now}, era {before}', {
247
+ now: url ?? slug,
248
+ before,
249
+ }),
246
250
  });
247
251
  }
248
252
  else if (await deps.exists(def.name, slug)) {
249
253
  // Already there from before (a second import): left as it is.
250
- progress.skipped.push({ title: item.title, reason: 'c’è già un contenuto con lo stesso indirizzo' });
254
+ progress.skipped.push({ title: item.title, reason: t('c’è già un contenuto con lo stesso indirizzo') });
251
255
  continue;
252
256
  }
253
257
  mine.add(slug);
254
258
  const data = {};
255
- for (const [name, source] of Object.entries(t.fields)) {
259
+ for (const [name, source] of Object.entries(target.fields)) {
256
260
  const f = def.fields[name];
257
261
  if (!f)
258
262
  continue;
@@ -260,7 +264,7 @@ export async function runImport(site, plan, deps) {
260
264
  if (value !== undefined)
261
265
  data[name] = value;
262
266
  }
263
- for (const [name, source] of Object.entries(t.fields))
267
+ for (const [name, source] of Object.entries(target.fields))
264
268
  if (source === 'slug')
265
269
  data[name] = slug;
266
270
  const doc = await deps.create(def, data);
@@ -271,10 +275,10 @@ export async function runImport(site, plan, deps) {
271
275
  published = true;
272
276
  }
273
277
  catch {
274
- progress.problems.push({ title: doc.title, reason: 'importato come bozza: ha campi da completare' });
278
+ progress.problems.push({ title: doc.title, reason: t('importato come bozza: ha campi da completare') });
275
279
  }
276
280
  progress.created.push({ id: doc.id, collection: def.name, title: doc.title, published });
277
- if (Object.entries(t.fields).some(([name, source]) => source === 'content' && def.fields[name]?.kind === 'page'))
281
+ if (Object.entries(target.fields).some(([name, source]) => source === 'content' && def.fields[name]?.kind === 'page'))
278
282
  canvas.push({ id: doc.id, collection: def.name, title: doc.title });
279
283
  const from = pathOf(item.link, site.url);
280
284
  if (published && from && url && from !== url)
@@ -301,14 +305,14 @@ export async function runImport(site, plan, deps) {
301
305
  try {
302
306
  const why = await deps.relayout(doc);
303
307
  if (why)
304
- progress.problems.push({ title: doc.title, reason: `impaginazione semplice lasciata: ${why}` });
308
+ progress.problems.push({ title: doc.title, reason: t('impaginazione semplice lasciata: {why}', { why }) });
305
309
  else
306
310
  progress.relaid++;
307
311
  }
308
312
  catch (error) {
309
313
  progress.problems.push({
310
314
  title: doc.title,
311
- reason: `l’AI non ha rifatto l’impaginazione: ${error.message}`,
315
+ reason: t('l’AI non ha rifatto l’impaginazione: {detail}', { detail: error.message }),
312
316
  });
313
317
  }
314
318
  progress.done++;
@@ -423,16 +427,16 @@ export function relayoutProblem(before, after) {
423
427
  const was = wordsOf(before);
424
428
  const now = wordsOf(after);
425
429
  if (!now.size)
426
- return 'la pagina sarebbe rimasta vuota';
430
+ return t('la pagina sarebbe rimasta vuota');
427
431
  const lost = [...was].filter((w) => !now.has(w)).length;
428
432
  const added = [...now].filter((w) => !was.has(w)).length;
429
433
  if (lost > Math.max(3, was.size * 0.1))
430
- return 'l’AI avrebbe tolto parte del testo';
434
+ return t('l’AI avrebbe tolto parte del testo');
431
435
  if (added > Math.max(8, was.size * 0.15))
432
- return 'l’AI avrebbe aggiunto testi che non c’erano';
436
+ return t('l’AI avrebbe aggiunto testi che non c’erano');
433
437
  const pictures = imagesOf(after);
434
438
  if ([...imagesOf(before)].some((src) => !pictures.has(src)))
435
- return 'l’AI avrebbe tolto delle immagini';
439
+ return t('l’AI avrebbe tolto delle immagini');
436
440
  return null;
437
441
  }
438
442
  /** Descriptions the page had for its images, put back where the new layout left them empty. */