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’);
}
}
// src/Form/StudentEditForm.php
<?php
namespace Drupal\student_registration\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Symfony\Component\HttpFoundation\RedirectResponse;
class StudentEditForm extends FormBase {
protected $id;
public function getFormId() {
return ‘student_edit_form’;
}
public function buildForm(array $form, FormStateInterface $form_state, $id = NULL) {
$this->id = $id;
$record = Database::getConnection()->select(‘student_registration’, ‘s’)
->fields(‘s’)
->condition(‘id’, $id)
->execute()->fetchObject();
$form[‘name’] = [
‘#type’ => ‘textfield’,
‘#title’ => ‘Student Name’,
‘#default_value’ => $record->name,
‘#required’ => TRUE,
];
$form[’email’] = [
‘#type’ => ’email’,
‘#title’ => ‘Email’,
‘#default_value’ => $record->email,
‘#required’ => TRUE,
];
$form[‘course’] = [
‘#type’ => ‘textfield’,
‘#title’ => ‘Course Name’,
‘#default_value’ => $record->course,
‘#required’ => TRUE,
];
$form[‘submit’] = [
‘#type’ => ‘submit’,
‘#value’ => ‘Update’,
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
Database::getConnection()->update(‘student_registration’)
->fields([
‘name’ => $form_state->getValue(‘name’),
’email’ => $form_state->getValue(’email’),
‘course’ => $form_state->getValue(‘course’),
])
->condition(‘id’, $this->id)
->execute();
\Drupal::messenger()->addMessage(‘Student record updated.’);
$response = new RedirectResponse(‘/admin/config/student-registration/list’);
$response->send();
}
}
// student_registration.install
<?php
function student_registration_install() {
$schema = [
‘description’ => ‘Stores student registration entries.’,
‘fields’ => [
‘id’ => [
‘type’ => ‘serial’,
‘not null’ => TRUE,
],
‘name’ => [
‘type’ => ‘varchar’,
‘length’ => 255,
‘not null’ => TRUE,
],
’email’ => [
‘type’ => ‘varchar’,
‘length’ => 255,
‘not null’ => TRUE,
],
‘course’ => [
‘type’ => ‘varchar’,
‘length’ => 255,
‘not null’ => TRUE,
],
‘created’ => [
‘type’ => ‘int’,
‘not null’ => TRUE,
‘description’ => ‘Timestamp when record was created.’,
],
],
‘primary key’ => [‘id’],
];
\Drupal::database()->schema()->createTable(‘student_registration’, $schema);
}
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