-
Notifications
You must be signed in to change notification settings - Fork 36
Overhaul web extension system docs #1187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JammingBen
wants to merge
2
commits into
main
Choose a base branch
from
docs/extension-system-overhaul
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,4 @@ | ||
| { | ||
| "label": "Development", | ||
| "position": 2, | ||
| "link": { | ||
| "type": "generated-index", | ||
| "description": "\uD83D\uDC69\u200D\uD83D\uDCBB Development", | ||
| "slug": "dev/web/development/" | ||
| } | ||
| "position": 2 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| title: 'Development' | ||
| --- | ||
|
|
||
| This section covers the development workflow and conventions for contributing to OpenCloud Web. | ||
|
|
||
| - [Tooling](./tooling) describes the local development setup and the tools used to build OpenCloud Web. | ||
| - [Repository structure and published packages](./repo-structure) explains the most important parts of the Web repository. | ||
| - [Conventions](./conventions) summarizes the coding and contribution conventions used by the project. |
4 changes: 4 additions & 0 deletions
4
docs/dev/web/extension-system/advanced-topics/_category_.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "label": "Advanced topics", | ||
| "position": 3 | ||
| } |
57 changes: 57 additions & 0 deletions
57
docs/dev/web/extension-system/advanced-topics/configuration.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| --- | ||
| title: 'Configuration' | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| This page describes how to add configuration options to your app. Administrators can then change the behaviour of your | ||
| app. | ||
|
|
||
| ## Manifest and defaults | ||
|
|
||
| Put static metadata of your app into `src/manifest.json`. It ends up in the `manifest.json` of your build, together with | ||
| the `name`, `version`, `description`, `license` and `author` fields of your `package.json`, and the entry point of your | ||
| app. | ||
|
|
||
| Default values for the app config belong under the `config` key: | ||
|
|
||
| ```json title="src/manifest.json" | ||
| { | ||
| "config": { | ||
| "maxFileSize": 10485760, | ||
| "showPreview": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Overriding values | ||
|
|
||
| There are two ways to override the defaults: | ||
|
|
||
| - During development, put your values into `src/config.json`. The file is merged on top of the `config` key of | ||
| `src/manifest.json`. Don't commit values that only apply to your machine. | ||
| - In a real deployment, administrators override them via the `apps.yaml` file, see the | ||
| [web applications admin docs](../../../../admin/configuration/web-applications). | ||
|
|
||
| ```json title="src/config.json" | ||
| { | ||
| "showPreview": false | ||
| } | ||
| ``` | ||
|
|
||
| ## Reading values in your app | ||
|
|
||
| The merged config is passed to the `setup` function of your app definition as `applicationConfig`: | ||
|
|
||
| ```typescript title="src/index.ts" | ||
| import { defineWebApplication } from '@opencloud-eu/web-pkg'; | ||
|
|
||
| export default defineWebApplication({ | ||
| setup({ applicationConfig }) { | ||
| const showPreview = applicationConfig?.showPreview ?? true; | ||
|
|
||
| // ... | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| Always provide a fallback value. The config can be empty, and an administrator can set any value. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| title: 'Advanced topics' | ||
| --- | ||
|
|
||
| This section covers additional concepts for developing and maintaining OpenCloud Web apps. | ||
|
|
||
| - [Configuration](./configuration) explains how to define defaults and expose configuration options to administrators. | ||
| - [Styling](./styling) describes how to use the OpenCloud design system, color roles, and Tailwind CSS. | ||
| - [Translations](./translations) explains how to make an app available in multiple languages. | ||
| - [Testing](./testing) introduces the available test setup and helpers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| --- | ||
| title: 'Styling' | ||
| sidebar_position: 2 | ||
| --- | ||
|
|
||
| This page describes how to style your app so that it fits into OpenCloud Web. | ||
|
|
||
| ## Design system components | ||
|
|
||
| The `@opencloud-eu/design-system` package contains the components that OpenCloud Web is built with, for example buttons, | ||
| inputs and modals. Use them where possible. Your app then follows the platform look and inherits accessibility and | ||
| theming for free. See the [design system documentation](../../design-system) for the list of components. | ||
|
|
||
| ## Color roles | ||
|
|
||
| OpenCloud Web exposes its colors as CSS variables with the `--oc-role-` prefix, for example `--oc-role-surface` or | ||
| `--oc-role-on-surface`. Always use these variables instead of fixed color values. They change with the active theme and | ||
| with the color scheme, so your app stays readable in light and dark mode. | ||
|
|
||
| ```css | ||
| .my-panel { | ||
| background-color: var(--oc-role-surface-container); | ||
| color: var(--oc-role-on-surface); | ||
| } | ||
| ``` | ||
|
|
||
| See [the defaults](https://github.com/opencloud-eu/web/blob/main/packages/design-system/src/styles/defaults.css) for a | ||
| complete list of color roles. | ||
|
|
||
| ## Tailwind CSS | ||
|
|
||
| The `@opencloud-eu/extension-sdk` package ships a preconfigured [Tailwind CSS](https://tailwindcss.com/) setup. Import | ||
| its stylesheet in your entrypoint (typically `src/index.ts`) to use it: | ||
|
|
||
| ```typescript title="src/index.ts" | ||
| import '@opencloud-eu/extension-sdk/tailwind.css'; | ||
| ``` | ||
|
|
||
| Tailwind classes need the `ext:` prefix in apps. The prefix avoids style conflicts with the OpenCloud Web runtime. | ||
|
|
||
| ```html | ||
| <main class="ext:p-4 ext:flex ext:gap-2">...</main> | ||
| ``` | ||
|
|
||
| The setup maps the color roles to Tailwind color utilities, so `--oc-role-surface` is available as `bg-role-surface`, | ||
| `text-role-on-surface` and so on: | ||
|
|
||
| ```html | ||
| <div class="ext:bg-role-surface-container ext:text-role-on-surface">...</div> | ||
| ``` | ||
|
|
||
| It also sets the OpenCloud font family, a spacing unit of `4px`, the breakpoints `xs`, `sm`, `md`, `lg` and `xl`, and a | ||
| `dark` variant. The `dark` variant follows the color scheme of OpenCloud Web, not the browser setting: | ||
|
|
||
| ```html | ||
| <div class="ext:bg-white ext:dark:bg-black">...</div> | ||
| ``` | ||
|
|
||
| In most cases you do not need the `dark` variant, because the color roles already handle both color schemes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| --- | ||
| title: 'Testing' | ||
| sidebar_position: 4 | ||
| --- | ||
|
|
||
| This page describes how to test your app. | ||
|
|
||
| ## Unit tests | ||
|
|
||
| The [web-app-skeleton repository](https://github.com/opencloud-eu/web-app-skeleton) comes with a | ||
| [vitest](https://vitest.dev/) setup. Run the unit tests with: | ||
|
|
||
| ```bash | ||
| pnpm test:unit | ||
| ``` | ||
|
|
||
| ## Test helpers | ||
|
|
||
| The `@opencloud-eu/web-test-helpers` package provides utilities for mounting components with a mocked OpenCloud Web | ||
| context. Without them, every component that uses a composable of `web-pkg` fails to mount. | ||
|
|
||
| ```typescript title="tests/unit/App.spec.ts" | ||
| import { defaultPlugins, mount } from '@opencloud-eu/web-test-helpers'; | ||
| import App from '../../src/App.vue'; | ||
|
|
||
| describe('App', () => { | ||
| it('renders the title', () => { | ||
| const wrapper = mount(App, { global: { plugins: [...defaultPlugins()] } }); | ||
| expect(wrapper.text()).toContain('My app'); | ||
| }); | ||
| }); | ||
| ``` | ||
|
|
||
| For details, please refer to the package's | ||
| [README.md](https://github.com/opencloud-eu/web/blob/main/packages/web-test-helpers/README.md). | ||
|
|
||
| ## End to end tests | ||
|
|
||
| For end to end tests with [Playwright](https://playwright.dev/), the | ||
| [web](https://github.com/opencloud-eu/web) and [web-extensions](https://github.com/opencloud-eu/web-extensions) | ||
| repositories contain working examples. |
138 changes: 138 additions & 0 deletions
138
docs/dev/web/extension-system/advanced-topics/translations.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| --- | ||
| title: 'Translations' | ||
| sidebar_position: 3 | ||
| --- | ||
|
|
||
| OpenCloud Web uses [gettext](https://www.gnu.org/software/gettext/) for translations, via the | ||
| [vue3-gettext](https://jshmrtn.github.io/vue3-gettext/) library. Your app brings its own translations and hands them to | ||
| the Web runtime. The language that the user picked in OpenCloud is then also used for your app. | ||
|
|
||
| Translations are optional. An app without them simply shows its original strings. | ||
|
|
||
| ## Marking strings | ||
|
|
||
| In a script or a composable, get `$gettext` from `useGettext`: | ||
|
|
||
| ```typescript | ||
| import { useGettext } from 'vue3-gettext'; | ||
|
|
||
| const { $gettext } = useGettext(); | ||
|
|
||
| const title = $gettext('Your application name'); | ||
| ``` | ||
|
|
||
| In a template, `$gettext` is globally available: | ||
|
|
||
| ```html | ||
| <template> | ||
| <p>{{ $gettext('No files here') }}</p> | ||
| </template> | ||
| ``` | ||
|
|
||
| Pass variables as an object. Use the `%{name}` syntax in the string, never string concatenation, because the word order | ||
| changes between languages: | ||
|
|
||
| ```typescript | ||
| $gettext('Open «%{resource}»', { resource: resource.name }); | ||
| ``` | ||
|
|
||
| For plurals, use `$ngettext` with the singular form, the plural form, the count, and the variables: | ||
|
|
||
| ```typescript | ||
| const { $ngettext } = useGettext(); | ||
|
|
||
| $ngettext( | ||
| 'Delete the selected resource?', | ||
| 'Delete %{amount} selected resources?', | ||
| resources.length, | ||
| { amount: resources.length.toString() } | ||
| ); | ||
| ``` | ||
|
|
||
| :::warning | ||
| The extraction tool reads your source code, not your runtime values. Always pass a plain string literal to `$gettext`. | ||
| A variable or a template literal cannot be extracted. | ||
| ::: | ||
|
|
||
| ## Setting up the workflow | ||
|
|
||
| Add [vue3-gettext](https://jshmrtn.github.io/vue3-gettext/) as a dev-dependency. It ships the `vue-gettext-extract` and | ||
| `vue-gettext-compile` commands. | ||
|
|
||
| Create a `gettext.config.cjs` in the root of your app. It defines which files are scanned and which languages you | ||
| support: | ||
|
|
||
| ```javascript title="gettext.config.cjs" | ||
| module.exports = { | ||
| input: { | ||
| path: './src', | ||
| include: ['**/*.js', '**/*.ts', '**/*.vue'] | ||
| }, | ||
| output: { | ||
| locales: ['de', 'es', 'fr', 'it'], | ||
| path: './l10n/locale', | ||
| potPath: '../template.pot', | ||
| jsonPath: '../translations.json', | ||
| flat: false, | ||
| linguas: false | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| Add two scripts to your `package.json`: | ||
|
|
||
| ```json title="package.json" | ||
| { | ||
| "scripts": { | ||
| "l10n:extract": "vue-gettext-extract", | ||
| "l10n:compile": "vue-gettext-compile" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| `l10n:extract` collects all marked strings into `l10n/template.pot` and creates one `.po` file per language under | ||
| `l10n/locale`. Run it whenever you add or change a string. | ||
|
|
||
| `l10n:compile` turns the `.po` files into a single `l10n/translations.json`. Run it after the translated `.po` files | ||
| come back. Commit `translations.json`, because the build imports it. | ||
|
|
||
| How the `.po` files get translated is up to you. The OpenCloud repositories use | ||
| [Transifex](https://www.transifex.com/), but any gettext based service or a manual workflow works as well. | ||
|
|
||
| ## Registering translations | ||
|
|
||
| Import `translations.json` and return it from your app definition. The Web runtime merges it into the global | ||
| translations when your app is loaded. | ||
|
|
||
| ```typescript title="src/index.ts" | ||
| import { defineWebApplication } from '@opencloud-eu/web-pkg'; | ||
| import { useGettext } from 'vue3-gettext'; | ||
| import translations from '../l10n/translations.json'; | ||
|
|
||
| export default defineWebApplication({ | ||
| setup() { | ||
| const { $gettext } = useGettext(); | ||
|
|
||
| return { | ||
| appInfo: { | ||
| name: $gettext('Your application name'), | ||
| id: 'your-app' | ||
| }, | ||
| translations | ||
| }; | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| The file is a map of language key to message map: | ||
|
|
||
| ```json title="l10n/translations.json" | ||
| { | ||
| "de": { | ||
| "No files here": "Keine Dateien hier" | ||
| }, | ||
| "fr": { | ||
| "No files here": "Aucun fichier ici" | ||
| } | ||
| } | ||
| ``` | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.