Comfestus
A membership website that survives a new board every twelve months, built on one custom plugin instead of four paid ones.
Context
Comfestus runs monthly events, workshops and company visits for its members. Like every student association, its board changes every academic year, so the people maintaining the website are new, non-technical, and gone again in twelve months.
The problem
They needed a site with paid yearly membership, event registration limited to paying members, member-only photo albums and a merch webshop. The obvious route is three or four paid plugins glued together, which is expensive, fragile, and impossible to hand over.
What I did
- Built membership on WooCommerce instead of a membership plugin. Each academic year’s membership is simply a virtual product. A custom settings screen marks which product is “current,” and every member-only feature checks against a paid order for it. No subscriptions, no licences, no plugin conflicts.
- Wrote a custom plugin, Comfestus Core, to handle access control: event registration and locked photo albums check membership status and redirect non-members to the Join page. Members can cancel their own registration up to seven days before an event.
- Set up self-updating content. A published news post appears on the News page and the homepage. A new event appears on the Agenda and in “Upcoming events.” An album lands on the Photos page. Category filters build themselves. The board never edits a layout.
- Added a live member list under Tools → Comfestus leden, with CSV export for the board’s records, and a bookings view showing who signed up for each event.
- Configured the webshop with size variations for clothing and local pickup only, so there is no shipping logic they’d have to maintain.
- Wrote a handover guide for the board, so next year’s committee can run the site without calling me.
Technical detail: membership is derived, not stored
The interesting decision here was refusing the plugin stack. A person is a member if they have a paid WooCommerce order containing the product currently flagged as active. That means the yearly rollover is a two-minute job. You create next year’s product and select it in settings, and there is no member database to drift out of sync with reality.
function comfestus_is_member( $user_id ) {
$product_id = (int) get_option( 'comfestus_current_membership' );
return (bool) wc_get_orders( array(
'customer_id' => $user_id,
'status' => array( 'wc-completed', 'wc-processing' ),
'limit' => 1,
'return' => 'ids',
'product_id' => $product_id,
) );
}
Outcome
The board adds content; the site arranges itself. Annual rollover takes minutes, there is no recurring membership-plugin cost, and the handover documentation means the site survives a change of board.