1 Access to Add and Sort Defined Values with Guardrails - pairs great with translation recipe Shared by Yeşu Chum, Houston's First Baptist Church 5 months ago 17.6 CRM, General Intermediate Defined Value Manager - Add and Sort Defined Values with Guardrails Give your staff a clean, safe UI to add, edit, and delete Defined Values without handing out admin access or running sort SQL by hand. One Lava Application, four endpoints, and a config file that lets you manage as many Defined Types as you want from the same code. What Does This Thing Do? It puts a searchable grid and a modal form on any staff page, wired to a Defined Type of your choosing. Staff manage the values; the app enforces the rules. Add, edit, and delete Defined Values from a friendly grid, no Admin Tools required Type-to-search filters the list as you type Deletes require typing yes delete, so nobody nukes a value by accident Re-sorts the Defined Type automatically after every save and delete (longest-first, A-Z, or Z-A, your pick) Attribute fields render from config: text, textarea, boolean, single-select, multi-select, and defined-value lookups One install manages many Defined Types; each one is just an entry in a config array Pairs Great with the Translation Recipe This is the companion piece to The Rosetta Stone - Translate anything. That recipe stores translation pairs in a Defined Type and needs them sorted longest-first; this one gives your staff a guarded UI for those pairs and handles the sort automatically on every save. No more re-running the sort SQL. And if you would rather skip maintaining pairs by hand entirely, my OmniLingua plugin on the Rock Shop does full page translation with less setup and better performance. How It Works The Moving Parts A Lava Application holds four shared endpoints: list, edit, save, delete. Configuration Rigging (a JSON blob on the application) describes each Defined Type you want to manage: labels, fields, sort behavior. A Lava Application Content block on any staff page renders the grid and picks which config entry to use via a cfgKey. HTMX handles the partial updates; the page never fully reloads. What Makes It Nice Adding another Defined Type later is a config entry and a content block; zero endpoint changes. Access is controlled by the application's security, not by Rock admin rights. The grid, modal, and forms use Rock's own styling, so it looks at home in your admin site, dark mode included. Sort logic runs server-side after every change, so the order is always right. Before You Start Lava Applications require Rock v17 or later. You'll also want a Defined Type to manage; if you're coming from the translation recipe, that's your Page Translation type and you're all set. The Setup in 4 Steps Work through these in order. Grab the attached files first; you'll paste one into each endpoint as you go. Step 1 - Create the Lava Application Go to Admin Tools > CMS Configuration > Lava Applications Create a new application: Name: Manage Defined Values Slug: manage-defined-values Active: checked Paste the contents of the attached ConfigurationRigging.json into the Configuration Rigging field. We'll customize it in Step 2. On the application's Security, grant Edit to the roles that should manage values. The endpoints all run in Application Edit mode, so this one security setting is the whole access story. Step 2 - Customize the Configuration Rigging The rigging is a Configs array; each object describes one Defined Type you want to manage. The content block picks an entry by its Key. Here's a minimal entry: { "Configs": [ { "Key": "spanish-translation", "DefinedTypeId": "123", "Title": "Page Translations", "Description": "Manage English-to-Spanish translations.", "ValueLabel": "Text to be Translated", "ValuePlaceholder": "Enter English text", "DescriptionDefault": "es", "ShowDescription": "false", "ShowActive": "true", "Sort": "length-desc", "Attributes": [ { "Key": "TranslatedText", "Label": "Spanish Translation", "Placeholder": "Enter Spanish translation", "Required": "true", "Type": "text" } ] } ] } Swap 123 for your Defined Type Id. The fields: Field What It Does Key Unique slug the content block uses to pick this config. DefinedTypeId The Defined Type this entry manages. Title / Description Heading and subheading shown above the grid. ValueLabel / ValuePlaceholder Label and placeholder for the Value field; always shown, always required. ShowDescription / DescriptionLabel "true" shows a Description field and column. When "false", DescriptionDefault is silently saved as the Description instead; the translation recipe uses this to stamp every pair with its language code. ShowActive "true" shows the Active toggle and column; "false" hides them and new values default to active. Sort How values re-order after every save and delete: length-desc (longest first, what the translation recipe needs), alpha-asc, alpha-desc, or none. Attributes One object per Defined Type attribute you want on the form. Key must exactly match the attribute key in Rock (case-sensitive). Type is one of text, textarea, boolean, single-select, multi-select, defined-value, defined-value-multi. Select types take an Options array of { "Value": "...", "Text": "..." }; defined-value types take a DefinedTypeId and query live values at render time. The attached rigging file includes a second example entry (a Schools list with a multi-select Grades attribute) so you can see a fuller shape. Delete what you don't need. Step 3 - Create the Four Endpoints Add four endpoints to the application, one per attached file. Same drill each time: set the name, slug, and settings from the table, then paste the matching file into the Code Template. Name Slug Method Security Mode Enabled Lava Commands File List list Get Application Edit Rock Entity ListEndpoint.lava Edit edit Get Application Edit Rock Entity EditEndpoint.lava Save save Get Application Edit Rock Entity, Rock Entity Modify, Sql SaveEndpoint.lava Delete delete Get Application Edit Rock Entity, Rock Entity Delete, Sql DeleteEndpoint.lava The Lava commands and Application Edit security mode are load-bearing; if an endpoint silently returns nothing, a missing command or a viewer without Edit rights on the application is the usual suspect. Step 4 - Add the Content Block Go to the staff page where you want the manager to live (an internal page your team already visits works great) Add a block of type Lava Application Content Point it at the Manage Defined Values application Paste the contents of the attached ContentBlock.lava into the template At the top of the paste, set the key to the config entry you want this page to manage: {% assign cfgKey = 'spanish-translation' %} That's the whole wiring. Want the same manager for a different Defined Type on another page? Add a config entry to the rigging, drop another content block, and change that one line. Using It Day to Day Once it's on the page, here's the whole workflow your staff needs to know. It's pretty straighforward it works like every other grid in Rock. To do this Do this Find a value Type in the search box above the grid. Rows filter as you type, across every column; clear the box to see everything again. Add a value Click the Add button in the panel header, fill in the form, click Save. Required fields are marked; the save won't go through without them. Edit a value Click the pencil on its row. The form opens pre-filled, including select and multi-select attributes; change what you need and click Save. Deactivate a value Edit it and uncheck Active. This is the gentle option; the value stays in the list (shown without the green check) and can be flipped back on later. Delete a value Click the trash icon, then type yes delete in the confirmation box and click Permanently Delete. Anything else typed in the box refuses to delete; that's the guardrail doing its job. Two things happen quietly on every save and delete, and they're the reason this beats editing the Defined Type directly: The sort runs itself. Whatever Sort your config entry specifies is re-applied to the whole Defined Type after each change. For translation pairs that means longest-first ordering is always correct and the "First Nombre" matching bug can't creep in, no SQL, no remembering. Hidden defaults are stamped. If the config hides the Description field, every value staff create still gets the configured default saved behind the scenes (the translation setup uses this to stamp es on every pair). Staff can't forget a field they never see. For the translation workflow specifically: when a ministry asks for a new phrase, staff search first to make sure it isn't already there, add the English text and its translation, and they're done. The page picks up the new pair on its next load. The only rule worth repeating from the translation recipe is to leave trailing periods out of the English text. Troubleshooting Grid loads but buttons do nothing, or the modal shows the wrong form. One of the endpoints is on an older paste than the others. These five files share element ids, so update all of them together, not just the one you changed. Endpoint returns nothing. Check the enabled Lava commands against the table in Step 3, and confirm the viewer has Edit on the application. Attribute fields come back empty. The Key in the rigging must match the attribute key on the Defined Type exactly, including case. Values save but land in the wrong order. Check the Sort setting on your config entry; none leaves Rock's manual ordering untouched. Delete refuses to run. That's the guardrail; the confirmation box needs yes delete typed into it. Changes don't show for other staff. Defined Values are cached; a browser refresh gets the new list, since the grid queries live on every load. That's It! Four steps and you've got a guarded Defined Value manager your staff can actually be trusted with. Hand them the page, keep your admin rights to yourself, and never re-run that sort SQL again.