# ILayoutManager > Pages authored in the Lectern UI editor: loading them, opening them, and running what their elements are bound to. `gg.lode.lecternapi.api.manager.ILayoutManager` --- ## Signature ```java public interface ILayoutManager ``` --- ## Notes This is the layer above `IHUDManager.playLayout`. That call plays a layout and stops, the server owns every decision about when it appears and what it does. A page instead carries its own rules, so dropping an exported file into `plugins/Lectern/layouts/` is enough to get a command, an opening on join, and buttons that work, with no plugin written for it. Pages are loaded from disk on startup and can be reloaded without a restart. A page opened for a player is tracked, which is what lets a click be matched back to the page that was showing rather than to whatever the client claims. ```java ILayoutManager layouts = api.getLayoutManager(); layouts.open(player, "stats", Map.of("kills", "12")); ``` --- ## Methods ### getPages ```java Collection<LayoutPage> getPages() ``` Every page currently loaded, keyed by id. --- ### getPage ```java LayoutPage getPage(String id) ``` The page with this id, or null if none is loaded. | Parameter | Type | |---|---| | `id` | `String` | --- ### register ```java void register(LayoutPage page) ``` Registers a page at runtime, replacing any already loaded under the same id. For a plugin that ships its own pages rather than expecting a server owner to install files. A page added this way is dropped on the next `reload()`, which only rereads the folder. | Parameter | Type | |---|---| | `page` | `LayoutPage` | --- ### reload ```java int reload() ``` Rereads `plugins/Lectern/layouts`, replacing what is loaded. Commands are re-registered to match, and a page a player has open is left alone: reloading mid-session changes what opens next, not what is already on screen. **Returns:** how many pages were loaded --- ### open ```java void open(Player player, String id) void open(Player player, String id, Map<String, String> variables) void open(Player player, LayoutPage page, Map<String, String> variables) ``` Opens a page for a player, applying its behaviour. Opens a page for a player, filling `%tokens%` in its text from `variables`. Opens an already-resolved page, which need not be one loaded from disk. --- ### close ```java void close(Player player, String id) ``` Closes a page for a player. Does nothing if they do not have it open. | Parameter | Type | |---|---| | `player` | `Player` | | `id` | `String` | --- ### closeAll ```java void closeAll(Player player) ``` Closes every page the player has open. | Parameter | Type | |---|---| | `player` | `Player` | --- ### getOpenPages ```java Collection<String> getOpenPages(Player player) ``` The ids of the pages this player currently has open. | Parameter | Type | |---|---| | `player` | `Player` | --- ### isOpen ```java boolean isOpen(Player player, String id) ``` Whether this player has this page open. | Parameter | Type | |---|---| | `player` | `Player` | | `id` | `String` | --- ### openPublished ```java void openPublished(Player player, String publishedId, String scene) void openPublished(Player player, String publishedId, String scene, LayoutTransition transition) ``` Plays a layout published on lode.gg, fetched by its shared id. Unlike `open`, which draws on the pages in the server's own layouts folder, this plays a document its author published from the editor, so a change made on the site reaches the server without a file drop or a restart. The document is cached after the first fetch and reused. The fetch itself runs off the main thread and the playback hops back onto it, so a slow answer from lode.gg costs a frame of lateness rather than a stalled tick. Call `clearPublishedCache()` to pick up an edit. As above, deciding how the switch looks rather than leaving it to the document. Worth using when the server knows something the author could not: a scene cut short by a round ending wants to leave from wherever it got to, while a deliberate change of state may want the cut. Pass `LayoutTransition.inherit()` to keep the scene's own setting, which is what the three-argument form does. --- ### closePublished ```java void closePublished(Player player, String publishedId) ``` Takes a published layout off screen, by the same id it was opened with. | Parameter | Type | |---|---| | `player` | `Player` | | `publishedId` | `String` | --- ### clearPublishedCache ```java int clearPublishedCache() ``` Forgets every cached published document, so the next play fetches it again. **Returns:** how many were being held --- ### fire ```java int fire(Player player, String pageId, String elementRef, LayoutAction.Trigger trigger) ``` | Parameter | Type | |---|---| | `player` | `Player` | | `pageId` | `String` | | `elementRef` | `String` | | `trigger` | `LayoutAction.Trigger` | --- ## Example Open a page you exported from the UI editor, filling in its `%tokens%`: ```java ILayoutManager layouts = LecternAPI.getApi().getLayoutManager(); layouts.open(player, "stats", Map.of( "kills", String.valueOf(stats.kills()), "rank", stats.rank())); ``` The page came from `plugins/Lectern/layouts/stats.json`, so nothing here had to describe what it looks like. If you edit the file, `layouts.reload()` picks it up without a restart and returns how many pages it read. Closing is by id, and a player can have several pages open at once: ```java if (layouts.isOpen(player, "stats")) { layouts.close(player, "stats"); } ``` To run an element's bindings yourself, without the player clicking anything: ```java layouts.fire(player, "stats", "close_button", LayoutAction.Trigger.CLICK); ``` --- ## Related Pages - [[LayoutPage]]. The page, its behaviour and its transitions - [[LayoutOpenEvent]]. Gate a page before it opens - [[LayoutInteractEvent]]. Gate what its elements do - [[IHUDManager]]. Playing a layout straight from the server instead