132 lines
3.8 KiB
Text
132 lines
3.8 KiB
Text
# 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,
|
|
},
|
|
}
|