- Replacing the Journal Sheet is difficult to do in a way which is compatible with both Foundry Core and other modules/systems which replace Journal Sheets.
- Styling a particular journal entry (or kind of entry, e.g. from a particular module) is difficult to do in a way which does not conflict with other modules.
- Modules which alter the display of Journal Entries would like a predictable way to do so, which is hard when different modules use different approaches to work around the issues above.
This issue outlines a generic request that if implemented would allow Journal (and other document) "sheets" to be registered just like Actor sheets.
This module continues to provide a means for modules to keep their custom sheets from allying to documents that they should not be. For example, a JournalEntry
sheet that should be used for a special loot list, but shouldn't be used for normal journal entries.
Our goal with this library is to offer a way to leverage this missing API as Foundry Gaming considers implementing this solution in Core.
You should consider using this module if you replace or drastically modify one of the compatible Document Sheets in a module and want your module to be compatible with other modules and systems which do the same.
Note that systems are encouraged to override the base sheet in CONFIG and should not need to use this library.
The core flag sheetClass
on the document will establish which registered sheet to use when opening.
It can be set in any of the ways a flag can be set.
someJournalEntry.setFlag('core', 'sheetClass', 'my-module.MyModuleSheetClassName');
This library introduces the ability to give documents "types" even for documents that did not support types before. The object.type
property is supported on many documents in Core such as Actor (character, npc, vehicle), Item, Macro (script, chat), and others. This allows a document to have type-specific sheets such as NPC sheets vs. character sheets. With Document Sheet Registrar, we can add "artificial" types to any of the following nine do documents:
- Actor
- Item
- JournalEntry
- RollTable
- Macro
- Playlist
- Scene
- User
- Folder
There are two steps to adding a new artificial type. First, you must register a new sheet and pass your custom type as part of the types
array:
DocType.registerSheet?.("myModule", SheetApplicationClass, {
types: ["my-type"],
makeDefault: false,
label: "My document sheet"
});
When you register a sheet in this way, the sheet will only be available to documents with the specified type. Since the object.data.type
property is part of the official schema of the document, we can not add this property to documents that don't already support it, or give it a custom value. Instead, DSR uses a type
flag in the _document-sheet-registrar
scope to specify the artificial type.
document.setFlag("_document-sheet-registrar", "type", "my-type")
This will cause the object.type
getter on the document to return the value stored in this flag, resulting in a different selection of sheets which are specific to that type
.
Note that if no sheet is registered to handle a given document and type, an error will occur. When this happens with the library enabled, a UI warning is displayed. When the library is disabled, the default sheet for that document will render.
Most of the following only applies to versions of this module below 1.0.0, used in Foundry versions before v9.
Once this library is active (it should be activated at the start of the init
hook), it enables the same API that Actor and Item documents use to register and unregister sheets for any Document Type in CONFIG
which has both a sheetClass
and a collection
:
Actor(core)Item(core)- JournalEntry
- RollTable
- Macro
- Playlist
- Scene
- User
- Folder
This library provides two hooks:
Hooks.on("preDocumentSheetRegistrarInit", (settings) => {});
Hooks.on("documentSheetRegistrarInit", (documentTypes) => {});
The preDocumentSheetRegistrarInit
hook passes an object of boolean "settings", you must set the setting corresponding to the document type that you wish to register a sheet for to true
. If you do not do this, the registration method will not be created which will produce an error when you call it.
The documentSheetRegistrarInit
hook indicates that the initialization process has been completed, and it is now safe to register your sheets. This hook also passes an object of data about any documents for which this library has been enabled.
From the preDocumentSheetRegistrarInit
hook you can choose to enable this library for particular document types. The hook passes a settings
parameter which is an object like so:
{
Actor: false
Folder: false
Item: false
JournalEntry: false
Macro: false
Playlist: false
RollTable: false
Scene: false
User: false
}
You need only to set the appropriate value to true
for the document type you wish to register a sheet for.
Example:
Hooks.on("preDocumentSheetRegistrarInit", (settings) => {
settings["JournalEntry"] = true;
});
This will enable Journal.registerSheet
.
Register a sheet class as a candidate which can be used to display this document.
You must enable your chosen document type in the preDocumentSheetRegistrarInit
hook for this method to be available.
Name | Type | Description | |
---|---|---|---|
scope | string |
Provide a unique namespace scope for this sheet | |
sheetClass | Application |
A defined Application class used to render the sheet | |
options | Object |
Additional options used for sheet registration | |
options.label | string |
A human readable label for the sheet name, which will be localized | Optional |
options.types | Array.<string> |
An array of entity types for which this sheet should be used. When not specified, all types will be used. That does not include artificial types, if you are using artificial types you must specify them here. | Optional |
options.makeDefault | boolean |
Whether to make this sheet the default for provided types | Optional |
Journal.registerSheet?.("myModule", SheetApplicationClass, {
types: ["base"],
makeDefault: false,
label: "My Journal Entry sheet"
});
Unregister a Journal Entry sheet class, removing it from the list of available Applications to use for Journal Entries.
You must enable your chosen document type in the preDocumentSheetRegistrarInit
hook for this method to be available.
Name | Type | Description | |
---|---|---|---|
scope | string |
Provide a unique namespace scope for this sheet | |
sheetClass | Application |
A defined Application class used to render the sheet | |
options | Object |
Additional options used for sheet registration | Optional |
options.types | Array.<string> |
An Array of types for which this sheet should be removed | Optional |
Journal.unregisterSheet?.("myModule", SheetApplicationClass, {
types: ["base"],
});
In order to give the user control of how their documents are rendered, documents that have multiple registered sheets will now have a "⚙ sheet" button in the header of their sheet application. This button opens the same sheet dialog that is used by Actor and Item.
If for some reason you need to prevent users from modifying this, you can hide the button with CSS by targeting the .configure-sheet
class on the element.
If it is important that documents created for your module only be rendered using sheets provided by your module, you may also want to restrict which sheets are available by setting a particular type
for those sheets. You can specify an existing type for documents that support it, e.g. "script" Macros, or you can use the artificial types system discussed in the API section above. The sheet config dialog will only give the user the option to select a sheet that is valid for the type of the document being configured.
This package is licensed under the MIT license, see LICENSE file for details.
Portions of the code are copied from Foundry VTT in accordance with the Foundry LIMITED LICENSE AGREEMENT FOR MODULE DEVELOPMENT. These portions are not covered by the MIT license, but by the FOUNDRY VIRTUAL TABLETOP END USER LICENSE AGREEMENT. These portions of code are marked with code comments.