// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA TEMPLATE INHERITANCE - Extends, Blocks, and Includes")
System.print("=" * 60)
var templates = {
"base.html": "<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>{\% block title \%}Default Title{\% endblock \%}</title>
<style>
{\% block styles \%}
body { font-family: sans-serif; margin: 20px; }
{\% endblock \%}
</style>
</head>
<body>
<header>
{\% block header \%}
<h1>My Website</h1>
<nav>{\% block nav \%}<a href=\"/\">Home</a>{\% endblock \%}</nav>
{\% endblock \%}
</header>
<main>
{\% block content \%}
<p>Default content goes here.</p>
{\% endblock \%}
</main>
<footer>
{\% block footer \%}
<p>Copyright 2024</p>
{\% endblock \%}
</footer>
</body>
</html>",
"page.html": "{\% extends \"base.html\" \%}
{\% block title \%}{{ page_title }} - My Website{\% endblock \%}
{\% block content \%}
<article>
<h2>{{ heading }}</h2>
<p>{{ content }}</p>
</article>
{\% endblock \%}",
"blog_base.html": "{\% extends \"base.html\" \%}
{\% block nav \%}
{{ super() }}
| <a href=\"/blog\">Blog</a>
| <a href=\"/about\">About</a>
{\% endblock \%}
{\% block styles \%}
{{ super() }}
.blog-post { border: 1px solid #ccc; padding: 10px; margin: 10px 0; }
.blog-meta { color: #666; font-size: 0.9em; }
{\% endblock \%}
{\% block content \%}
<section class=\"blog\">
{\% block blog_content \%}
<p>Blog posts will appear here.</p>
{\% endblock \%}
</section>
{\% endblock \%}",
"blog_post.html": "{\% extends \"blog_base.html\" \%}
{\% block title \%}{{ post.title }} - Blog{\% endblock \%}
{\% block blog_content \%}
<article class=\"blog-post\">
<h2>{{ post.title }}</h2>
<p class=\"blog-meta\">By {{ post.author }} on {{ post.date }}</p>
<div class=\"blog-body\">
{{ post.body }}
</div>
{\% if post.tags \%}
<p class=\"blog-tags\">Tags: {{ post.tags|join(\", \") }}</p>
{\% endif \%}
</article>
{\% endblock \%}",
"blog_list.html": "{\% extends \"blog_base.html\" \%}
{\% block title \%}All Posts - Blog{\% endblock \%}
{\% block blog_content \%}
<h2>Recent Posts</h2>
{\% for post in posts \%}
<article class=\"blog-post\">
<h3>{{ post.title }}</h3>
<p class=\"blog-meta\">{{ post.date }} by {{ post.author }}</p>
<p>{{ post.excerpt }}</p>
<a href=\"/blog/{{ post.slug }}\">Read more...</a>
</article>
{\% else \%}
<p>No posts yet.</p>
{\% endfor \%}
{\% endblock \%}",
"admin_base.html": "{\% extends \"base.html\" \%}
{\% block header \%}
<h1>Admin Panel</h1>
<nav>
<a href=\"/admin\">Dashboard</a> |
<a href=\"/admin/users\">Users</a> |
<a href=\"/admin/posts\">Posts</a> |
<a href=\"/admin/settings\">Settings</a>
</nav>
{\% endblock \%}
{\% block styles \%}
{{ super() }}
.admin-panel { background: #f5f5f5; padding: 20px; }
.admin-table { width: 100\%; border-collapse: collapse; }
.admin-table th, .admin-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
{\% endblock \%}
{\% block content \%}
<div class=\"admin-panel\">
{\% block admin_content \%}
<p>Welcome to the admin panel.</p>
{\% endblock \%}
</div>
{\% endblock \%}
{\% block footer \%}
<p>Admin Panel v1.0 | <a href=\"/\">Back to site</a></p>
{\% endblock \%}",
"admin_users.html": "{\% extends \"admin_base.html\" \%}
{\% block title \%}User Management - Admin{\% endblock \%}
{\% block admin_content \%}
<h2>User Management</h2>
<table class=\"admin-table\">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{\% for user in users \%}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.role|title }}</td>
<td>{{ \"Active\" if user.active else \"Inactive\" }}</td>
</tr>
{\% endfor \%}
</tbody>
</table>
<p>Total users: {{ users|length }}</p>
{\% endblock \%}",
"sidebar.html": "<aside class=\"sidebar\">
<h3>{{ title|default(\"Sidebar\") }}</h3>
{\% if items \%}
<ul>
{\% for item in items \%}
<li><a href=\"{{ item.url }}\">{{ item.label }}</a></li>
{\% endfor \%}
</ul>
{\% endif \%}
</aside>",
"alert.html": "<div class=\"alert alert-{{ type|default(\"info\") }}\">
{\% if dismissible \%}<button class=\"close\">&times;</button>{\% endif \%}
<strong>{{ title }}:</strong> {{ message }}
</div>",
"page_with_includes.html": "{\% extends \"base.html\" \%}
{\% block title \%}Page with Includes{\% endblock \%}
{\% block content \%}
<div class=\"container\">
<div class=\"main-content\">
{\% include \"alert.html\" \%}
<h2>Main Content</h2>
<p>{{ content }}</p>
</div>
{\% include \"sidebar.html\" \%}
</div>
{\% endblock \%}",
"email_base.html": "From: {{ from_email }}
To: {{ to_email }}
Subject: {\% block subject \%}No Subject{\% endblock \%}
{\% block greeting \%}Hello,{\% endblock \%}
{\% block body \%}
This is the email body.
{\% endblock \%}
{\% block signature \%}
Best regards,
{{ sender_name }}
{\% endblock \%}",
"welcome_email.html": "{\% extends \"email_base.html\" \%}
{\% block subject \%}Welcome to Our Service, {{ user.name }}!{\% endblock \%}
{\% block greeting \%}Dear {{ user.name }},{\% endblock \%}
{\% block body \%}
Thank you for signing up for our service!
Your account details:
- Username: {{ user.username }}
- Email: {{ user.email }}
- Plan: {{ user.plan|title }}
To get started, please verify your email by clicking the link below:
{{ verification_url }}
If you have any questions, feel free to contact our support team.
{\% endblock \%}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n" + "-" * 60)
System.print("1. BASIC PAGE (extends base.html)")
System.print("-" * 60)
System.print(env.getTemplate("page.html").render({
"page_title": "Welcome",
"heading": "Welcome to Our Website",
"content": "This is a simple page that extends the base template."
}))
System.print("\n" + "-" * 60)
System.print("2. BLOG POST (three-level inheritance: blog_post -> blog_base -> base)")
System.print("-" * 60)
System.print(env.getTemplate("blog_post.html").render({
"post": {
"title": "Getting Started with Jinja Templates",
"author": "Alice Smith",
"date": "2024-01-15",
"body": "Template inheritance is a powerful feature that allows you to build a base skeleton template containing common elements of your site and defines blocks that child templates can override.",
"tags": ["jinja", "templates", "tutorial"]
}
}))
System.print("\n" + "-" * 60)
System.print("3. BLOG LIST (loops within inherited template)")
System.print("-" * 60)
System.print(env.getTemplate("blog_list.html").render({
"posts": [
{"title": "First Post", "date": "2024-01-15", "author": "Alice", "excerpt": "This is my first post...", "slug": "first-post"},
{"title": "Second Post", "date": "2024-01-14", "author": "Bob", "excerpt": "Another great article...", "slug": "second-post"},
{"title": "Third Post", "date": "2024-01-13", "author": "Charlie", "excerpt": "More content here...", "slug": "third-post"}
]
}))
System.print("\n" + "-" * 60)
System.print("4. ADMIN USERS PAGE (admin template hierarchy)")
System.print("-" * 60)
System.print(env.getTemplate("admin_users.html").render({
"users": [
{"id": 1, "name": "Alice Smith", "email": "alice@example.com", "role": "admin", "active": true},
{"id": 2, "name": "Bob Jones", "email": "bob@example.com", "role": "editor", "active": true},
{"id": 3, "name": "Charlie Brown", "email": "charlie@example.com", "role": "user", "active": false},
{"id": 4, "name": "Diana Ross", "email": "diana@example.com", "role": "user", "active": true}
]
}))
System.print("\n" + "-" * 60)
System.print("5. PAGE WITH INCLUDES")
System.print("-" * 60)
System.print(env.getTemplate("page_with_includes.html").render({
"type": "warning",
"title": "Notice",
"message": "This page demonstrates the include feature.",
"dismissible": true,
"content": "This is the main content of the page.",
"title": "Quick Links",
"items": [
{"label": "Home", "url": "/"},
{"label": "About", "url": "/about"},
{"label": "Contact", "url": "/contact"}
]
}))
System.print("\n" + "-" * 60)
System.print("6. STANDALONE INCLUDE (sidebar)")
System.print("-" * 60)
System.print(env.getTemplate("sidebar.html").render({
"title": "Navigation",
"items": [
{"label": "Dashboard", "url": "/dashboard"},
{"label": "Profile", "url": "/profile"},
{"label": "Settings", "url": "/settings"},
{"label": "Logout", "url": "/logout"}
]
}))
System.print("\n" + "-" * 60)
System.print("7. EMAIL TEMPLATE (text-based inheritance)")
System.print("-" * 60)
System.print(env.getTemplate("welcome_email.html").render({
"from_email": "noreply@example.com",
"to_email": "newuser@example.com",
"sender_name": "The Example Team",
"user": {
"name": "John Doe",
"username": "johndoe",
"email": "newuser@example.com",
"plan": "premium"
},
"verification_url": "https://example.com/verify?token=abc123"
}))
System.print("\n" + "-" * 60)
System.print("8. SUPER() DEMONSTRATION")
System.print("-" * 60)
var superDemo = {
"level1": "[L1-START]{\% block content \%}Level1-Content{\% endblock \%}[L1-END]",
"level2": "{\% extends \"level1\" \%}{\% block content \%}{{ super() }}+Level2{\% endblock \%}",
"level3": "{\% extends \"level2\" \%}{\% block content \%}{{ super() }}+Level3{\% endblock \%}"
}
var superEnv = Environment.new(DictLoader.new(superDemo))
System.print("Level 1: " + superEnv.getTemplate("level1").render({}))
System.print("Level 2: " + superEnv.getTemplate("level2").render({}))
System.print("Level 3: " + superEnv.getTemplate("level3").render({}))
System.print("\n" + "-" * 60)
System.print("9. MULTIPLE BLOCKS INHERITANCE")
System.print("-" * 60)
var multiBlock = {
"base": "A:{\% block a \%}base-a{\% endblock \%} B:{\% block b \%}base-b{\% endblock \%} C:{\% block c \%}base-c{\% endblock \%}",
"override_a": "{\% extends \"base\" \%}{\% block a \%}OVERRIDE-A{\% endblock \%}",
"override_bc": "{\% extends \"base\" \%}{\% block b \%}OVERRIDE-B{\% endblock \%}{\% block c \%}OVERRIDE-C{\% endblock \%}",
"override_all": "{\% extends \"base\" \%}{\% block a \%}NEW-A{\% endblock \%}{\% block b \%}NEW-B{\% endblock \%}{\% block c \%}NEW-C{\% endblock \%}"
}
var multiEnv = Environment.new(DictLoader.new(multiBlock))
System.print("Base: " + multiEnv.getTemplate("base").render({}))
System.print("Override A: " + multiEnv.getTemplate("override_a").render({}))
System.print("Override BC:" + multiEnv.getTemplate("override_bc").render({}))
System.print("Override All:" + multiEnv.getTemplate("override_all").render({}))
System.print("\n" + "=" * 60)
System.print("End of Inheritance Demo")
System.print("=" * 60)