AI Reading
Quick summary of this article
This tutorial explains how to build a custom Drupal 10 module called "Student Registration" that lets students register themselves from the frontend while giving administrators a backend interface to manage those records. The module includes a registration form, a student list view, and edit and delete functions, all protected by custom permissions. It's designed for educational organizations that want to handle student enrollments directly within Drupal.
- The module uses a standard Drupal file structure with configuration files (.info.yml, .routing.yml, .permissions.yml) and PHP classes for forms and controllers.
- Students can register by filling out a simple form with their name, email, and course, which is then saved to a custom database table.
- Administrators can view all registered students in a table format and can edit or delete individual records from the admin menu.
- Access is controlled through three custom permissions: "Access student list," "Edit student entry," and "Delete student entry."
- The tutorial suggests future enhancements like adding email notifications, validation rules, or CSV export functionality to extend the module.
Drupal 10 Student Registration Module: A Complete Tutorial
Introduction
In this comprehensive tutorial, we will walk you through creating a custom Drupal 10 module called Student Registration that allows users to register students from the frontend, while providing admin capabilities to view, edit, and delete those student records from the admin configuration menu. This module is ideal for universities, training institutes, or any educational organization looking to manage student enrollments directly on their Drupal site without relying on third-party systems.
The tutorial is designed to be beginner-friendly yet powerful enough for production use. We will explore how to build the form, define routes, assign permissions, build menu links under the configuration section, and create the database schema using a custom .install file. With this module, students can self-register, and site administrators will have a full backend interface to manage those entries efficiently.
Module File Structure
Your module folder should be structured like this:
student_registration/
├── student_registration.info.yml
├── student_registration.permissions.yml
├── student_registration.links.menu.yml
├── student_registration.routing.yml
├── student_registration.install
├── src/
│ ├── Controller/
│ │ └── StudentController.php
│ ├── Form/
│ ├── StudentRegistrationForm.php
│ └── StudentEditForm.php
Complete Source Code
student_registration.info.yml
name: 'Student Registration'
type: module
description: 'Allows users to register students and admins to manage them.'
core_version_requirement: ^10
package: Custom
version: 1.0
student_registration.permissions.yml
access student list:
title: 'Access student list'
description: 'Allow access to view student list.'
edit student entry:
title: 'Edit student entry'
description: 'Allow editing student entries.'
delete student entry:
title: 'Delete student entry'
description: 'Allow deleting student entries.'
student_registration.links.menu.yml
student_registration.admin:
title: 'Student Registration'
description: 'Manage student registrations.'
parent: system.admin_config_development
route_name: student_registration.list
weight: 100
permissions:
- 'access student list'
student_registration.routing.yml
student_registration.register:
path: '/student/register'
defaults:
_form: '\Drupal\student_registration\Form\StudentRegistrationForm'
_title: 'Register Student'
requirements:
_permission: 'access content'
student_registration.list:
path: '/admin/config/student-registration/list'
defaults:
_controller: '\Drupal\student_registration\Controller\StudentController::studentList'
_title: 'Student List'
requirements:
_permission: 'access student list'
student_registration.edit:
path: '/admin/config/student-registration/edit/{id}'
defaults:
_form: '\Drupal\student_registration\Form\StudentEditForm'
_title: 'Edit Student'
requirements:
_permission: 'edit student entry'
student_registration.delete:
path: '/admin/config/student-registration/delete/{id}'
defaults:
_controller: '\Drupal\student_registration\Controller\StudentController::deleteStudent'
_title: 'Delete Student'
requirements:
_permission: 'delete student entry'
src/Form/StudentRegistrationForm.php
<?php
namespace Drupal\student_registration\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
class StudentRegistrationForm extends FormBase {
public function getFormId() {
return 'student_registration_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['name'] = [
'#type' => 'textfield',
'#title' => 'Student Name',
'#required' => TRUE,
];
$form['email'] = [
'#type' => 'email',
'#title' => 'Email',
'#required' => TRUE,
];
$form['course'] = [
'#type' => 'textfield',
'#title' => 'Course Name',
'#required' => TRUE,
];
$form['submit'] = [
'#type' => 'submit',
'#value' => 'Register',
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$connection = Database::getConnection();
$connection->insert('student_registration')->fields([
'name' => $form_state->getValue('name'),
'email' => $form_state->getValue('email'),
'course' => $form_state->getValue('course'),
'created' => REQUEST_TIME,
])->execute();
\Drupal::messenger()->addMessage('Student Registered Successfully.');
}
}
src/Controller/StudentController.php
<?php
namespace Drupal\student_registration\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Link;
class StudentController extends ControllerBase {
public function studentList() {
$header = ['ID', 'Name', 'Email', 'Course', 'Operations'];
$rows = [];
$results = Database::getConnection()->select('student_registration', 's')
->fields('s', ['id', 'name', 'email', 'course'])
->execute();
foreach ($results as $row) {
$edit_url = Url::fromRoute('student_registration.edit', ['id' => $row->id]);
$delete_url = Url::fromRoute('student_registration.delete', ['id' => $row->id]);
$rows[] = [
$row->id,
$row->name,
$row->email,
$row->course,
[
'data' => [
'#markup' => Link::fromTextAndUrl('Edit', $edit_url)->toString() . ' | ' .
Link::fromTextAndUrl('Delete', $delete_url)->toString(),
],
],
];
}
return [
'#type' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => 'No students registered yet.',
];
}
public function deleteStudent($id) {
Database::getConnection()->delete('student_registration')
->condition('id', $id)
->execute();
\Drupal::messenger()->addMessage('Student deleted successfully.');
return $this->redirect('student_registration.list');
}
}
Further Improvement:
Module File Structure
student_registration/
├── student_registration.info.yml
├── student_registration.permissions.yml
├── student_registration.links.menu.yml
├── student_registration.routing.yml
├── student_registration.install
├── src/
│ ├── Controller/
│ │ └── StudentController.php
│ ├── Form/
│ │ ├── StudentRegistrationForm.php
│ │ ├── StudentEditForm.php
Complete Source Code
// student_registration.info.yml
name: 'Student Registration'
type: module
description: 'Allows users to register students and admins to manage them.'
core_version_requirement: ^10
package: Custom
version: 1.0
// student_registration.permissions.yml
access student list:
title: 'Access student list'
description: 'Allow access to view student list.'
edit student entry:
title: 'Edit student entry'
description: 'Allow editing student entries.'
delete student entry:
title: 'Delete student entry'
description: 'Allow deleting student entries.'
// student_registration.links.menu.yml
student_registration.admin:
title: 'Student Registrations'
description: 'Manage student registrations.'
parent: system.admin_content
route_name: student_registration.list
weight: 100
permissions:
- 'access student list'
// student_registration.routing.yml
student_registration.register:
path: '/student/register'
defaults:
_form: '\Drupal\student_registration\Form\StudentRegistrationForm'
_title: 'Register Student'
requirements:
_permission: 'access content'
student_registration.list:
path: '/admin/content/student-registration/list'
defaults:
_controller: '\Drupal\student_registration\Controller\StudentController::studentList'
_title: 'Student List'
requirements:
_permission: 'access student list'
student_registration.edit:
path: '/admin/content/student-registration/edit/{id}'
defaults:
_form: '\Drupal\student_registration\Form\StudentEditForm'
_title: 'Edit Student'
requirements:
_permission: 'edit student entry'
student_registration.delete:
path: '/admin/content/student-registration/delete/{id}'
defaults:
_controller: '\Drupal\student_registration\Controller\StudentController::deleteStudent'
_title: 'Delete Student'
requirements:
_permission: 'delete student entry'
// src/Form/StudentRegistrationForm.php
<?php
namespace Drupal\student_registration\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
class StudentRegistrationForm extends FormBase {
public function getFormId() {
return 'student_registration_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['name'] = [
'#type' => 'textfield',
'#title' => 'Student Name',
'#required' => TRUE,
];
$form['email'] = [
'#type' => 'email',
'#title' => 'Email',
'#required' => TRUE,
];
$form['course'] = [
'#type' => 'textfield',
'#title' => 'Course Name',
'#required' => TRUE,
];
$form['submit'] = [
'#type' => 'submit',
'#value' => 'Register',
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$connection = Database::getConnection();
$connection->insert('student_registration')->fields([
'name' => $form_state->getValue('name'),
'email' => $form_state->getValue('email'),
'course' => $form_state->getValue('course'),
'created' => REQUEST_TIME,
])->execute();
\Drupal::messenger()->addMessage('Student Registered Successfully.');
}
}
Conclusion
You now have a working Drupal 10 Student Registration module. Users can register via frontend forms, and admins can manage records through the backend. To access:
- Student List:
/admin/content/student-registration/list(requires permission ‘access student list’) - Register Student:
/student/register(frontend) - Edit Student:
/admin/content/student-registration/edit/{id} - Delete Student:
/admin/content/student-registration/delete/{id}
Next steps: Add email notifications, validation rules, or CSV export functionality for more advanced features.
Conclusion
You’ve now built a fully functional student registration system using Drupal 10. From frontend form submissions to admin backend controls for listing, editing, and deleting entries, this tutorial covered the complete process. You also learned how to integrate your module into Drupal’s configuration menu, apply proper permission controls, and use Drupal’s Form API and routing system.
Next steps: consider expanding the module with email notifications, validation rules, or exporting student data as CSV. Drupal offers limitless possibilities, and this foundational module is a great starting point for deeper development.
Downloads from GitHub
