Le CLAPE (formerly APEC) — Course Enrollment Platform
A custom e-commerce platform for the French international school community in Rome. Built a WordPress/WooCommerce solution enabling parents to register, manage children profiles, and enroll in after-school activities with real-time availability tracking. Delivered bilingual French/Italian support and handled high-concurrency enrollment periods over 5+ years of active development.
Project Overview
Client: APEC – Association des Parents d’Élèves du Lycée Chateaubriand (Rome, Italy)
Website: www.atelierschateau.it
Project Duration: January 2014 – September 2019 (5+ years of active development and maintenance)
My Role: Frontend Developer
Team:
- Lushano Perera – Frontend Development (512 commits)
- Carlo Cifarelli – Backend Development (414 commits)
The Challenge
The Association des Parents d’Élèves du Lycée Chateaubriand, a parents’ association connected to the prestigious French international school Lycée Chateaubriand in Rome, needed a comprehensive digital platform to manage:
- Parent registration and authentication
- Children profile management
- After-school activities enrollment
- Course booking with limited availability
- Online payments
- Bilingual support (French and Italian)
The platform had to handle high-concurrency scenarios during enrollment periods, where hundreds of parents compete for limited course spots simultaneously.
The Solution
We developed a fully custom WordPress-based platform with WooCommerce integration, featuring a real-time stock management system for course enrollment and a sophisticated user management system.
Key Features Delivered
- User Registration & Authentication System
- Custom login flow with session management
- Automatic parent profile creation upon registration
- Login status tracking to prevent concurrent sessions
- Child Management Interface
- Parents can add, edit, and manage multiple children profiles
- Custom fields for school information, medical notes, emergency contacts
- Real-time Course Enrollment System
- Live availability tracking
- Cart reservation with 20-minute expiration timer
- Prevention of double-booking through slot validation
- E-commerce Integration
- WooCommerce-powered checkout
- Multiple payment methods (PayPal, bank transfer, check)
- Order status tracking and notifications
- Admin Control Panel
- Toggle switches for registration, validation, shop, and profile access
- Real-time control without code deployment
- Comprehensive reporting system
- Multilingual Support
- Full French/Italian translation via WPML
- Language switcher with flag indicators
Technology Stack
Frontend (My Focus)
| Technology | Purpose |
|---|---|
| HTML5/CSS3 | Semantic markup, responsive styling |
| jQuery 1.10 | DOM manipulation, AJAX interactions |
| Cycle2 | Homepage slider and activity carousels |
| Fancybox | Image galleries and modal windows |
| Switchery | iOS-style toggle switches for admin controls |
| Superfish | Accessible dropdown navigation menus |
| jsPDF | Client-side PDF generation for reports |
| Font Awesome | Icon library |
| Modernizr | Feature detection for progressive enhancement |
Backend (Developed by Carlo Cifarelli)
| Technology | Purpose |
|---|---|
| WordPress | Content management system |
| PHP 5.6 | Server-side logic |
| MySQL | Database |
| Redis | Object caching for performance |
| WooCommerce | E-commerce engine |
| WPML | Multilingual content management |
| Toolset Types | Custom post types and fields |
DevOps & Infrastructure
| Technology | Purpose |
|---|---|
| Docker | Local development environment |
| GitLab CI/CD | Automated deployment pipeline |
| Nginx | Web server |
| LFTP | FTP-based deployment |
Frontend Development Highlights
Custom Theme Architecture
I built a completely custom WordPress theme from scratch, based on HTML5 Boilerplate/Initializr best practices. The theme follows a modular structure with separated concerns:
apec-theme/
├── css/
│ ├── main.css # Primary stylesheet (~4000 lines)
│ ├── normalize.css # CSS reset
│ └── print.css # Print-optimized styles
├── js/
│ ├── main.js # Core functionality
│ ├── init.js # Initialization scripts
│ └── vendor/ # Third-party libraries
├── fonts/ # Custom Museo Slab webfonts
└── inc/ # PHP includes (modular functions)
Responsive Navigation System
Implemented a multi-level navigation system with Superfish for accessibility:
jQuery(document).ready(function() {
jQuery('ul.menu .sub-menu').hide();
// Show relevant submenu based on current page
jQuery('.current-menu-item .sub-menu, ' +
'.current-page-ancestor .sub-menu, ' +
'.current-menu-parent .sub-menu').show();
});
Real-time Admin Controls
Created an intuitive admin control panel using Switchery toggles that communicate with the backend via AJAX:
var input_controllo_vendita = document.querySelector('#input_controllo_vendita');
var controllo_vendita_switchery = new Switchery(input_controllo_vendita, {
color: '#00bf12',
secondaryColor: '#fb2a2a'
});
input_controllo_vendita.onchange = function() {
jQuery(".overlay").show();
jQuery.post(ajaxurl, {
'action': 'abilita_acquisti',
'checked': input_controllo_vendita.checked
}, function(response) {
jQuery(".overlay").hide();
alert(response);
location.reload();
});
};
Loading Overlay System
Implemented a loading overlay to improve UX during AJAX operations:
<div class="overlay" style="display: none;">
<div>Chargement...</div>
</div>
jQuery(".cred-form").submit(function(event) {
jQuery(".overlay").show();
jQuery(".js-wpt-field-items .wpt-form-error:visible").onAvailable(function() {
jQuery(".overlay").hide();
});
});
Image Gallery with Fancybox
Built dynamic gallery functionality that automatically groups images and pulls captions:
jQuery('section.gallery figure a').each(function() {
var title = jQuery(this).parent('figure').find('.caption').text();
jQuery(this).attr('title', title);
});
jQuery('section.gallery').each(function() {
var gallery_id = jQuery(this).attr('id');
jQuery(this).children('div').children('figure').each(function() {
jQuery(this).find('a').attr('rel', gallery_id);
});
});
jQuery('section.gallery a').fancybox();
Form Validation & UX Enhancements
Implemented real-time form field formatting:
// Auto-uppercase surnames
jQuery("input[name='wpcf-cognome']").keyup(function() {
jQuery(this).val(jQuery(this).val().toUpperCase());
});
// Capitalize first letters of names
jQuery("input[name='wpcf-nome']").keyup(function() {
jQuery(this).val(jQuery(this).val().capitalise());
});
// Lowercase emails
jQuery("input[name='wpcf-email']").keyup(function() {
jQuery(this).val(jQuery(this).val().toLowerCase());
});
Custom String Capitalization Prototype
String.prototype.capitalise = function() {
var text = this,
split = text.split(" "),
res = [],
i, len, component;
for (i = 0, len = split.length; i < len; i++) {
component = split[i];
res.push(component.substring(0, 1).toUpperCase());
res.push(component.substring(1));
if (len > 1 && i < len - 1) {
res.push(" ");
}
}
return res.join("");
};
CSS Architecture
Custom Typography with Web Fonts
@font-face {
font-family: 'museo-slab-500';
src: url('../fonts/museo_slab_700-webfont.eot');
src: url('../fonts/museo_slab_700-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/museo_slab_700-webfont.woff') format('woff'),
url('../fonts/museo_slab_700-webfont.ttf') format('truetype'),
url('../fonts/museo_slab_700-webfont.svg#museo_slab700') format('svg');
font-weight: normal;
font-style: normal;
}
Header Bar with Admin Controls
#top {
width: 100%;
float: left;
height: 34px;
background: #2b2b2b;
color: #ffffff;
border-bottom: 3px solid #fcb040;
font-size: 1.2em;
}
#top .flex {
display: flex;
align-items: center;
justify-content: space-between;
}
Language Switcher with Flag Icons
#top ul#langs li.fr.active a {
background: url(../img/flag_fr_active.png) no-repeat;
}
#top ul#langs li.fr a {
background: url(../img/flag_fr.png) no-repeat;
}
#top ul#langs li a {
display: block;
width: 22px;
height: 14px;
float: left;
text-indent: -999em;
}
Timer/Notification Banner
#timer {
width: 100%;
float: left;
background: #7DBE74;
color: #ffffff;
}
#timer p {
margin: 0 35px;
padding: 10px 0;
font-weight: bold;
font-size: 2em;
text-align: center;
}
#timer p span {
color: #fcb040;
}
Performance Optimizations
CDN with Fallback Pattern
Implemented smart resource loading with local fallback:
function load_theme_scripts() {
wp_deregister_script('jquery');
$url = 'https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js';
if (urlOK($url)) {
wp_register_script('jquery',
'//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js',
false, '1.10.1', true);
} else {
wp_register_script('jquery',
get_template_directory_uri() . '/js/vendor/jquery-1.10.1.min.js',
__FILE__, '1.10.1', true);
}
wp_enqueue_script('jquery');
}
DNS Prefetching
<link rel="dns-prefetch" href="//ajax.googleapis.com" />
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
<link rel="dns-prefetch" href="//fonts.gstatic.com" />
<link rel="dns-prefetch" href="//www.google-analytics.com" />
Asset Versioning for Cache Busting
wp_register_style('main',
get_template_directory_uri() . '/css/main.css',
array('normalize'),
'1.91', // Version number for cache busting
'screen'
);
Challenges & Solutions
Challenge 1: High-Concurrency Course Enrollment
Problem: During enrollment periods, hundreds of parents tried to book limited course spots simultaneously, causing race conditions.
Solution: Implemented a cart reservation system with a 20-minute timer. Items are temporarily “locked” in a user’s cart, preventing double-booking while giving users time to complete checkout.
Challenge 2: Bilingual Content Management
Problem: All content needed to be available in both French and Italian, with seamless language switching.
Solution: Integrated WPML for full multilingual support, with custom language switcher in the header using flag icons.
Challenge 3: Complex User Roles
Problem: Different user types (parents, teachers, administrators) needed different access levels and features.
Solution: Custom role-based access control with WordPress capabilities system, plus special username whitelist for administrative features.
Results & Impact
- 5+ years of continuous operation serving the school community
- 900+ commits representing ongoing improvements and feature additions
- Successfully handled seasonal enrollment rushes with high concurrent users
- Zero downtime during critical enrollment periods
- Smooth rebranding transition from APEC to Le CLAPE in 2019
Lessons Learned
- WordPress can scale: With proper caching (Redis) and optimized queries, WordPress handles high-traffic scenarios effectively.
- User experience matters: Small UX touches like loading overlays, real-time field formatting, and clear error messages significantly improve user satisfaction.
- Plan for concurrency: Any booking/reservation system needs to handle race conditions from the start.
- Modular code pays off: Separating frontend logic into focused files (init.js, main.js, validation.js) made maintenance much easier over 5+ years.
Technologies Used (Summary)
Frontend: HTML5, CSS3, jQuery, Cycle2, Fancybox, Superfish, Switchery, jsPDF, Modernizr, Font Awesome
Backend: WordPress, PHP, MySQL, Redis, WooCommerce, WPML, Toolset Types
DevOps: Docker, GitLab CI/CD, Nginx