# 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, }, }