Split up theme Javascript into multiple files

Complex theme javascript can be split into multiple files, to keep things nicely organised.

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 or source the theme from git.

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.


As an example, you can now accomplish Using Plugin Outlet Connectors from a Theme or Plugin by adding a single file to your theme:

/javascripts/my-theme/connectors/discovery-list-container-top/add-header-message.gjs

import Component from "@glimmer/component"; import { service } from
"@ember/service"; export default class HeaderMessage extends Component {
@service currentUser;

<template>
  Welcome
  {{this.currentUser.username}}
</template>
}

To use the JS API, create an initializer:

/javascripts/discourse/api-initializers/init-theme.gjs

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  // Your code here
});

If you need a totally different .js asset (e.g. for a web worker), check out this topic.


This document is version controlled - suggest changes on github.

27 лайков

Предположим, я ничего не знаю о иерархии файлов в core/plugins, потому что я просто пришёл сюда, чтобы создать новый компонент темы. Где мне искать эту информацию? Какие соглашения об именовании существуют для каталогов и файлов внутри них?

Просто глядя на различные темы и компоненты, которые сейчас распространены, я вижу самые разные схемы вложенности и подкаталогов. Мне не удалось найти никакой закономерности или документации. (Например, в чём разница между /initializers, /api-initializers и /pre-initializers? :crying_cat_face:)

1 лайк

Файлы здесь используют API. Честно говоря, я тоже долго задавался вопросом: почему нельзя поместить файлы api-initializers в initializers?

Да. Это сложно понять. Я предпочитаю не думать о том, сколько раз я тратил 3 часа на что-то, только чтобы обнаружить, что назвал что-то неправильно или положил не в то место, а иногда просто забыл включить это одним из множества способов (в plugin.rb, в include в JS-файле — какой путь? Нужно ли расширение?)

Лучше всего использовать приложение командной строки Discourse Theme CLI для помощи в создании тем, чтобы оно создало для вас шаблон темы. Это также упрощает отладку, так как оно автоматически загружает тему на ваш сервер (обычный продакшн-сервер) и (как правило) автоматически перезагружает ваш браузер.

Не знаю, есть ли разница или какая именно (я не думаю, что есть? Но я мало что понимаю). Я бы использовал тот, который находится в шаблоне темы.

Существует репозиторий под названием all-the-themes. Вы можете скачать его и поискать примеры. Всегда используйте тот, который был изменён более недавно.

3 лайка

Многое в EmberJS (и Rails) основано на Convention over configuration. Это отлично работает в большинстве случаев, но может быть невероятно раздражающим, когда вы допускаете даже небольшую ошибку, например, в именовании.

3 лайка

Кстати, я нашел объяснение api-initializers/ здесь:

(Это связывает его с документацией Ember, и тогда всё начинает иметь смысл.)

Тем не менее, было бы здорово иметь в одном документе базовый перечень/объяснение возможных структур директорий. (Например, я знаю, что connectors/ существует… есть ли ещё что-то?)

Также, кстати: приложение Theme CLI загружает шаблон отсюда:

Там упоминается только api-initializers/.

(Я, собственно, использую приложение Theme CLI, но начал пользоваться им уже после того, как у меня были первые наработки компонента темы, поэтому я пропустил шаг с шаблоном.)

2 лайка