- [Server helpers (only for plugins)](#server-helpers-only-for-plugins)
- [Settings](#settings)
- [Storage](#storage)
+ - [Update video constants](#update-video-constants)
+ - [Client helpers (themes & plugins)](#client-helpers-themes--plugins)
+ - [Plugin static route](#plugin-static-route)
+ - [Translate](#translate)
+ - [Get public settings](#get-public-settings)
- [Publishing](#publishing)
- [Write a plugin/theme](#write-a-plugintheme)
- [Clone the quickstart repository](#clone-the-quickstart-repository)
- [Update README](#update-readme)
- [Update package.json](#update-packagejson)
- [Write code](#write-code)
+ - [Add translations](#add-translations)
- [Test your plugin/theme](#test-your-plugintheme)
- [Publish](#publish)
+- [Plugin & Theme hooks/helpers API](#plugin--theme-hookshelpers-api)
- [Tips](#tips)
- [Compatibility with PeerTube](#compatibility-with-peertube)
- [Spam/moderation plugin](#spammoderation-plugin)
+ - [Other plugin examples](#other-plugin-examples)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Concepts
-Themes are exactly the same than plugins, except that:
+Themes are exactly the same as plugins, except that:
* Their name starts with `peertube-theme-` instead of `peertube-plugin-`
* They cannot declare server code (so they cannot register server hooks or settings)
* CSS files are loaded by client only if the theme is chosen by the administrator or the user
For example to replace words in video comments, or change the videos list behaviour
* `action`: used to do something after a certain trigger. For example to send a hook every time a video is published
* `static`: same than `action` but PeerTube waits their execution
-
-Example:
-
-```js
-// This register function is called by PeerTube, and **must** return a promise
-async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
- registerHook({
- target: 'action:application.listening',
- handler: () => displayHelloWorld()
- })
-}
-```
On server side, these hooks are registered by the `library` file defined in `package.json`.
}
```
+And `main.js` defines a `register` function:
+
+Example:
+
+```js
+async function register ({
+ registerHook,
+ registerSetting,
+ settingsManager,
+ storageManager,
+ videoCategoryManager,
+ videoLicenceManager,
+ videoLanguageManager
+}) {
+ registerHook({
+ target: 'action:application.listening',
+ handler: () => displayHelloWorld()
+ })
+}
+```
+
On client side, these hooks are registered by the `clientScripts` files defined in `package.json`.
All client scripts have scopes so PeerTube client only loads scripts it needs:
}
```
+And these scripts also define a `register` function:
+
+```js
+function register ({ registerHook, peertubeHelpers }) {
+ registerHook({
+ target: 'action:application.init',
+ handler: () => onApplicationInit(peertubeHelpers)
+ })
+}
+```
+
### Static files
Plugins can declare static directories that PeerTube will serve (images for example)
### CSS
Plugins can declare CSS files that PeerTube will automatically inject in the client.
+If you need to override existing style, you can use the `#custom-css` selector:
+
+```
+body#custom-css {
+ color: red;
+}
+
+#custom-css .header {
+ background-color: red;
+}
+```
### Server helpers (only for plugins)
await storageManager.storeData('mykey', { subkey: 'value' })
```
+#### Update video constants
+
+You can add/delete video categories, licences or languages using the appropriate managers:
+
+```js
+videoLanguageManager.addLanguage('al_bhed', 'Al Bhed')
+videoLanguageManager.deleteLanguage('fr')
+
+videoCategoryManager.addCategory(42, 'Best category')
+videoCategoryManager.deleteCategory(1) // Music
+
+videoLicenceManager.addLicence(42, 'Best licence')
+videoLicenceManager.deleteLicence(7) // Public domain
+```
+
+### Client helpers (themes & plugins)
+
+### Plugin static route
+
+To get your plugin static route:
+
+```js
+const baseStaticUrl = peertubeHelpers.getBaseStaticRoute()
+const imageUrl = baseStaticUrl + '/images/chocobo.png'
+```
+
+#### Translate
+
+You can translate some strings of your plugin (PeerTube will use your `translations` object of your `package.json` file):
+
+```js
+peertubeHelpers.translate('User name')
+ .then(translation => console.log('Translated User name by ' + translation))
+```
+
+#### Get public settings
+
+To get your public plugin settings:
+
+```js
+peertubeHelpers.getSettings()
+ .then(s => {
+ if (!s || !s['site-id'] || !s['url']) {
+ console.error('Matomo settings are not set.')
+ return
+ }
+
+ // ...
+ })
+```
+
+
### Publishing
PeerTube plugins and themes should be published on [NPM](https://www.npmjs.com/) so that PeerTube indexes
and will be supported by web browsers.
If you want to write modern JavaScript, please use a transpiler like [Babel](https://babeljs.io/).
+### Add translations
+
+If you want to translate strings of your plugin (like labels of your registered settings), create a file and add it to `package.json`:
+
+```json
+{
+ ...,
+ "translations": {
+ "fr-FR": "./languages/fr.json",
+ "pt-BR": "./languages/pt-BR.json"
+ },
+ ...
+}
+```
+
+The key should be one of the locales defined in [i18n.ts](https://github.com/Chocobozzz/PeerTube/blob/develop/shared/models/i18n/i18n.ts).
+You **must** use the complete locales (`fr-FR` instead of `fr`).
+
+Translation files are just objects, with the english sentence as the key and the translation as the value.
+`fr.json` could contain for example:
+
+```json
+{
+ "Hello world": "Hello le monde"
+}
+```
+
### Test your plugin/theme
You'll need to have a local PeerTube instance:
and republish it on NPM. Remember that the PeerTube index will take into account your new plugin/theme version after ~24 hours.
+## Plugin & Theme hooks/helpers API
+
+See the dedicated documentation: https://docs.joinpeertube.org/#/api-plugins
+
+
## Tips
### Compatibility with PeerTube
}
})
```
- * Don't try to require parent PeerTube modules, only use `peertubeHelpers`. If you need another helper or a specific, please [create an issue](https://github.com/Chocobozzz/PeerTube/issues/new)
+ * Don't try to require parent PeerTube modules, only use `peertubeHelpers`. If you need another helper or a specific hook, please [create an issue](https://github.com/Chocobozzz/PeerTube/issues/new)
* Don't use PeerTube dependencies. Use your own :)
-If your plugin is broken with a new PeerTube release, update your code and the `peertubeEngine` `package.json` field.
+If your plugin is broken with a new PeerTube release, update your code and the `peertubeEngine` field of your `package.json` field.
This way, older PeerTube versions will still use your old plugin, and new PeerTube versions will use your updated plugin.
### Spam/moderation plugin
* `filter:api.video-thread-comments.list.result`: to change/hide the text of replies
* `filter:video.auto-blacklist.result`: to automatically blacklist local or remote videos
+### Other plugin examples
-
+You can take a look to "official" PeerTube plugins if you want to take inspiration from them: https://framagit.org/framasoft/peertube/official-plugins