How it works
The wall above is one page and two endpoints. The endpoints and settings below are pulled live from Rock, so they’re exactly the code that’s running right now.
The page Lava Application Content block
Draws the wall, then asks the requests endpoint for cards as soon as it loads.
<div class="prayer-wall">
<h2>{{ ConfigurationRigging.Title }}</h2>
<div id="wall"
hx-get="^/prayer-wall/requests"
hx-trigger="load">
Loading prayer requests…
</div>
</div>
The styling CSS at the top of the page block
A starting point. Everything is scoped to .prayer-wall, so it won’t touch the rest of your site. Change the colors to match your church’s brand.
<style>
.prayer-wall {
background: #f6f4ef;
color: #1c1b19;
border-radius: 20px;
padding: 32px;
margin: 24px 0 40px;
}
.prayer-wall h2 {
margin: 0 0 24px;
font-weight: 500;
color: #1c1b19;
}
.prayer-wall #wall {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 20px;
}
.prayer-wall .prayer-card {
display: flex;
flex-direction: column;
gap: 12px;
background: #fdfcf9;
border: 1px solid #e2ded4;
border-radius: 16px;
padding: 24px;
}
.prayer-wall .prayer-card h4 {
margin: 0;
font-size: 20px;
font-weight: 700;
color: #1c1b19;
}
.prayer-wall .prayer-card p {
margin: 0;
line-height: 1.5;
color: #4a4741;
}
.prayer-wall .prayer-card button {
margin-top: auto; /* lines the buttons up along the bottom of each row */
align-self: flex-start;
border: 0;
border-radius: 999px;
padding: 8px 18px;
background: #1f6fbf;
color: #fdfcf9;
font-size: 15px;
font-weight: 700;
cursor: pointer;
}
.prayer-wall .prayer-card button:hover { background: #185a9c; }
.prayer-wall .prayer-card button:focus-visible { outline: 3px solid #9cc3ea; outline-offset: 2px; }
.prayer-wall .prayer-card button.htmx-request { opacity: .6; cursor: wait; } /* while the click is saving */
.prayer-wall .prayer-card button[disabled] { /* the "Prayed" button */
background: #e3edf8;
color: #1a5da3;
cursor: default;
}
@media (max-width: 600px) {
.prayer-wall { padding: 20px; }
}
</style>
Configuration Rigging set once on the app
{
"Title": "Pray With Us",
"PageSize": 12,
"CategoryId": 1866
}
Requests GET /requests
Security: Application view · Lava commands: RockEntity
{% assign size = ConfigurationRigging.PageSize | AsInteger %}
{% assign page = QueryString.page | AsInteger | Default:1 | AtLeast:1 | AtMost:1000 %}
{% assign skip = page | Minus:1 | Times:size %}
{% prayerrequest where:'IsApproved == true
&& IsActive == true && IsPublic == true && CategoryId == {{ ConfigurationRigging.CategoryId }}'
sort:'EnteredDateTime desc'
limit:'{{ size }}' offset:'{{ skip }}' %}
{% for r in prayerrequestItems %}
<div class="prayer-card">
<h4>{{ r.FirstName | Escape }}</h4>
<p>{{ r.Text | Escape }}</p>
<button hx-post="^/prayer-wall/pray"
hx-vals='{"id": {{ r.Id }}}'
hx-swap="outerHTML">
I prayed · {{ r.PrayerCount | Default:0 }}
</button>
</div>
{% endfor %}
{% endprayerrequest %}
Pray POST /pray
Security: Application edit · Lava commands: RockEntity, RockEntityModify
{% assign categoryId = ConfigurationRigging.CategoryId | AsInteger | Default:0 %}
{% assign id = Form.id | AsInteger | Default:0 %}
{% prayerrequest where:'Id == {{ id }}
&& IsApproved == true && IsActive == true
&& CategoryId == {{ categoryId }}
&& IsPublic == true' %}
{% for r in prayerrequestItems %}
{% assign count = r.PrayerCount | Default:0 | Plus:1 %}
{% modifyprayerrequest id:'{{ r.Id }}'
securityenabled:'false' %}
[[ property name:'PrayerCount' ]]
{{ count }}
[[ endproperty ]]
<button class="prayed" disabled>
Prayed · {{ count }}
</button>
{% endmodifyprayerrequest %}
{% endfor %}
{% endprayerrequest %}
Questions? Find David Axelson on Rocket.Chat at david.axelson.