Rock RMS Developer · Houston's First Baptist Church

Building tools for
Rock that I actually like.

Plugins, recipes, and notes from the attic of church management software. Made by someone who started with a label printer that wouldn't behave.
01 plugin shipped
09 recipes published
03 posts written
// plugins
Things I've shipped
view all →
i18n
Rosetta Stone
Full page translation for Rock. OWIN middleware handles the server-side paint, a JS engine handles live switching, and a Lava filter covers emails and templates.
···
More coming
Got ideas. Not enough hours in the day. Probably a few more late nights away.
// recent recipes
From the cookbook
view all →
i18n
The Rosetta Stone
Translate any Rock page into another language via Lava shortcode and a Defined Type. The recipe that became the plugin.
pet
Chip Cursor Pet
Chip follows your cursor around Rock admin. Completely unnecessary. Absolutely worth it.
sql
SQL Model Map
A QoL reference for navigating Rock's data model without losing your mind. Keep this one bookmarked.
// blog
Field notes
view all →
01
From check-in to C#
Worked in children's ministry. Moved to membership. Eight hours fighting a ZPL label, one week sucked into Rock, and one Rock Star meeting I should not have been in.
02
The point system is a trap
I answered one question on the Rock community. Then I refreshed my profile at 11pm on a Tuesday.
03
My first plugin nearly broke me
Three nights past midnight, one very confused service container, and a lesson I will not forget.
plugins

Rock RMS Plugins

Open source plugins for the Rock ChMS ecosystem. More in the pipeline.
1 plugin
i18n
coming soon
Rosetta Stone
Full visitor-facing page translation for Rock RMS. Admins enter source and translated text pairs through the Rock UI, drop a language toggle on any public page, and visitors switch languages with one click. No code changes, no theme edits, no Defined Types to manage.

Three coordinated layers: OWIN middleware handles the server-side initial paint so there is no flash of English before Spanish. A MutationObserver-based JS engine handles live switching and Obsidian-rendered content without a page reload. A | Translate:'es' Lava filter covers emails, communication templates, and any custom Lava blocks where you want explicit opt-in translation.

Translation pairs support case-insensitive matching with case preservation, typography tolerance for smart quotes and non-breaking spaces, and per-pair conditions scoped to campus, authenticated state, time windows, or a full Lava expression. CSV import and export so translators can work in a spreadsheet.
web C# TypeScript OWIN Lava Obsidian
···
soon
Something else
Working on it. Check back when it's ready.
recipes

Rock RMS Recipes

Patterns, snippets, and the occasional bit of chaos. All live on the Rock community.
9 recipes
lava intermediate
The Rosetta Stone — Translate anything
Client-side page translation using a Lava shortcode and a Defined Type. Point it at a language, maintain your pairs in Rock, watch the page swap. Staff manages it without touching code.
fun beginner
Chip Cursor Pet
A tiny Chip mascot that follows your cursor around Rock admin. Impractical. Delightful. Kids in your office will ask why admin has a pet.
reference all levels
SQL Model Map
The table relationships and key columns you keep looking up, in one place. A QoL reference for navigating Rock's data model without losing your mind.
fun beginner
Chip's Check-In Chaos
A chaotic, fun check-in screen experience. Because check-in Sunday doesn't have to be boring for the people running it either.
qol intermediate
Security Management, Data Integrity and QoL
A collection of Rock admin improvements around security, data integrity, and the things that make your daily life easier to manage.
lava beginner
Countdown Timer Shortcode
Drop a countdown timer anywhere on your Rock site with a shortcode. Event pages, giving campaigns, registration deadlines. One tag, done.
qol intermediate
Group Viewer — Meeting Details Accordion
Locations, schedules, links — all tucked into a clean accordion for your group finder pages. Makes meeting details readable instead of a wall of text.
lava beginner
Calculate Time Duration
Show a human-readable duration like "2 hrs 30 min" from your event start and end times. A small thing that makes event pages feel a lot more polished.
fun beginner
All-Seeing Chip
Chip's eyes track your cursor. That's the recipe. It started the whole Chip cursor era and is responsible for the others. You're welcome, or sorry.
blog

Thoughts & Findings

