Menu Templates
Templates define reusable layout layers applied to a Menu before decorate() runs. They handle decoration (borders, fillers, fixed buttons) so individual menus only declare their interactive content.
MenuTemplate interface
Section titled โMenuTemplate interfaceโpublic interface MenuTemplate { void apply(Menu menu);}AbstractMenuTemplate
Section titled โAbstractMenuTemplateโProvides protected helpers for common patterns:
public abstract class AbstractMenuTemplate implements MenuTemplate { protected void applyBorder(Menu menu, ItemStack filler) { ... } protected void applyFill(Menu menu, ItemStack filler) { ... }}applyBorderโ fills the outer ring of slots (top row, bottom row, left and right edges).applyFillโ fills every slot.
Built-in templates (Templates factory)
Section titled โBuilt-in templates (Templates factory)โ// Border with default gray glass pane fillerTemplates.bordered()
// Border with custom fillerTemplates.bordered(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).name(" ").build())
// Fill all slots with default filler (content overwrites after)Templates.filled()
// Fill with custom fillerTemplates.filled(myFillerItem)Using a template in a menu
Section titled โUsing a template in a menuโOverride template():
@Overrideprotected MenuTemplate template() { return Templates.bordered();}The template is applied first; decorate() runs after, so content overwrites template items in any slot.
Custom templates
Section titled โCustom templatesโExtend AbstractMenuTemplate for reusable layouts:
public final class ShopTemplate extends AbstractMenuTemplate {
@Override public void apply(Menu menu) { applyBorder(menu, new ItemBuilder(Material.PURPLE_STAINED_GLASS_PANE).name(" ").build());
// Fixed close button in the bottom center menu.set(49, MenuItem.of( new ItemBuilder(Material.BARRIER).name("<red>Close").build(), event -> menu.back())); }}Apply it: return new ShopTemplate();
YAML-driven templates
Section titled โYAML-driven templatesโDefine templates in menus.yml without recompiling:
my-template: filler: material: GRAY_STAINED_GLASS_PANE name: " " border: true items: title-icon: material: NETHER_STAR name: "<aqua><bold>My Menu" lore: - "<gray>A config-driven layout." slots: [4]Load and apply with YamlMenuTemplate:
Config menus = service(ConfigManager.class).load("menus.yml");MenuTemplate template = new YamlMenuTemplate(menus, "my-template");Then return it from template():
@Overrideprotected MenuTemplate template() { return new YamlMenuTemplate(menusConfig, "my-template");}YAML item format
Section titled โYAML item formatโ| Key | Description |
|---|---|
material |
Bukkit Material name (e.g. DIAMOND) |
name |
MiniMessage display name |
lore |
List of MiniMessage lore lines |
slots |
List of slot indices the item occupies |
border: true uses applyBorder; border: false uses applyFill.