Who this is for. Site builders and developers who want to see the whole of this unit at work in one model. After this page you can design an application on custom entities and say why each part takes the shape it does.
A learning site of this shape runs in production on Core dna. Learners enrol on courses, read the lessons, take tests and receive a certificate when they pass. None of it is framework code: the definitions, layouts and jobs are configured in the admin, and the only files are templates.
The model
| Part | Built as | Set up |
|---|---|---|
| Course | A definition with a path and a record path | Layout areas for the description, price and pass mark, and a record layout area pointing at the book that holds the lessons. An optional list relationship, prerequisites, to other courses. |
| Enrolment | A definition with a record path and no path | A relationship course (minimum 1, maximum 1, allowed entity Course). A record layout area user holding the learner. Layout areas progress, passScore, passDate and certPath. |
| Test | A definition whose parent definition is Enrolment, with a record path of its own | Layout areas for the learner's answers and the result. |
| Certificate | An Orchestration job | Runs when a test is submitted; on a pass, it renders the certificate and emails it. |
Why each part takes its shape
- The lessons are a book. Books already have units, pages and a reading order. A course points at its book through a record layout area rather than rebuilding lesson order inside a custom entity.
- The enrolment is a record of its own, not a few layout areas on the member, because it has a lifecycle of its own (progress, a pass date, a certificate) and children of its own.
- The enrolment has no listing path. Nobody browses a list of every enrolment; each learner sees their own. With the path empty, the listing route does not exist.
- The course is a relationship; the learner is a layout area. An enrolment and a course both stand on their own, so a relationship definition with a maximum of 1 links them. A relationship can only target custom entity records, so the learner, a member, is a record layout area on the enrolment.
- A test is a child, not a relationship. It cannot exist without its enrolment. With Enrolment as the parent definition of Test, every test's parent must be an enrolment, and the admin offers + Add Test on each enrolment. Test has its own record path, because a child's URL is not nested under its parent's.
- The certificate is a job, because issuing it is an event with side effects, a file and an email, not content.
The enrolment page
The enrolment's detail template shows the course, the learner's progress and the tests taken. The course comes from the relationship, the tests from getChildren():