Rustelo/resources/nickel/menus/defaults.ncl

133 lines
3.8 KiB
Text
Raw Normal View History

2026-07-18 20:16:16 +01:00
# Menu Configuration Defaults and Helpers
#
# Provides helper functions for creating menu items with minimal duplication.
# Single source of truth for multilingual menus.
let contracts = import "contracts.ncl" in
{
# Base defaults for menu items
base_menu_item = {
is_external = false,
enabled = true,
},
# Helper function: Create a basic menu item
#
# Usage:
# make_menu_item {
# id = "home",
# routes = { en = "/", es = "/inicio" },
# labels = { en = "Home", es = "Inicio" },
# }
#
# Parameters:
# config: Record with id, routes, labels, and optional icon/order
#
# Returns: MenuItem record with defaults
make_menu_item
| Dyn -> Dyn
= fun config =>
base_menu_item & {
id = config.id,
routes = config.routes,
labels = config.labels,
}
& (if std.record.has_field "icon" config then { icon = config.icon } else {})
& (if std.record.has_field "order" config then { order = config.order } else {})
& (if std.record.has_field "children" config then { children = config.children } else {})
& (if std.record.has_field "is_external" config then { is_external = config.is_external } else {})
& (if std.record.has_field "enabled" config then { enabled = config.enabled } else {})
& (if std.record.has_field "visible_in" config then { visible_in = config.visible_in } else {}),
# Helper function: Create an external link menu item
#
# External links use the same URL and label for all languages.
#
# Usage:
# make_external_item {
# id = "github",
# url = "https://github.com/user/repo",
# label = "GitHub",
# icon = "fab fa-github",
# }
#
# Parameters:
# config: Record with id, url, label, and optional icon/order
#
# Returns: ExternalMenuItem record
make_external_item
| Dyn -> Dyn
= fun config =>
{
id = config.id,
url = config.url,
label = config.label,
is_external = true,
enabled = true,
}
& (if std.record.has_field "icon" config then { icon = config.icon } else {})
& (if std.record.has_field "order" config then { order = config.order } else {})
& (if std.record.has_field "enabled" config then { enabled = config.enabled } else {})
& (if std.record.has_field "visible_in" config then { visible_in = config.visible_in } else {}),
# Helper function: Create a menu item with alternate language routes
#
# Some sites support both /about and /en/about for the same content.
#
# Usage:
# make_menu_item_with_alts {
# id = "services",
# routes = {
# en = "/services",
# es = "/servicios",
# "en-alt" = "/en/services",
# "es-alt" = "/es/servicios",
# },
# labels = { en = "Services", es = "Servicios" },
# }
#
# Parameters:
# config: Record with id, routes (including -alt), labels
#
# Returns: MenuItem with alternate routes
make_menu_item_with_alts
| Dyn -> Dyn
= fun config =>
make_menu_item config,
# Helper function: Create a menu item with submenu
#
# Usage:
# make_menu_with_children {
# id = "products",
# routes = { en = "/products", es = "/productos" },
# labels = { en = "Products", es = "Productos" },
# children = [
# make_menu_item { id = "product-a", ... },
# make_menu_item { id = "product-b", ... },
# ],
# }
#
# Parameters:
# config: Record with id, routes, labels, children array
#
# Returns: MenuItem with nested children
make_menu_with_children
| Dyn -> Dyn
= fun config =>
make_menu_item config,
# Common menu orders for consistent organization
menu_orders = {
home = 1,
about = 2,
services = 3,
portfolio = 4,
blog = 5,
recipes = 6,
contact = 10,
external_links = 100,
},
}