You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the [client side Plugin API](https://meta.discourse.org/t/a-new-versioned-api-for-client-side-plugins/40051) is the safest way to build Discourse Javascript plugins and themes while respecting backwards compatibility.
7
+
Discourse's JavaScript API allows themes and plugins to make extensive customizations to the user experience. The simplest way to use it is to create a new theme from the admin panel, click "Edit Code", and then head to the JS tab.
8
8
9
-
However, some people have made simple customizations using the Admin > Customization > CSS/HTML and dropping some Javascript into a `<script>` tag. Previously, it was very difficult to use the `withPluginApi` to access objects using the Discourse container.
9
+
For file-based themes, the API can be used by creating a file in the `api-initializers` directory. For theme's that's `{theme}/javascripts/api-initializers/init-theme.gjs`, and for plugins, it's `{plugin}/assets/javascripts/discourse/api-initializers/init-plugin.js`. The content should be:
10
10
11
-
In the latest tests-passed build of Discourse I've added the ability to use the pluginAPI via a site customization.
11
+
```gjs
12
+
import { apiInitializer } from "discourse/lib/api";
12
13
13
-
To use it, you just need to add some attributes to a script tag in your `</HEAD>` customization:
When you save the customization, Discourse will transpile the ES2015 code within the tag so you can use the latest Javascript features. Additionally, it wraps the code in an initializer and runs it through `withPluginApi` so you don't have to bother with that. Just specify the version of the `api` object you want and Discourse will give it to you, providing safe backwards compatibility.
19
+
All the available APIs are listed in the [`plugin-api.gjs` source code](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/lib/plugin-api.gjs) in Discourse core, along with a short description and examples.
20
+
21
+
For a full tuturial, including examples of JS API usage, check out:
23
22
24
-
If the compilation of the ES2015 fails for some reason, when you view source on your page you'll see the error in a `<script type='text/discourse-js-error'>` block. Fix what it says and re-save your customization and you'll be good to go.
Copy file name to clipboardExpand all lines: docs/03-code-internals/13-plugin-outlet-connectors.md
-16Lines changed: 0 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -62,22 +62,6 @@ If you need custom logic as well, see the other ℹ️ sections below.
62
62
[/details]
63
63
[/quote]
64
64
65
-
[quote]
66
-
[details=ℹ️ Defining template via theme </head>]
67
-
We recommend using a dedicated file for your connector template. However, Discourse does still support defining a template via a `<script>` tag in your theme's `</head>` section. In that case, a definition would look like
Plugin Outlets provide information about the surrounding context via `@outletArgs`. The arguments passed to each outlet vary. An easy way to view the arguments is to add this to your template:
Copy file name to clipboardExpand all lines: docs/05-themes-components/07-multiple-js-files.md
+18-30Lines changed: 18 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,52 +6,40 @@ id: multiple-js-files
6
6
7
7
Complex theme javascript can be split into multiple files, to keep things nicely organised.
8
8
9
-
To use this functionality, simply add files to the `/javascripts` folder in your theme directory. Currently, these files can not be edited from the Discourse UI, so you must use the [Theme CLI](https://meta.discourse.org/t/discourse-theme-cli-console-app-to-help-you-build-themes/82950) or [source the theme from git](https://meta.discourse.org/t/how-to-source-a-theme-from-a-private-git-repository/82584).
9
+
To use this functionality, simply add files to the `/javascripts` folder in your theme directory. These files can not be edited from the Discourse UI, so you must use the [Theme CLI](https://meta.discourse.org/t/discourse-theme-cli-console-app-to-help-you-build-themes/82950) or [source the theme from git](https://meta.discourse.org/t/how-to-source-a-theme-from-a-private-git-repository/82584).
10
10
11
11
Javascript files are treated exactly the same as they are in core/plugins, so you should follow the same file/folder structure. Theme files are loaded after core/plugins, so if the filenames match, the theme version will take precedence.
12
12
13
13
---
14
14
15
15
As an example, you can now accomplish https://meta.discourse.org/t/adding-to-plugin-outlets-using-a-theme/32727 by adding a single file to your theme:
import Component from "@glimmer/component"; import { service } from
21
+
"@ember/service"; export default class HeaderMessage extends Component {
22
+
@service currentUser;
23
+
24
+
<template>
25
+
Welcome
26
+
{{this.currentUser.username}}
27
+
</template>
28
+
}
37
29
```
38
30
39
31
---
40
32
41
-
If you want to simply move some existing theme javascript out of a `<script type="text/discourse-plugin"` block, you should wrap it in an initializer like this:
@@ -205,14 +205,19 @@ If your user tries to enter a value that's not within the allowed range, they'll
205
205
206
206
<h3 id='heading--settings-js-css'>Access to settings in your JS/CSS/Handlebars</h3>
207
207
208
-
To have access to setting in your theme JS code, the `script` tag that wraps your code must have a `type="text/discourse-plugin"` attribute as well as `version` specified like so:
208
+
Theme settings are made available globally as a `settings` variable in theme JavaScript files. For example:
import { apiInitializer } from "discourse/lib/api";
213
+
214
+
export default apiInitializer((api) => {
215
+
console.log("settings are", settings);
216
+
});
214
217
```
215
218
219
+
This `settings` object is also usable as normal within `.gjs` `<template>` tags.
220
+
216
221
In CSS, you'll get a variable created for every setting of your theme and each variable will have the same name as the setting it represents.
217
222
218
223
So if you had a float setting called `global_font_size` and a string setting called `site_background`, you could do something like this in your theme CSS:
@@ -224,137 +229,6 @@ html {
224
229
}
225
230
```
226
231
227
-
Similarly, theme settings are available in handlebars templates that you define in your theme whether you're overriding a core template, or creating your own. For example if you have something like this in your theme:
If you have a question about this or there is something unclear, feel free to ask - I'll try to answer/clarify as much as I can. Also this is a wiki post, so contributions to improve this are greatly appreciated! :sunflower:
252
-
253
-
---
254
-
255
-
## :question: Frequently Asked Questions
256
-
257
-
[quote="p0fi, post:27, topic:82557"]
258
-
Can I combine javascript and handlebars in there somehow too? I would like to get the current year using javascript to put it in the string too.
259
-
[/quote]
260
-
261
-
Not directly; you’ll need to use the `registerConnectorClass` plugin API to add an attribute that has the current year to the connector instance behind your connector template. See an [example](https://github.com/OsamaSayegh/discourse-tab-bar-theme/blob/c05adce3274ffee821eadac8f81ffb54b85e5045/mobile/head_tag.html#L91) from my theme.
262
-
263
-
My theme sets the `tabs` attributes which is then referenced in the Handlebars template at the end of the file. You can do something like `this.set("year", compute current year here)` in the `setupComponent` method and then in your template you can access the year value like this `{{year}}`.
the `script` tag that wraps your code must have a `type="text/discourse-plugin"` attribute as well as `version` specified like so:
294
-
[/quote]
295
-
296
-
What’s that version value? Is it supposed to be the version of my plugin?
297
-
[/quote]
298
-
299
-
No, that’s the version of our [Plugin API](https://github.com/discourse/discourse/blob/e6b5b6eae348aa0f6148589a07e9ade0f08bae59/app/assets/javascripts/discourse/app/lib/plugin-api.js#L112)
300
-
301
-
We bump that every time a new method is added to the API so that themes / plugins which relay on methods that were recently added to the plugin API don’t end up breaking sites which haven’t been updated.
302
-
303
-
You don’t really need to worry about this a lot because:
304
-
305
-
1. We don’t add new methods very often
306
-
2. Most sites that use Discourse are updated very frequently.
Is it possible to access the theme settings from within the Ruby code as opposed to the JS?
310
-
[/quote]
311
-
312
-
To access theme settings in Ruby you need to call the `settings` method on a theme like so: `Theme.find(<id>).settings`. It will return an array which contains a [`ThemeSettingsManager`](https://github.com/discourse/discourse/blob/66151d805609839a333500248149da4cc5e9cae3/lib/theme_settings_manager.rb#L1) instance for each setting and from it you can get the setting name and value by calling the `name` and `value` methods respectively.
313
-
314
-
[quote="Heddson, post:47, topic:82557"]
315
-
Could things break if I don’t prefix my setting names with something like my theme name?
316
-
[/quote]
317
-
318
-
In JavaScript and hbs templates, there is no way this can happen. The `settings` variable that you use to access your theme settings is local to your theme and only contains your theme settings. In hbs templates, the settings of each theme are namespaced with their theme’s primary key in the database, so conflicts are impossible.
When I use a list in settings, I get the values as:
322
-
323
-
```
324
-
value1,value2,value3|value1,value2,value3
325
-
```
326
-
327
-
Is it possible to modify this output by declaring a different list_type? I’d like to use values from a list in Scss, but I think I could only de-structure the list if the output is formatted as
328
-
329
-
```
330
-
value1 value2 value3,
331
-
value1 value2 value3;
332
-
```
333
-
334
-
[/quote]
335
-
336
-
You can create custom SCSS functions to transform settings values into whatever format you want. E.g., in your case I think all you need is a string replace function that replaces commas with whitespace and pipes with commas? Here is an implementation of a string replace function in SCSS: [Str-replace Function | CSS-Tricks](https://css-tricks.com/snippets/sass/str-replace-function/)
Is it possible to access settings from another theme or component. e.g. if you have the category icons theme component installed, can you access information about the icons defined in its settings in a different custom theme component?
340
-
[/quote]
341
-
342
-
There is not a supported way to access the settings of another theme/component.
0 commit comments