No editorial calendar. Just things worth writing down from the Rock trenches.
3 posts
story Apr 2025
From check-in to C#: how I became a Rock developer
I worked in children's ministry, moved to membership, and broke a label template. The thing that changed everything wasn't Rock itself — it was eight hours of ZPL, a week of getting sucked in, and one Rock Star meeting I accidentally crashed at RX.
musings Mar 2025
The Rock community point system is a trap (a good one)
I answered one question. Then another. Then I checked my profile at 11pm on a Tuesday to see if my points had gone up. They had. By two. I was unreasonably pleased about this.
findings Feb 2025
Building my first Rock plugin nearly broke me (and I'd do it again)
Three nights past midnight, one very confused service container, and a mutual understanding with Visual Studio that we don't have to like each other. This is that story.
plugins / rosetta-stone / v1.0.0 / user guide
/ blog
story 5 min read

From check-in to C#: how I became a Rock developer

I worked in children's ministry. Not as a developer. Not even close. My entire relationship with Rock RMS at the time was knowing which buttons to press on check-in Sunday so the right label printed and the right kid went home with the right family. That was the job. That was the whole thing.

I was good at it. Showed up early, kept the line moving, didn't panic when the printer jammed. Very normal staff stuff.

The label incident

Then I moved over to the membership department, and Rock stopped being a check-in screen and started being everything. Every workflow we touched, every report we ran, every list we pulled — Rock. So I started spending more time in it.

Somewhere in that transition I made a mistake with a label template. I don't remember the exact details of what I changed, but the result was labels printing wrong — wrong layout, wrong fields in the wrong places. Something was off in the ZPL and I had caused it.

The sensible thing would have been to flag it and let someone else fix it. I did not do the sensible thing. I decided I was going to fix it myself.

I knew nothing about ZPL. I had never heard of ZPL. ZPL is the programming language Zebra label printers use, and it is not something you just pick up in an afternoon. But I sat down with it anyway, started reading, started trying things. Most of them didn't work. I tried more things. Eight hours later I had fixed the label.

Eight hours. For a label template. I was not going to let it beat me.

That's the thing about those moments — you don't realize they're turning points while they're happening. You just think you're being stubborn about a printer problem.

One week, fully sucked in

What those eight hours actually taught me had nothing to do with ZPL. The point was that I discovered something about how I work: I will chase an "aha" moment for an unreasonable amount of time, and it doesn't feel like work. It feels like a puzzle. Something that can be solved if I just keep going.

That was on a Monday. By the following Monday I had read the entire Rock admin hero guide, watched every Master Class video I could find, mapped half of the data model in my head, and was writing my first Lava templates. I have no other way to describe that week except that I got sucked in. Every time I learned one thing, three other things I didn't know about poked their heads up to be learned next.

Master Class lit the fire. I had no business going that deep that fast — I wasn't even on the IT team — but the way the material was structured made the whole stack feel knowable instead of intimidating. Lava, then SQL, then workflow actions, then Pre-HTML, then theme zones, then check-in configuration. I was making notes in margins. I was running test queries against a sandbox at midnight.

Accidentally crashing a Rock Star meeting

Then I went to RX. If you don't know what RX is — it's the annual Rock conference, the gathering of everyone who builds on or works in Rock. I went the first year I was eligible, mostly to soak it in.

And I ended up in a Rock Star meeting by accident.

I want to be transparent: I did not know it was a Rock Star meeting. I walked in. The door was open. People were sitting around. I sat down. And then I realized everyone in the room had earned the Rock Star title and I had not.

The polite thing would have been to slip out. I did try. I made what I think was a reasonable effort to leave and was, very kindly, told to stay. So I stayed.

What I heard in that room was an entire room of people who had built things in Rock that I didn't even know were possible. Plugins, integrations, gnarly migrations, custom blocks, crazy theme work. They were trading war stories and asking each other for help on problems I couldn't yet describe, let alone solve.

I left that meeting with one thought: I'm coming back next year and I'm earning that title for real.

What I learned the year after

Reader, I earned it.

The year between that accidentally-crashed meeting and the next RX was the most concentrated year of learning I've ever had. Started writing real Lava. Wrote my first SQL reports that actually held up. Started contributing recipes to the community. Got into Obsidian. Built things. Broke things. Fixed the things I broke. The Rock community point system kicked in around month three and that's a whole other post.

The gap between "power user" and "developer" is smaller than it looks from the outside. Rock is a good place to close that gap because you can do genuinely useful things at every level — Lava templates, SQL reports, workflow actions — before you ever have to write a line of C#. By the time I started on actual plugins, I already understood enough of the system that the C# wasn't the scary part. The scary part was deploying to production on a Sunday morning. Still is, if I'm honest.

No CS degree. No formal background. Just a label that printed wrong, a week of getting sucked in, a meeting I shouldn't have walked into, and enough late nights to eventually figure out what I was doing. Stubbornness dressed up as curiosity. It's served me pretty well.

/ blog
musings 4 min read

The Rock community point system is a trap (a good one)

I'm going to be transparent about something: I refreshed my Rock community profile at 11pm on a Tuesday to see if my points had gone up.

They had. By two. I was unreasonably pleased about this.

How it starts

The Rock community has a point system. You answer questions, share recipes, people like your contributions, you get points. Simple. And it is extremely effective at making you want more points.

I answered my first question because I actually knew the answer and thought I'd help. Reasonable, healthy motivation. Then I watched the notification appear. Then I checked whether anyone had upvoted it. Then I found another question I could answer while I was already there anyway, just because.

This is how it begins.

For the record: I have full awareness that I'm being lightly gamified. This does not stop it from working. Whoever designed this system understood something real about human psychology.

The thing is, it actually makes you better

Here's what I didn't expect: the point-chasing is mostly a red herring. The actual effect of answering questions on the Rock community is that you get really good at Rock.

When someone asks a question you don't fully know the answer to, you have two choices — move on, or figure it out. The points provide just enough silly motivation to push you toward figuring it out. And then you know something you didn't before. Then someone replies with a better approach and now you know two things. It compounds.

I've learned more from trying to write a clear answer to someone else's Lava question than I have from most formal documentation. You have to understand something well enough to explain it, which is a higher bar than just understanding it yourself. The points get you in the door. The learning is the actual reward.

The community is the real thing

The points are not actually why I keep coming back. The community is just good. People are generous with their knowledge, the tone is helpful rather than gatekeep-y, and there's a shared understanding that everyone is working toward the same general goal — churches running well, staff not losing their minds, ministry actually happening.

That shared purpose makes it feel different from a lot of tech spaces. Nobody is posturing. Nobody makes you feel bad for asking a beginner question. Everyone was a beginner at Rock once and most people seem to remember that.

The points are fun. The community is the real thing. The points just got me in the door fast enough to realize that.

(My current total is none of your business.)

/ blog
findings 6 min read

Building my first Rock plugin nearly broke me (and I'd do it again)

There were three separate nights where I was still at my computer past 3am, staring at an exception I didn't understand, wondering what I had done to deserve this.

This is the story of building the Rosetta Stone plugin — a tool that lets churches translate any Rock page into another language. It was the most frustrating thing I'd built in Rock so far, and also the most satisfying. Writing it down while the details are still fresh.

Why I built it

We have Spanish-speaking families at our church who interact with Rock through public-facing pages — event registrations, group sign-ups, giving forms. All of it was in English. There was no clean built-in way to serve them in their language.

I'd already built the recipe version, which uses a Lava shortcode and a Defined Type to do client-side text swapping. It works, and it's on the Rock community if you want it now. But I wanted something cleaner. OWIN middleware for the server-side paint. A proper JS engine for live switching. A real admin UI instead of copy-pasting Pre-HTML on every registration page.

So I started down that road.

What I underestimated

The service container. Rock uses dependency injection throughout, and if you get the lifetime of a service wrong — say, you inject a scoped service into a singleton — you get an exception that tells you nothing useful on the surface. I spent the better part of an evening convinced my code was correct before I found a Stack Overflow post from 2019 that put the pieces together.

It was 1:30am. I read that post three times. Fixed one line. Rebuilt. It worked. I sat back and stared at the ceiling for a minute.

If you are hitting cryptic DI exceptions in Rock plugins: check your service lifetimes first. Scoped inside singleton equals a bad time. I say this as someone who lost significant sleep to this exact lesson.

The 3am problem

There's a version of late-night coding that's actually productive. You're in flow, things are clicking, the world is quiet and you're just building. I had sessions like that.

Then there's the other kind, where you've been staring at the same bug for two hours, your brain stopped being useful an hour ago, and you keep trying variations of the same wrong approach hoping one of them will magically work. I had sessions like that too.

The honest lesson: the second kind is the problem. The first kind is fine — if you're productive late, go for it. But the moment you catch yourself copy-pasting the same broken code with slightly different spacing, close the laptop. I didn't always listen to that cue.

Every fix I found after sleeping was obvious. Every single one. Not one of them required me to be awake past midnight. I just had to not know that yet.

What I loved about it

All of that said — the frustration was real but so was the satisfaction on the other side. The first time I loaded a registration page and watched every English label flip to Spanish in real time, correctly, without any visible delay — that was a genuinely great moment.

Building a plugin forces you to understand Rock at a different level than recipes or Lava ever will. You're inside the framework. You're looking at how blocks work, how the service layer is structured, how OWIN middleware intercepts responses. That context makes you better at everything else in Rock, even the surface-level stuff.

The plugin isn't live yet — still polishing before the public release. When it drops, it'll be worth the sleep debt. Probably.

↑ ↑ ↓ ↓ ← → ← → B A

You found the Konami code. There's no prize, but I respect the dedication.

Try console.log'ing this site too. There's something there.