Developer Documentation

Academic Report Template Documentation

Complete guide to template variables, data structures, and implementation for generating academic reports.

Template Variables Quick Reference

Template Context Structure

Your backend must provide these root objects in the rendering context.

Root Context Objects

{
  "school": {...},
  "student": {...},
  "session": {...},
  "term": {...},
  "subjects": [...],
  "assessment_fields": [...],
  "summary": {...},
  "psychomotor": {...},
  "affective": {...},
  "custom_ratings": {...},
  "get_remark": function
}

School Object

school.name String
school.logo URL/Base64
school.address String
school.phone String
school.email String

Student Object

student.name String
student.reg_no String
student.class String
student.age String (Pre-calculated)
student.passport_photo URL

Complete Data Structure Example

context = {
    "school": {
        "name": "SCHOOL OF EXCELLENCE",
        "logo": "https://example.com/logo.png",
        "address": "123 Education Street",
        "phone": "+234 801 234 5678",
        "email": "info@schoolexcellence.edu",
        "website": "www.schoolexcellence.edu",
        "motto": "Knowledge is Power"
    },
    "student": {
        "name": "John Doe",
        "reg_no": "REG-2024-001",
        "class": "JSS 3A",
        "gender": "Male",
        "dob": "15/03/2008",
        "age": 15,
        "passport_photo": "https://ui-avatars.com/api/?name=John+Doe"
    },
    "session": {"id": 1, "name": "2023/2024"},
    "term": {"id": 1, "name": "First Term"},
    "subjects": [
        {
            "name": "Mathematics",
            "code": "MATH",
            "total": 90.0,
            "grade": "A",
            "remark": "Excellent",
            "position": "1st",
            "assessment_scores": {
                "quiz": 15,
                "assignment": 13,
                "midterm": 30,
                "project": 17
            }
        }
    ],
    "assessment_fields": [
        {
            "display_name": "Quiz",
            "field_code": "quiz",
            "max_score": 20.0,
            "weight": 0.15,
            "field_type": "test",
            "is_compulsory": True
        }
    ],
    "summary": {
        "total_score": 540.0,
        "average_score": 85.5,
        "overall_grade": "A",
        "class_position": "3rd",
        "total_subjects": 8,
        "report_date": "25 January, 2024",
        "teacher_comment": "Excellent performance.",
        "principal_comment": "Keep it up."
    },
    "psychomotor": {
        "Handwriting": "Good",
        "Sports": "Excellent"
    },
    "affective": {
        "Punctuality": "Very Good",
        "Neatness": "Good"
    },
    "get_remark": get_remark_function
}

Template Usage Guide

Backend Implementation

Required Helper Functions

def get_remark(grade):
    remarks = {
        "A": "Excellent",
        "B": "Very Good",
        "C": "Good",
        "D": "Pass",
        "F": "Fail"
    }
    return remarks.get(grade, "N/A")

def calculate_age(dob):
    # Must be pre-calculated in backend
    today = datetime.today()
    age = today.year - dob.year
    if today.month < dob.month or (today.month == dob.month and today.day < dob.day):
        age -= 1
    return f"{age} years"

Rendering Context

  • All objects must be present (can be empty)
  • get_remark function must be injected
  • Image URLs must be valid for PDF rendering

Template Rendering Logic

Conditional Rendering

{% if assessment_fields and assessment_fields|length > 0 %}
  <!-- Show dynamic assessment columns -->
{% else %}
  <!-- Legacy CA/Exam fallback -->
{% endif %}

{% if psychomotor or affective %}
  <!-- Show behavioral assessments -->
{% endif %}

Loop Examples

{% for subject in subjects %}
  <tr>
    <td>{{ loop.index }}</td>
    <td>{{ subject.name }}</td>
    <td>{{ subject.total }}</td>
    <td>{{ subject.grade }}</td>
    <td>{{ subject.remark }}</td>
  </tr>
{% endfor %}

Important Implementation Notes

Backward Compatibility

  • • If assessment_fields is empty, template uses CA/Exam fallback
  • • Legacy schools must provide ca_score and exam_score
  • • Behavioral assessments are optional

Data Validation

  • assessment_scores keys must match field_code
  • • Numbers must be floats/ints (not strings)
  • • Images must be URLs, not file paths

Frequently Asked Questions

What happens if some data is missing?

The template is designed to handle missing data gracefully:

  • Missing objects render as blank sections
  • Conditional sections hide if data is not available
  • Template won't crash on missing variables

How do I implement dynamic assessment fields?

Dynamic assessment fields allow custom scoring categories:

assessment_fields = [
    {
        "display_name": "Classwork",
        "field_code": "classwork",
        "max_score": 10.0,
        "weight": 0.10,
        "field_type": "activity"
    },
    {
        "display_name": "Project",
        "field_code": "project",
        "max_score": 30.0,
        "weight": 0.30,
        "field_type": "assignment"
    }
]

Each subject must have matching assessment_scores with these field codes.

Can I add custom behavioral ratings?

Yes! Use the custom_ratings object for school-specific traits:

custom_ratings = {
    "Leadership Skills": "Excellent",
    "Team Collaboration": "Very Good",
    "Creativity": "Good",
    "Problem Solving": "Excellent"
}

These will automatically appear in the behavioral assessment section.

How does PDF generation work with this template?

For PDF generation, ensure:

  • All image URLs are accessible (not local paths)
  • Use absolute URLs for logos and photos
  • Consider using base64 encoded images for reliability

What's the performance impact with many students/subjects?

The template is optimized for performance:

  • Efficient Jinja2 rendering for large datasets
  • Minimal DOM operations in template
  • Loops are optimized and pagination-ready

How do I handle grade calculations?

Grade calculations should be done in the backend:

def calculate_grade(score):
    if score >= 75: return "A"
    elif score >= 70: return "AB"
    elif score >= 65: return "B"
    elif score >= 60: return "BC"
    elif score >= 55: return "C"
    elif score >= 50: return "CD"
    elif score >= 45: return "D"
    elif score >= 40: return "E"
    else: return "F"

# Apply to each subject
for subject in subjects:
    subject['grade'] = calculate_grade(subject['total'])
    subject['remark'] = get_remark(subject['grade'])

The template only displays pre-calculated grades.

Implementation Checklist

Before Rendering

All required root objects exist
subjects list is non-empty
get_remark function is injected
Images are URLs or base64 encoded

Data Validation

assessment_scores keys match field_code
Numbers are floats/ints (not strings)
Student age is pre-calculated
All grades and remarks are calculated

Pro Tips

  • • Use the template's conditional rendering for optional sections
  • • Implement caching for frequently generated reports
  • • Test with both dynamic and legacy assessment systems
  • • Validate all data before passing to template engine

Need Help Implementing?

Our team can help you integrate this template system into your application.

Looking for Full Implementation?

We offer complete integration services including backend development, template customization, and PDF generation.

Contact Sales Team
! Chat with us