Nikola Georgijev
Book a 20-min call

Comfestus

A membership website that survives a new board every twelve months, built on one custom plugin instead of four paid ones.

Industry
Student association, Hogeschool Utrecht
Role
Design implementation, custom WordPress development
[Hero screenshot — Comfestus]
1 custom plugin replacing a paid membership stack
4 content types the board manages themselves
€0 recurring licence cost for membership

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.

Stack
WordPress Elementor WooCommerce Custom PHP plugin ACF