Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Whats new in Volto for developers

Whats new in Volto for developers

#Ploneconf2021 #Volto presentation about the new features added in Volto in the last year since our previous Ploneconf

David Ichim

October 28, 2021
Tweet

Other Decks in Programming

Transcript

  1. Plus new tooling and tool releases: plone i18n - 4

    releases plone generator - 4 releases
  2. New Volto config Dubbed as Volto's Configuration Registry Added in

    Volto 12 as optional, made mandatory in Volto 14 Introduced to fix “circular import dependency" problems HMR (Hot Module Reloader) fixed https://bit.ly/volto-config
  3. New config code example Old imports: import { settings }

    from '~/config' console.log(settings.apiPath) settings.isMultilingual = true New imports: import config from '@plone/volto/registry' console.log(config.settings.apiPath) config.settings.isMultilingual = true
  4. New i18n infrastructure i18n infrastructure is now a separate package

    Same package is used for generation of add-ons i18n Upgrade is easy and well documented in the upgrade guide https://bit.ly/volto-i18n
  5. New i18n infrastructure code example In project package.json "scripts": {

    "i18n": "rm -rf build/messages && NODE_ENV=production i18n" }, In add-on package.json: "scripts":{ "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon", } "dependencies": { "@plone/scripts": "*" }
  6. Forms as schema Forms should be constructed from schemas instead

    of by hand InlineForm allows us to create forms for blocks from schema Blocks can have variations based on the same schema Since schema is guaranteed it means that we can also extend it https://bit.ly/volto-forms-as-schema
  7. Problems solved by having forms as schema We no longer

    need to manually create and copy fields Reusability, focus on expressing interactions as widgets 10x less spent time by developers Opens the door to extensibility
  8. Object List Widget Think of it as an equivalent to

    DataGridField Used in core by the Search Block facets Useful for the creation of repeatable objects You can drag and drop these fields as you wish
  9. Object List Widget code example ... facets: { title: intl.formatMessage(messages.facets),

    widget: 'object_list', schema: FacetSchema({ intl }), schemaExtender: enhanceSchema, }, ...
  10. Object Browser widget Added in Volto 4 as part of

    a block, you can now also use it as a widget This widget now allows the addition of external content Pasting an internal URL will convert it to a tokenized value
  11. Object Browser widget code example { title: 'Item', fieldsets: [

    { id: 'default', title: 'Default', fields: ['href'], }, ], properties: { href: { title: 'title', widget: 'object_browser', mode: 'link', allowExternals: true, selectedItemAttrs: ['Title', 'Description'], }, }
  12. URL Widget Used on text inputs, it knows to validate

    their value as an url Can be used on both internal and external links url: { title: 'Remote url', widget: 'url', },
  13. Vocabulary Terms Widget Widget for plone.schema.JSONField Acts as a source

    for a SimpleVocabulary or Choice field Check out https://github.com/plone/volt o/pull/2532 Play with it here https://bit.ly/volto-storybook
  14. Pluggables The Pluggables framework gives you insertion points to push

    components to other components Similar to React's <Portal> component See Volto Pluggables talk held by Tiberiu Ichim for more details https://bit.ly/volto-pluggables
  15. Storybook Storybook provides a sandbox to build and test visual

    components in isolation Curently only setup to be used by Volto core Help with work to have storybook setup with addons See Storybook talk held by Victor for more details https://bit.ly/volto-storybook
  16. Critical CSS Inline's critical css for improved performance Run critical-cli

    to output critical.css Critical.css is inlined in header while regular css is moved to the bottom of the body https://bit.ly/volto-critical-css
  17. Lazy Loading utils Introduced injectLazyLibs HOC wrapper to inject lazy-loaded

    libraries as props to your components Component is only rendered once all the libraries are loaded https://bit.ly/volto-lazy-loading import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; function MyComponent({toastify}) { useEffect(() => {toastify.toast.success('Hello')}}; } export default injectLazyLibs(['toastify'])(MyComponent);
  18. Express.js middleware Volto uses Express for SSR and static resource

    serving You can now write custom middleware
  19. Express middleware code import config from '@plone/volto/registry'; const settings =

    { ...config.settings }; if (__SERVER__) { const express = require('express'); const middleware = express.Router(); middleware.all('/test-middleware', function (req, res, next) { res.send('Hello world'); }); middleware.id = 'test-middleware' settings.expressMiddleware = [ ...settings.expressMiddleware, middleware, ]; }
  20. See Volto middleware virtual host for a real world example

    https://github.com/eea/volto-middleware-vh ~ your-theme/index.js function applyConfig(config) { ... config.settings.virtualHostedPaths = ['**/RSS'] ... }
  21. API expanders Allow the expansion of different api endpoints from

    Volto with calls from your custom endpoints Useful when you want to have the endpoint result when retrieving the content Avoids an extra xhr call after retriving the content Avoid adding too many expanders if they are not critical to the initial page https://bit.ly/plone-restapi
  22. API Expanders code config.settings.apiExpanders = [ { match: '', GET_CONTENT:

    ['rest.endpoint'], }, ]; // request call will be http://localhost:3000?expand=rest.endpoint // when calling getContents
  23. AsyncPropExtenders Enable SSR of content that depends on additional async

    props coming from backend calls Can also be used to exclude certain calls from being requested
  24. AsyncPropExtenders code example Breadcrumbs exclusion from the root path config.settings.asyncPropsExtenders

    = [ ...config.settings.asyncPropsExtenders, { path: '/', extend: (dispatchActions) => dispatchActions.filter(asyncAction=> asyncAction.key !== 'breadcrumb') } ]
  25. AsyncPropExtenders code example 2 Editable footer action called for the

    server side rendering path: '/', extend: (dispatchActions) => { if ( !dispatchActions.filter( (asyncAction) => asyncAction.key === 'editable-footer', ).length ) { dispatchActions.push({ key: 'editable-footer', promise: ({ location, store: { dispatch } }) => __SERVER__ && dispatch(getEditableFooterColumns()), }); } return dispatchActions; },
  26. External routes Useful when another application is published under the

    same top domain as Volto Volto fetching the content for that path will break You can disable that path in config.settings.externalRoutes config.settings.externalRoutes = [ { match: "/news" }, { match: "/events" }, ];
  27. External routes code examples You can also pass a regex

    path which can match negative expressions const notInIMS = /^(?!.*(\/ims|\/static|\/controlpanel|\/cypress)).*$/; config.settings.externalRoutes = [ { match: { path: notInIMS, exact: false, strict: false, }, }, ];
  28. Seamless mode Introduced in Volto 13, enhanced in Volto 14

    Tried to unify both frontend and backend servers under the same path https://github.com/plone/volto/pull/2722 Introduces a new ++api++ traversal You can now pass environment variables at runtime instead of build time Checkout documentation at https://bit.ly/volto-seamless-mode
  29. Seamless mode code examples Before Volto 14, you'd do: RAZZLE_API_PATH=https://plone.org

    yarn build && yarn start:prod From Volto 14 onwards, you can now do: yarn build && RAZZLE_API_PATH=https://plone.org yarn start:prod
  30. Context navigation component Volto provides a navigation portlet component It's

    props are similar to classic Plone navigation portlet Up to the user to implement it in whatever view is necessary Check out documentation at https://bit.ly/volto-context-navigation
  31. Work in progress Slots Async blocks SSR Image proxy New

    auth model using backend as the reference Replace Draft.js with Slate editor Defaults in blocks form Remove customizations warnings
  32. Image proxy Image scale generation done by a middleware instead

    of plone.scale See progress at https://github.com/plone/volto/pull/2205
  33. Auth from backend Already started by Victor, perhaps done by

    Volto 14 Work done in part by the new seamless mode
  34. Replace Draft.js with Volto Slate What is missing is a

    migration tool from Draft.js to Slate, however...
  35. Future work Defaults in all widgets Enable blocks enhancers in

    all blocks Storybook in addons Use newest react-intl Folder contents component refactoring Form editing text enhancements A “Group block” included with Volto, to allow its reuse in accordion block, columns block, tabs block, etc. Quanta toolbar
  36. Thank you Volto early adopter comunity! Eaudeweb: Tiberiu Ichim Alin

    Voinea Razvan Miu Alexandru Medesan Krisztina Elekes Nilesh Gulia Daniela Mormocea Kitconcept: Víctor Fernández de Alba Timo Stollenwerk Alok Kumar Jakob Kahl Thomas Kindermann Rohit Singh
  37. Thank you Volto early adopter comunity! RedTurtle: Giulia Ghisini *Nicola

    Zambello Andrea Cecchi *Mauro Amico Rohberg: Katja Süss
  38. Thank you Volto early adopter comunity! CodeSyntax: Ion Lizarazu Mikel

    Larreategi Individual contribuitors: Johannes Raggam - Syslab Ross Patterson - rpatterson Érico Andrei - Pendact Fred van Dijk - Zest Software Carsten Senger 1bsilver damiDev8 Alexander Bückig - Werkbank GmbH