Apostrophe 2 v3.3.0 Release NotesRelease Date: 2021-08-30 // 25 days ago
- ➕ Addresses the page jump when using the in-context undo/redo feature. The page will immediately return users to their origin scroll position after the content refreshes.
- Resolves slug-related bug when switching between images in the archived view of the media manager. The slug field was not taking into account the double slug prefix case.
- 🛠 Fixes migration task crash when parking new page. Thanks to Miro Yovchev for this fix.
- 🛠 Fixes incorrect month name in
AposCellDate, which can be optionally used in manage views of pieces. Thanks to Miro Yovchev for this fix.
- 📚 This version achieves localization (l10n) through a rich set of internationalization (i18n) features. For more information, see the documentation.
- 👍 There is support for both static string localization and dynamic content localization.
- 🔧 The home page, other parked pages, and the global document are automatically replicated to all configured locales at startup. Parked properties are refreshed if needed. Other pages and pieces are replicated if and when an editor chooses to do so.
- An API route has been added for voluntary replication, i.e. when deciding a document should exist in a second locale, or desiring to overwrite the current draft contents in locale
Bwith the draft contents of locale
- 🚧 Locales can specify
hostnameoptions, which are automatically recognized by middleware that removes the prefix dynamically where appropriate and sets
req.locale. In 3.x this works more like the global site
prefixoption. This is a departure from 2.x which stored the prefix directly in the slug, creating maintenance issues.
- 🔍 Locales are stateless: they are never recorded in the session. This eliminates many avenues for bugs and bad SEO. However, this also means the developer must fully distinguish them from the beginning via either
hostname. A helpful error message is displayed if this is not the case.
- 🔧 Switching locales preserves the user's editing session even if on separate hostnames. To enable this, if any locales have hostnames, all configured locales must have hostnames and/or baseUrl must be set for those that don't.
- 🐎 An API route has been added to discover the locales in which a document exists. This provides basic information only for performance (it does not report
- 0️⃣ Editors can "localize" documents, copying draft content from one locale to another to create a corresponding document in a different locale. For convenience related documents, such as images and other pieces directly referenced by the document's structure, can be localized at the same time. Developers can opt out of this mechanism for a piece type entirely, check the box by default for that type, or leave it as an "opt-in" choice.
- 0️⃣ The
@apostrophecms/i18nmodule now uses
i18nextto implement static localization. All phrases in the Vue-based admin UI are passed through
i18nextis also available via
req.t()in routes and
__t()in templates. Apostrophe's own admin UI phrases are in the
apostrophenamespace for a clean separation. An array of locale codes, such as
en-au, can be specified using the
localesoption to the
@apostrophecms/i18nmodule. The first locale is the default, unless the
defaultLocaleoption is set. If no locales are set, the locale defaults to
i18next-http-middlewarelocale guesser is installed and will select an available locale if possible, otherwise it will fall back to the default.
- 💻 In the admin UI,
v-tooltiphas been extended as
v-apos-tooltip, which passes phrases through
- Developers can link to alternate locales by iterating over
data.localizationsin any page template. Each element always has
homePageUrlproperties. Each element also has an
availableproperty (if true, the current context document is available in that locale),
titleand a small number of other document properties are populated, and
_urlredirects to the context document in that locale. The current locale is marked with
- To facilitate adding interpolated values to phrases that are passed as a single value through many layers of code, the
this.$thelper provided in Vue also accepts an object argument with a
keyproperty. Additional properties may be used for interpolation.
i18nextlocalization JSON files can be added to the
i18nsubdirectory of any module, as long as its
i18noption is set. The
i18nobject may specify
nsto give an
i18nextnamespace, otherwise phrases are in the default namespace, used when no namespace is specified with a
i18nextcall. The default namespace is yours for use at project level. Multiple modules may contribute to the same namespace.
APOS_DEBUG_I18N=1is set in the environment, the
i18nextdebug flag is activated. For server-side translations, i.e.
__t(), debugging output will appear on the server console. For browser-side translations in the Vue admin UI, debugging output will appear in the browser console.
- 👉 If
APOS_SHOW_I18N=1is set in the environment, all phrases passed through
i18nextare visually marked, to make it easier to find those that didn't go through
i18next. This does not mean translations actually exist in the JSON files. For that, review the output of
- There is a locale switcher for editors.
- There is a backend route to accept a new locale on switch.
- 👯 A
req.clone(properties)method is now available. This creates a clone of the
reqobject, optionally passing in an object of properties to be set. The use of
req.cloneensures the new object supports
req.getand other methods of a true
reqobject. This technique is mainly used to obtain a new request object with the same privileges but a different mode or locale, i.e.
- Fallback wrappers are provided for the
__()localization helpers, which were never official or documented in 3.x but may be in use in projects ported from 2.x. These wrappers do not localize but do output the input they are given along with a developer warning. You should migrate them to use
- 💅 Bolsters the CSS that backs Apostrophe UI's typography to help prevent unintended style leaks at project-level code.
- ✂ Removes the 2.x series changelog entries. They can be found in the 2.0 branch in Github.