### Using loop.first in for loop Source: https://docs.juniper.bot/en/message-templates/advanced/tags Demonstrates the loop.first property, which is true only in the first iteration. The example outputs 'Start' only once. ```JuniperBot Template {% for item in [1, 2, 3] %} {% if (loop.first) %} Start {% endif %} {% endfor %} ``` -------------------------------- ### title function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Capitalizes the first letter of every word. This example produces 'Hello World'. ```JuniperBot Template {{ title('hello world') }} ``` -------------------------------- ### startsWith basic usage Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if the first string starts with the second. Returns true for 'hello' starting with 'he'. ```JuniperBot Template {{ startsWith('hello', 'he') }} ``` -------------------------------- ### split function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Splits the first argument by the second argument into a collection. This example returns '[juniper, bot]'. ```JuniperBot Template {{ split('juniper-bot', '-') }} ``` -------------------------------- ### keys function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Returns the collection of keys for a given collection. The example produces '[0, 1]'. ```JuniperBot Template {{ keys(['A', 'B']) }} ``` -------------------------------- ### upper function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Converts the string to uppercase. This example prints 'JUNIPERBOT'. ```JuniperBot Template {{ upper('juniperbot') }} ``` -------------------------------- ### Embed Builder Example Source: https://docs.juniper.bot/en/message-templates/types/discord/embed Example of chaining Embed builder methods to create and send a Discord embed. ```APIDOC ## Embed Builder Example ### Description Demonstrates how to use the Embed builder methods in a chain to create and send a Discord embed. ### Code ``` {% do channel .createEmbed() .withContent('Content outside the embed') .withTitle('Title', 'https://juniper.bot') .withDescription('Oh, hi!') .appendDescription('\nHow are you?') .withDate(1587713425964) .withColor('ffff00') .withThumbnail(member.avatarUrl) .withImage('https://i.pinimg.com/originals/a4/41/6e/a4416e024d691af3a2971e4114a6da7f.png') .withAuthor(member.nickname) .withFooter('Huff, bye!', member.avatarUrl) .addField('First field', 'Ah! A value of the first field', true) .addField('Second field', 'Something here too', true) .addReaction(':fox_face:') .addButton('LINK', 'https://juniper.bot/', 'Website', '🦊') .send() %} ``` ``` -------------------------------- ### slice function examples Source: https://docs.juniper.bot/en/message-templates/advanced/functions Slices a string or collection. The first example returns '2', the second returns '[1, 2]'. The third and fourth examples demonstrate boundary handling, returning '3' and '' respectively. ```JuniperBot Template {{ slice("123", 1, 1) }} ``` ```JuniperBot Template {{ slice([1, 2, 3], 0, 2) }} ``` ```JuniperBot Template {{ slice("123", 2, 3) }} ``` ```JuniperBot Template {{ slice("123", 5, 1) }} ``` -------------------------------- ### capitalize function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Capitalizes the first word of the string. This example renders as 'Hello world'. ```JuniperBot Template {{ capitalize('hello world') }} ``` -------------------------------- ### join function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Joins list elements with a separator. Ignores null values. The example outputs '1|2'. ```JuniperBot Template {{ join([1, null, 2], '|') }} ``` -------------------------------- ### lower function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Converts the string to lowercase. This example prints 'juniperbot'. ```JuniperBot Template {{ lower('JUNIPERBOT') }} ``` -------------------------------- ### concat function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Concatenates an arbitrary number of string arguments. The example outputs '1+1=2'. ```JuniperBot Template {{ concat('1', '+', '1', '=', '2') }} ``` -------------------------------- ### trim function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Removes whitespace from the beginning and end of the string. This example produces 'Hello World' without whitespaces. ```JuniperBot Template {{ trim(' Hello World ') }} ``` -------------------------------- ### format function with placeholders Source: https://docs.juniper.bot/en/message-templates/advanced/functions Formats a string using %s placeholders and provided values. This example prints 'hello world! 123'. ```JuniperBot Template {{ format('hello %s! %s', 'world', 123) }} ``` -------------------------------- ### values function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Returns the collection of values for a given collection. The example produces '[one, two]'. ```JuniperBot Template {{ values({'1':'one', '2':'two'}) }} ``` -------------------------------- ### sort function examples Source: https://docs.juniper.bot/en/message-templates/advanced/functions Sorts a collection. The first example uses default ASC sort and produces '[1, 10, 2]'. The second example uses NUM_ASC and produces '[1, 2, 10]', removing non-numeric elements. ```JuniperBot Template {{ sort(['2', '1', '10']) }} ``` ```JuniperBot Template {{ sort(['2', '1', '10', 'NotANumber'], 'NUM_ASC') }} ``` -------------------------------- ### shuffle function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Randomly shuffles the values of a list. The example prints a randomly shuffled sequence of A, B, C, D. ```JuniperBot Template {{ shuffle(['A', 'B', 'C', 'D']) }} ``` -------------------------------- ### date function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Formats a date using the specified format and timezone. The example uses 'now' as the date, a Java SimpleDateFormat pattern, and the 'Europe/Moscow' timezone. The output is 'Tue, 22 Jun 2021 04:04:05 MSK'. ```JuniperBot Template {{ date('now', 'EEE, d MMM yyyy HH:mm:ss z', 'Europe/Moscow') }} ``` -------------------------------- ### duration function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Formats a time interval in milliseconds into a readable format. The example uses 3650 milliseconds and a maximum of 2 units, producing '3 sec, 650 ms'. ```JuniperBot Template {{ duration(3650, 2) }} ``` -------------------------------- ### Get slash command options by type Source: https://docs.juniper.bot/en/cmd/custom/index Use this template to get a list of all slash command options of a specified type, such as 'MEMBER'. The options are passed as part of the 'arguments' variable. ```JuniperBot Template {{ arguments.getOptionsByType('MEMBER') }} ``` -------------------------------- ### even function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if a number is even. Returns 'true' when the number is even, 'false' otherwise. The example prints 'A' because 2 is even. ```JuniperBot Template {% if (even(2)) %}A{% else %}B{% endif %} ``` -------------------------------- ### default function Source: https://docs.juniper.bot/en/message-templates/advanced/functions Returns the second argument if the first argument is null or Undefined. The example produces 'Hello World' because undefinedVariable is not defined. ```JuniperBot Template {{ default(null, 'Hello') }} {{ default(undefinedVariable, 'World') }} ``` -------------------------------- ### Comparison Order Example in JuniperBot Template Source: https://docs.juniper.bot/en/message-templates/types/type-convert Shows two expressions that appear equivalent but produce different results due to the order of operations in type conversion. The first prints false, the second prints true, illustrating the algorithm's behavior. ```JuniperBot Template {{ 'true' == 1 == true }} {{ true == 1 == 'true' }} ``` -------------------------------- ### batch function example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Splits a list into equally sized groups. Expects a list as first argument and group size as second. Outputs a list of groups. ```JuniperBot Template {{ batch([1,2,3], 2) }} ``` -------------------------------- ### JuniperBot Template: Create and send a selection menu with method chaining Source: https://docs.juniper.bot/en/message-templates/types/discord/menu-builder Shows how to build a selection menu using method chaining on a channel. The menu is of type 'STRING', has a custom ID, and includes two options with a default option. The menu is then sent to the channel. ```juniperbot-template {% do channel .createEmbed() .withDescription('Oh, hi!') .addSelectMenu('STRING', 'selectedSpecies', 'Who are you?', '27a55ca1-c13b-47f5-b8ad-e0da6329a53f') .addOption('Otter', 'otterOption', ':otter:') .addOption('Fox', 'foxOption', ':fox_face:') .withDefaultOption('foxOption') .endMenu() .send() %} ``` -------------------------------- ### Pagination Example for Balance Top Source: https://docs.juniper.bot/en/message-templates/persistence/guild-indexes Complete message template for a balance top with pagination navigation. Requires a Send Message action in text mode with 'Edit Component Message' checked, and replacing the action UUID. Only one page per index can be requested per message, up to 25 entries. ```JuniperBot Template {% set actionId = 'ae04dfed-e19c-49d3-84fc-b05cec59976e' %} {% set targetMember = arguments.targetMember %} {% if targetMember and not component %} {% set newBalance = random(1000) %} {# Requesting balance entry for member from balances index #} {% set balanceEntry = guild.indexes.balances.get(targetMember.id) %} {# Updating the balance #} {% do balanceEntry.update(newBalance) %} Balance of {{ targetMember }} has been set to {{ newBalance }}! {% else %} {# Calculating requested page number #} {% set wasLast = parameters.get('page.isLast') %} {% set pageNum = (parameters.get('page.number')) ?: 0 %} {% if component.id == 'next_page' and not wasLast %} {% set pageNum += 1 %} {% elseif component.id == 'prev_page' and pageNum > 0 %} {% set pageNum -= 1 %} {% endif %} {# Requesting the page from the index, saving some if its data that will be used to calculate next page number #} {% set page = guild.indexes.balances.getPageOf(pageNum, 2, 'DESC') %} {% do parameters.store('page.number', page.number) %} {% do parameters.store('page.isLast', page.isLast) %} {% set isEmpty = page.totalPages <= 0 %} {% if not isEmpty -%} {# If we have any data in the index, show page content #} Page {{ page.number + 1 }} of {{ page.totalPages }} (total {{ page.totalElements }} entries) {% for entry in page %} {% set number = loop.index + page.number * page.size -%} {{ number }}. <@{{ entry.key }}>: {{ entry.value -}} {% endfor %} {%- else -%} No records {%- endif %} {# Show pagination buttons #} {% set pageLabel = (page.number + 1) ~ ' / ' ~ page.totalPages %} {% do button('PRIMARY', 'prev_page', null, '⬅️', actionId, isEmpty or page.isFirst) %} {% do button('SECONDARY', 'current_page', pageLabel, null, actionId, true) %} {% do button('PRIMARY', 'next_page', null, '➡️', actionId, isEmpty or page.isLast) %} {% endif %} ``` -------------------------------- ### Apply functions with {% filter lower | capitalize -%} Source: https://docs.juniper.bot/en/message-templates/advanced/tags Applies the 'lower' function then the 'capitalize' function to the content 'HELLO WORLD', producing 'Hello world'. The filter uses the body as the first argument to the specified function. ```JuniperBot Template {% filter lower | capitalize -%} HELLO WORLD {%- endfilter %} ``` -------------------------------- ### Pass parameters using the parameters store Source: https://docs.juniper.bot/en/message-templates/advanced/tags This alternative approach stores a parameter in the `parameters` store and then runs the child action. It achieves the same result as the `with` syntax. Actions may chain up to 3 times, and method quotas are shared across the chain. ```JuniperBot Template {% do parameters.store('param1', 123) %} {% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' %} ``` -------------------------------- ### iterable function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if an argument is iterable (a collection for loops or index/map selections). The example prints 'B' because 2 is not a map or list. ```JuniperBot Template {% if (iterable(2)) %}A{% else %}B{% endif %} ``` -------------------------------- ### startsWith Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if the first string argument starts with the second string argument. Accepts an optional third boolean parameter for case-insensitive comparison. ```APIDOC ## startsWith ### Description Checks if the first string argument starts with the second string argument. Accepts an optional third boolean parameter for case-insensitive comparison. ### Usage In JuniperBot message templates, use the syntax: `{{ startsWith(string, prefix, [caseInsensitive]) }}` ### Parameters - **string** (string) - Required - The string to check. - **prefix** (string) - Required - The prefix to look for. - **caseInsensitive** (boolean) - Optional - If true, the check is case-insensitive. ### Examples ``` {{ startsWith('hello', 'he') }} ``` Produces `true`. ``` {{ startsWith('HELLO', 'he', true) }} ``` Produces `true`. ``` -------------------------------- ### number function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if an argument is a number or available for automatic conversion to number according to Type Convert. The example prints 'A' because 2 is a number. ```JuniperBot Template {% if (number(2)) %}A{% else %}B{% endif %} ``` -------------------------------- ### odd function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if a number is odd. Returns 'true' when the number is odd, 'false' otherwise. The example prints 'B' because 2 is not odd. ```JuniperBot Template {% if (odd(2)) %}A{% else %}B{% endif %} ``` -------------------------------- ### Access data from parameters using get method Source: https://docs.juniper.bot/en/message-templates/persistence/parameters Use this construct to access data stored in parameters. The 'get' method retrieves the value associated with the given key. ```JuniperBot Template {{ parameters.get('example') }} ``` -------------------------------- ### Execute a macro like a function Source: https://docs.juniper.bot/en/message-templates/advanced/tags Defines a macro fullname that concatenates firstName and lastName, then executes it with arguments 'Elon' and 'Mask'. The result is the string built by rendering the macro template with the specified arguments. ```JuniperBot Template {% macro fullname(firstName, lastName) %} {{ firstName ~ ' ' ~ lastName }} {% endmacro %} {{ fullname('Elon', 'Mask') }} ``` -------------------------------- ### defined function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if an expression is defined. Returns 'true' if defined, 'false' otherwise. The example outputs 'NO' because index 5 of list [1, 2] is undefined. ```JuniperBot Template {% if (defined([1, 2][5])) %}YES{% else %}NO{% endif %} ``` -------------------------------- ### Clear a single guild index entry with clear() Source: https://docs.juniper.bot/en/message-templates/persistence/guild-indexes Clears the entry with key 'entryKey' from the index named 'myIndex'. Uses getIndex() to get the index, get() to retrieve the entry, and clear() to clear it. ```juniperbot-template {% do guild.getIndex('myIndex').get('entryKey').clear() %} ``` -------------------------------- ### empty function template example Source: https://docs.juniper.bot/en/message-templates/advanced/functions Checks if an input is empty: null, undefined, empty list, empty map, or zero number. The example produces 'B' because [1, 2] is not an empty list. ```JuniperBot Template {% if (empty([1, 2])) %}A{% else %}B{% endif %} ``` -------------------------------- ### calendar function with DateTime methods Source: https://docs.juniper.bot/en/message-templates/advanced/functions Shows how to use the DateTime instance returned by `calendar` to perform date arithmetic. The example creates a DateTime for the current date, adds 5 hours, and outputs both dates. The output shows two dates with a 5-hour difference. ```JuniperBot Template {% set currentDate = calendar('now', 'Europe/Moscow') %} {% set fiveHours = currentDate.plusHours(5) %} {{ currentDate }} {{ fiveHours }} ``` ```JuniperBot Template Tue, 22 Jun 2021 04:04:05 MSK Tue, 22 Jun 2021 09:04:05 MSK ``` -------------------------------- ### get(Position) Source: https://docs.juniper.bot/en/message-templates/types/custom-commands/arguments Returns argument by its position. ```APIDOC ## get(Position) ### Description Returns argument by its position. ### Method get ### Parameters - **Position** - The position of the argument to retrieve. ### Returns [String](https://docs.juniper.bot/en/message-templates/types/index#literals) ``` -------------------------------- ### Same As Test Expression - Same Reference Source: https://docs.juniper.bot/en/message-templates/advanced/expressions Example showing that when two variables reference the same object, 'same as' outputs 'true'. Here 'value' and 'other' point to the same number instance. ```JuniperBot Template {% set value = 1 %} {% set other = value %} {{ value is same as (other) }} ``` -------------------------------- ### range(Start, End) Source: https://docs.juniper.bot/en/message-templates/types/custom-commands/arguments Returns arguments from specified range. ```APIDOC ## range(Start, End) ### Description Returns arguments from specified range. ### Method range ### Parameters - **Start** - The starting position of the range. - **End** - The ending position of the range. ### Returns [String](https://docs.juniper.bot/en/message-templates/types/index#literals) ```