![No UI](https://img.shields.io/static/v1?label=UI&message=none&color=inactive) The *Configurable Filenames* makes it possible to define complex filename resolvers through configuration only. If needed, new features/properties can be added. A configurable filename *resolver* is built on reusable *parts* and *rules*. Rules can be applied to resolvers (the resulting string) and parts. If a rule has several properties defined, they are applied in the following order: 1. *extract* with optional *fallback* 2. *search* only (= delete) i.e. *search/replace* 3. *trim* (set it to true to trim the value) 4. *formatDuration* (to format a duration in seconds) 4. *empty* or *replaceEmptyWithPart* to replace an empty resulting string with this value 5. *pad* for padding (if empty/replaceEmptyWithPart and padding is set, then the padding is only applied to strings that weren't empty before applying the empty rule) 6. *prefix*, *suffix* 7. *alwaysPrefix*, *alwaysSuffix* 8. *length* (cuts off the rest of the string if it is longer than the given length) **If rules are applied to a part and it is a value list (e.g. node referencing information fields) the rules are applied to each element.** The parts are processed in order and for each part, the evaluation happens as follows (all actions are only performed if the involved parameters are not empty): 1. Get the value depending on the type of the part (e.g. the value of an information field). 2. Apply the rules (in order) to the value. 3. Prepend the value with the specified delimiter if the value and at least one part before the current are not empty. Note: It is not possible to disable a download format with a configurable filename resolver due to the way the configurable filename resolvers are loaded. The download format will be enabled again after a server restart. To disable the download format permanently, the configurable filename resolver has to be removed. [MINITOC] ## Properties To be configured in {home}/appserver/conf/custom.properties ##### configurableFilenameResolver.license > type: string, **required: yes**, default: - The license key for the plugin (product: configurableFilenameResolver), provided by *brix*. ##### configurableFilenameResolver.originalResolver > type: string, required: no, default: -, available since v1.0.1 Because a resolver for the original download format specified via configuration is removed on start up, it has to be specified here. If this is empty, nothing will be done, but if the resolver is set then it will be set each time the system is started. E.g. to set the example resolver as the resolver for the original download format, you would do `configurableFilenameResolver.originalResolver=pretty`. ##### configurableFilenameResolver.resolver.{id}.parts > type: comma-separated list of part ids, **required: yes**, default: 10 The filename resolver's name will be `configurableFilenameResolver.{id}`. All ids in this document are normal strings without dots and spaces. This property expects a comma-separated list of part ids which will be processed in the specified order. ##### configurableFilenameResolver.resolver.{id}.rules > type: comma-separated list of rule ids, required: no, default: - The rules which should be applied in the given order. ##### configurableFilenameResolver.rule.{id}.search > type: regex, required: no, default: - The regular expression to search for in a value. All matches are either removed or replaced by the string configured in the replace property of the rule. There is one predefined rule called `invalid` to remove all invalid characters for filenames (the backslash is escaped twice, once for the property file and once for the regex, that's why there are four of them): `configurableFilenameResolver.rule.invalid.search=[\\\\/:*?"<>|]+` ##### configurableFilenameResolver.rule.{id}.replace > type: string, required: no, default: - The string to replace the matches with. If a rule has no corresponding replace, the matches are removed. A replace without a search is ignored. ##### configurableFilenameResolver.rule.{id}.extract > type: regex, required: no, default: - A regular expression to extract a value, the first capturing group `(...)` is taken. Make non-capturing groups with `(?:...)`. ##### configurableFilenameResolver.rule.{id}.fallback > type: string, required: no, default: - Fallback string to use if the regex does not find anything. Use `` to just use empty string if the regex doesn't match, otherwise the original value is taken. ##### configurableFilenameResolver.rule.{id}.trim > type: boolean, required: no, default: - If set to true, the resulting string is trimmed. There is a predefined rule which does nothing else but trimming the value: `configurableFilenameResolver.rule.trim.trim=true` ##### configurableFilenameResolver.rule.{id}.durationFormat > type: string, required: no, default: - Format a duration in seconds. Available symbols: - `y` year (365 days) - `M` month (30 days) - `w` week (7 days) - `d` days (24 hours) - `h` hours (60 minutes) - `m` minutes (60 seconds) - `s` seconds The symbols above can be repeated, to enforce a minimum number of digits. E.g. `hh':'mm` would display `00:08` for 8 minutes. With `?` the unit is optional and only displayed if not 0. E.g. `h?':'m` would just display `8` for 8 minutes. The `?` has to follow right after the unit symbols. If the unit is omitted a literal right after it is omitted too. With `'abc'` literals are introduced. The `'` can be escaped with `\`, so `\` has to be escaped too. E.g. `h?' hours 'm' minutes'` would display `8 minutes` for 8 minutes. The smallest unit can have a decimal point. E.g. `m.mm` would display `0.50` for 30 seconds and `0.16` i.e. `0.17` for 10 seconds (depending on rounding). The smallest unit is rounded mathematically unless specified with the very last character (`<` to round down and `>` to round up). E.g. `m.mm>` would display `0.34` for 20 seconds. ##### configurableFilenameResolver.rule.{id}.empty > type: string, required: no, default: - If the resulting value is empty it is replaced by this one. ##### configurableFilenameResolver.rule.{id}.replaceEmptyWithPart > type: string, required: no, default: -, since v1.1.3 If the resulting value is empty it is replaced by the part with the given id. ##### configurableFilenameResolver.rule.{id}.pad > type: string, required: no, default: - The string which should be used to pad the value. E.g. if the value is `876` and pad is `abcdefg` then the result would be `abcd876`. A realistic use case would be `pad=000` to get 3 digit version numbers, so if version is `7` then the result would be `007`. Optionally combined with prefix `v` to get `v007`. To prevent padding of empty strings set empty to ``. ##### configurableFilenameResolver.rule.{id}.length > type: integer, required: no, default: `0` (no limit) Everything exceeding the given length will be cut off. ##### configurableFilenameResolver.rule.{id}.prefix > type: string, required: no, default: - A static prefix, only prepended to the value if it is not empty. <SPACE> denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. ##### configurableFilenameResolver.rule.{id}.suffix > type: string, required: no, default: - A static suffix, only appended to the value if it is not empty. <SPACE> denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. ##### configurableFilenameResolver.rule.{id}.alwaysPrefix > type: string, required: no, default: - A static prefix, always prepended to the value even if it is empty. <SPACE> denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. ##### configurableFilenameResolver.rule.{id}.alwaysSuffix > type: string, required: no, default: - A static suffix, always appended to the value even if it is empty. <SPACE> denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. ##### configurableFilenameResolver.part.{id}.type > type: string, **required: yes**, default: - The type of the part. Here are the currently available types: - assetId - name (asset name without file extension) - originalName (original file name without file extension) - info_{id} (the information field with the given id) - version (just an integer) - assetType - assetTypeId - downloadFormat - parents (nodes to which the asset is linked to) - static_{text} (static text) - created (asset creation date) - file_{property} (the file property to extract, e.g. width, height, pages, duration, be careful because if formatting is done on values that are not always available, then the resolver might fail for assets where the property isn't set) ##### configurableFilenameResolver.part.{id}.rules > type: comma-separated list of rule ids, required: no, default: - The rules which should be applied in the given order. ##### configurableFilenameResolver.part.{id}.delimiter > type: string, required: no, default: - A delimiter with which the part is prepended if it is not empty and at least one part before it is not empty too. `` denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. ##### configurableFilenameResolver.part.{id}.format > type: simple date format string, required: no, default: `dd.MM.yyyy` Java SimpleDateFormat to format date values. ##### configurableFilenameResolver.part.{id}.valueDelimiter > type: string, required: no, default: `,` The delimiter for the values of the part (for node referencing fields and parents). `` denotes a space, this is needed for spaces at the beginning and the end of the prefix because the property loader trims the normal spaces. Use `` to specify no delimiter at all. ##### configurableFilenameResolver.part.{id}.max > type: integer, required: no, default: `0` (no limit) The maximum number of values to use for this part (for node referencing fields and parents). So only the first `max` ones are taken. ##### configurableFilenameResolver.part.{id}.collect > type: string, required: no, default: - The string to use if there are more than max values (for node referencing fields and parents). ##### configurableFilenameResolver.part.{id}.locales > type: comma-separated list of locales, required: no, default: (default system locale) The locale(s) to use for localized values (parents, assetType, downloadFormat, localized information fields, node referencing information fields, dropdowns). If the value is empty for the first locale then the next one is tried and so on. If this property is set then it is recommended to have the default system locale somewhere in there, unless it is the desired behavior that the part is ignored if there is no value in the given languages. ##### configurableFilenameResolver.part.{id}.nodeTypeIds > type: comma-separated list of node type ids, required: no, default: - If this property is set then all nodes with other types than the given ones are ignored. Applicable to parents and node referencing information fields. ##### configurableFilenameResolver.part.{id}.nodeIds > type: comma-separated list of node ids, required: no, default: - If this property is set then all nodes which are not under at least one of the given nodes are ignored. Applicable to parents and node referencing fields. ##### configurableFilenameResolver.part.{id}.recursive > type: boolean, required: no, default: `true` If this is set to false then only the nodes which are direct children of the nodes specified in nodeIds are considered. Applicable to parents and node referencing fields. ## Example configuration configurableFilenameResolver.rule.invalid.search=[\\\\/:*?"<>|]+ configurableFilenameResolver.rule.space.search=[ ]+ configurableFilenameResolver.rule.space.replace=- configurableFilenameResolver.rule.versionFormat.pad=000 configurableFilenameResolver.rule.versionFormat.alwaysPrefix=v configurableFilenameResolver.part.brand.type=info_84781 configurableFilenameResolver.part.brand.max=4 configurableFilenameResolver.part.brand.valueDelimiter=+ configurableFilenameResolver.part.brand.rules=invalid,space configurableFilenameResolver.part.docType.type=info_84773 configurableFilenameResolver.part.docType.valueDelimiter=+ configurableFilenameResolver.part.docType.rules=invalid,space configurableFilenameResolver.part.docType.delimiter=_ configurableFilenameResolver.part.lang.type=info_84779 configurableFilenameResolver.part.lang.max=1 configurableFilenameResolver.part.lang.collect=Multilingual configurableFilenameResolver.part.lang.rules=invalid,space configurableFilenameResolver.part.lang.delimiter=_ configurableFilenameResolver.part.version.type=version configurableFilenameResolver.part.version.rules=versionFormat configurableFilenameResolver.part.version.delimiter=_ configurableFilenameResolver.part.assetId.type=assetId configurableFilenameResolver.part.assetId.delimiter=_ configurableFilenameResolver.resolver.pretty.parts=brand, docType, lang, version, assetId Possible result: `Brand-1+Brand-2_DocType-1+DocType-2_Multilingual_v003_9512.jpg` ## Compatibility Matrix | Configurable Filename Resolver | CELUM (min. version) | |:-------------------------------|:------------------------------------------------------| | < 1.1.4 | <= 6.8 (tested up to 6.8) | | 1.1.4+ | 6.14+ (tested with 6.14, might work for 6.10 to 6.13) | ## Release Notes ##### 1.0.0 > Released 2020-07-31 Initial version ##### 1.1.0 > Released 2021-06-29 Added file properties (file_{property} type) and formatDuration rule. ##### 1.1.3 > Released 2021-09-02 Added the possibility to replace empty resulting strings by parts. ##### 1.1.4 > Released 2022-10-13 Support for newer CELUM versions