.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "LLNG-BUILD-MANAGER-FILES 1p" .TH LLNG-BUILD-MANAGER-FILES 1p 2026-10-15 "perl v5.42.3" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME llng\-build\-manager\-files \- Regenerate LemonLDAP::NG Manager with plugin extensions .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 1 \& llng\-build\-manager\-files [\-\-plugins\-dir= ...] [options] .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" This script allows LemonLDAP::NG plugins to extend the Manager interface by adding new configuration attributes, tree nodes (for the configuration tree), and portal constants. .PP Extensions can be provided in either Perl (.pm) or JSON (.json) format and are loaded from the specified plugins directory. .SH OPTIONS .IX Header "OPTIONS" .IP \fB\-\-plugins\-dir\fR=\fIpath\fR 4 .IX Item "--plugins-dir=path" Directory containing plugin extension files (.pm or .json). Can be specified multiple times to scan several directories. If not specified or a directory doesn\*(Aqt exist, it is skipped with a warning. .IP \fB\-\-struct\-file\fR=\fIpath\fR 4 .IX Item "--struct-file=path" Output path for struct.json file. .IP \fB\-\-new\-struct\-file\fR=\fIpath\fR 4 .IX Item "--new-struct-file=path" Path to nstruct.json, the configuration tree of the new manager interface .IP \fB\-\-new\-manager\-attributes\-file\fR=\fIpath\fR 4 .IX Item "--new-manager-attributes-file=path" .PD 0 .IP \fB\-\-new\-manager\-definitions\-file\fR=\fIpath\fR 4 .IX Item "--new-manager-definitions-file=path" .IP \fB\-\-new\-manager\-tree\-file\fR=\fIpath\fR 4 .IX Item "--new-manager-tree-file=path" .PD Paths to the attributes, definitions and tree metadata of the new manager interface (default: in the \f(CW\*(C`new\*(C'\fR subdirectory of the static directory) .IP \fB\-\-new\-manager\-attributes\-extra\-file\fR=\fIpath\fR 4 .IX Item "--new-manager-attributes-extra-file=path" UI\-only attribute additions merged into the attributes metadata .IP \fB\-\-conftree\-file\fR=\fIpath\fR 4 .IX Item "--conftree-file=path" Output path for conftree.js file. .IP \fB\-\-manager\-constants\-file\fR=\fIpath\fR 4 .IX Item "--manager-constants-file=path" Output path for ReConstants.pm file. .IP \fB\-\-manager\-attributes\-file\fR=\fIpath\fR 4 .IX Item "--manager-attributes-file=path" Output path for Attributes.pm file. .IP \fB\-\-default\-values\-file\fR=\fIpath\fR 4 .IX Item "--default-values-file=path" Output path for DefaultValues.pm file. .IP \fB\-\-conf\-constants\-file\fR=\fIpath\fR 4 .IX Item "--conf-constants-file=path" Output path for Constants.pm file. .IP \fB\-\-reverse\-tree\-file\fR=\fIpath\fR 4 .IX Item "--reverse-tree-file=path" Output path for reverseTree.json file. .IP \fB\-\-portal\-constants\-file\fR=\fIpath\fR 4 .IX Item "--portal-constants-file=path" Output path for portal Constants.pm file. .IP \fB\-\-handler\-status\-constants\-file\fR=\fIpath\fR 4 .IX Item "--handler-status-constants-file=path" Output path for StatusConstants.pm file. .IP \fB\-\-lang\-dir\fR=\fIpath\fR 4 .IX Item "--lang-dir=path" Directory containing language JSON files (e.g., en.json, fr.json). Translations from extensions will be merged into these files. .IP "\fB\-\-verbose\fR, \fB\-v\fR" 4 .IX Item "--verbose, -v" Show detailed progress information. .IP "\fB\-\-help\fR, \fB\-h\fR" 4 .IX Item "--help, -h" Show help message. .SH "EXTENSION FILE FORMAT" .IX Header "EXTENSION FILE FORMAT" .SS "Perl Format (.pm)" .IX Subsection "Perl Format (.pm)" .Vb 1 \& package MyPlugin::Extension; \& \& sub attributes { \& return { \& myPluginEnabled => { \& type => \*(Aqbool\*(Aq, \& default => 0, \& documentation => \*(AqEnable my plugin\*(Aq, \& help => \*(Aqmyplugin.html\*(Aq, \& }, \& myPluginOption => { \& type => \*(Aqtext\*(Aq, \& default => \*(Aqdefault_value\*(Aq, \& }, \& }; \& } \& \& sub tree { \& return { \& insert_into => \*(AqgeneralParameters/plugins\*(Aq, \& nodes => [ \& { \& title => \*(AqmyPluginNode\*(Aq, \& help => \*(Aqmyplugin.html\*(Aq, \& form => \*(AqsimpleInputContainer\*(Aq, \& nodes => [\*(AqmyPluginEnabled\*(Aq, \*(AqmyPluginOption\*(Aq], \& } \& ], \& }; \& } \& \& sub ctrees { \& return { \& # Extend oidcRPMetaDataNode with additional options \& oidcRPMetaDataNode => { \& insert_after => \*(AqoidcRPMetaDataMacros\*(Aq, \& nodes => [ \& { \& title => \*(AqmyPluginOidcOptions\*(Aq, \& form => \*(AqsimpleInputContainer\*(Aq, \& nodes => [\*(AqmyPluginOidcAttr\*(Aq], \& } \& ], \& }, \& }; \& } \& \& sub constants { \& return { \& PE_MYPLUGIN_ERROR => 200, \& }; \& } \& \& sub lang { \& return { \& myPluginEnabled => { \& en => \*(AqEnable my plugin\*(Aq, \& fr => \*(AqActiver mon plugin\*(Aq, \& }, \& myPluginOption => { \& en => \*(AqMy plugin option\*(Aq, \& fr => \*(AqOption de mon plugin\*(Aq, \& }, \& }; \& } \& \& 1; .Ve .SS "JSON Format (.json)" .IX Subsection "JSON Format (.json)" .Vb 10 \& { \& "attributes": { \& "myPluginEnabled": { \& "type": "bool", \& "default": 0, \& "documentation": "Enable my plugin" \& } \& }, \& "tree": { \& "insert_into": "generalParameters/plugins", \& "nodes": [ \& { \& "title": "myPluginNode", \& "form": "simpleInputContainer", \& "nodes": ["myPluginEnabled"] \& } \& ] \& }, \& "ctrees": {}, \& "constants": { \& "PE_MYPLUGIN_ERROR": 200 \& }, \& "lang": { \& "myPluginEnabled": { \& "en": "Enable my plugin", \& "fr": "Activer mon plugin" \& } \& } \& } .Ve .SH "AUTH PLUGIN DECLARATION" .IX Header "AUTH PLUGIN DECLARATION" Authentication plugins can declare themselves via the \f(CW\*(C`authPlugin\*(C'\fR key (top level of an extension file, alongside \f(CW\*(C`attributes\*(C'\fR, \f(CW\*(C`tree\*(C'\fR, etc.) instead of manually appending to every select list: .PP .Vb 5 \& "authPlugin": { \& "k": "JsonFile", \& "v": "JSON File (dev/test)", \& "roles": ["authentication", "userDB"] \& } .Ve .PP Multiple plugins may be declared as an array. Allowed roles are \&\f(CW\*(C`authentication\*(C'\fR, \f(CW\*(C`userDB\*(C'\fR, and \f(CW\*(C`passwordDB\*(C'\fR. The option is appended to the following core selects based on the declared roles: .IP \(bu 4 \&\f(CW\*(C`authentication\*(C'\fR role: \f(CW\*(C`authentication\*(C'\fR, \f(CW\*(C`authChoiceModules\*(C'\fR (auth slot), \f(CW\*(C`combModules\*(C'\fR .IP \(bu 4 \&\f(CW\*(C`userDB\*(C'\fR role: \f(CW\*(C`userDB\*(C'\fR, \f(CW\*(C`authChoiceModules\*(C'\fR (userDB slot), \&\f(CW\*(C`combModules\*(C'\fR .IP \(bu 4 \&\f(CW\*(C`passwordDB\*(C'\fR role: \f(CW\*(C`passwordDB\*(C'\fR, \f(CW\*(C`authChoiceModules\*(C'\fR (password slot) .PP Appends are deduplicated on the \f(CW\*(C`k\*(C'\fR key, so re\-running the rebuilder or declaring the same plugin in multiple files is safe. .SH "TREE INSERTION" .IX Header "TREE INSERTION" The \f(CW\*(C`tree\*(C'\fR and \f(CW\*(C`ctrees\*(C'\fR extensions support the following insertion options: .IP \fBinsert_into\fR 4 .IX Item "insert_into" Path to the target node, using "/" as separator (e.g., "generalParameters/plugins"). .IP \fBinsert_after\fR 4 .IX Item "insert_after" Insert new nodes after the node with this title. .IP \fBinsert_before\fR 4 .IX Item "insert_before" Insert new nodes before the node with this title. .PP If neither \f(CW\*(C`insert_after\*(C'\fR nor \f(CW\*(C`insert_before\*(C'\fR is specified, nodes are appended at the end. .PP If \f(CW\*(C`insert_after\*(C'\fR or \f(CW\*(C`insert_before\*(C'\fR refers to a sibling that does not exist in the target tree, nodes are also appended at the end and a warning is printed on stderr pointing to the offending extension file. .SH TRANSLATIONS .IX Header "TRANSLATIONS" Extensions can provide translations for their configuration keys using the \&\f(CW\*(C`lang\*(C'\fR function (Perl) or \f(CW\*(C`lang\*(C'\fR key (JSON). Translations are specified as a hash where keys are the translation identifiers and values are hashes mapping language codes to translated text. .PP If a translation is not provided for a specific language, the script will: .ie n .IP "1. Use the English (""en"") translation if available" 4 .el .IP "1. Use the English (\f(CWen\fR) translation if available" 4 .IX Item "1. Use the English (en) translation if available" .PD 0 .IP "2. Fall back to the first available translation" 4 .IX Item "2. Fall back to the first available translation" .PD .PP This ensures all language files get an entry even if translations are only provided for a subset of languages. .SH "PORTAL CONSTANTS" .IX Header "PORTAL CONSTANTS" Plugin constants should use values >= 200 to avoid conflicts with core constants. A warning is issued if a value below 200 is used. .SH EXAMPLES .IX Header "EXAMPLES" .Vb 2 \& # Regenerate with plugins (uses default paths from installation) \& llng\-build\-manager\-files \-\-plugins\-dir=/etc/lemonldap\-ng/manager\-overrides.d \& \& # Multiple plugin directories \& llng\-build\-manager\-files \e \& \-\-plugins\-dir=/etc/lemonldap\-ng/manager\-overrides.d \e \& \-\-plugins\-dir=/usr/share/lemonldap\-ng/plugins.d \& \& # Verbose mode \& llng\-build\-manager\-files \-\-plugins\-dir=/etc/lemonldap\-ng/manager\-overrides.d \-v \& \& # Override specific output paths (useful for testing) \& llng\-build\-manager\-files \e \& \-\-plugins\-dir=/etc/lemonldap\-ng/manager\-overrides.d \e \& \-\-struct\-file=/custom/path/struct.json .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Lemonldap::NG::Manager::Build, .SH AUTHORS .IX Header "AUTHORS" LemonLDAP::NG team .SH LICENSE .IX Header "LICENSE" This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.