87 lines
3.6 KiB
Python
87 lines
3.6 KiB
Python
|
|
from django.template import Template, Context
|
||
|
|
import re
|
||
|
|
|
||
|
|
|
||
|
|
def render_universal_segment(segment, context_data):
|
||
|
|
segment_type = segment.get('segment_type', 'unknown')
|
||
|
|
raw_content = segment.get('content')
|
||
|
|
|
||
|
|
if raw_content is None:
|
||
|
|
content = []
|
||
|
|
elif isinstance(raw_content, dict):
|
||
|
|
content = [raw_content]
|
||
|
|
elif isinstance(raw_content, list):
|
||
|
|
content = raw_content
|
||
|
|
else:
|
||
|
|
content = [raw_content]
|
||
|
|
|
||
|
|
rendered = []
|
||
|
|
context = Context(context_data)
|
||
|
|
|
||
|
|
for item in content:
|
||
|
|
if not isinstance(item, dict):
|
||
|
|
continue
|
||
|
|
|
||
|
|
title = Template(item.get('title', '')).render(context)
|
||
|
|
subtitle = Template(item.get('subtitle', '')).render(context)
|
||
|
|
description = Template(item.get('description', '')).render(context)
|
||
|
|
|
||
|
|
if title:
|
||
|
|
rendered.append(f'<h2 style="color: #2c3e50; margin-top: 30px;">{title}</h2>')
|
||
|
|
|
||
|
|
if subtitle:
|
||
|
|
rendered.append(f'<h3 style="color: #34495e; margin-top: 20px;">{subtitle}</h3>')
|
||
|
|
|
||
|
|
if description:
|
||
|
|
processed_desc = []
|
||
|
|
in_list = False
|
||
|
|
for line in description.split('\n'):
|
||
|
|
line = line.strip()
|
||
|
|
if re.match(r'^[-•*]\s', line):
|
||
|
|
if not in_list:
|
||
|
|
processed_desc.append('<ul style="list-style-type: disc; margin-left: 20px;">')
|
||
|
|
in_list = True
|
||
|
|
processed_desc.append(f'<li>{line[2:].strip()}</li>')
|
||
|
|
else:
|
||
|
|
if in_list:
|
||
|
|
processed_desc.append('</ul>')
|
||
|
|
in_list = False
|
||
|
|
if line:
|
||
|
|
processed_desc.append(f'<p style="margin: 10px 0; line-height: 1.6;">{line}</p>')
|
||
|
|
if in_list:
|
||
|
|
processed_desc.append('</ul>')
|
||
|
|
rendered.append('\n'.join(processed_desc))
|
||
|
|
|
||
|
|
if 'headers' in item and 'rows' in item:
|
||
|
|
table_html = ['<table class="report-table" style="width: 100%; border-collapse: collapse; margin: 20px 0;">']
|
||
|
|
table_html.append('<thead><tr>')
|
||
|
|
for header in item['headers']:
|
||
|
|
table_html.append(f'<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">{Template(header).render(context)}</th>')
|
||
|
|
table_html.append('</tr></thead><tbody>')
|
||
|
|
|
||
|
|
for row in item['rows']:
|
||
|
|
table_html.append('<tr>')
|
||
|
|
for cell in row:
|
||
|
|
cell_content = Template(cell).render(context) if isinstance(cell, str) else ', '.join([Template(str(c)).render(context) for c in cell])
|
||
|
|
table_html.append(f'<td style="border: 1px solid #ddd; padding: 8px;">{cell_content}</td>')
|
||
|
|
table_html.append('</tr>')
|
||
|
|
table_html.append('</tbody></table>')
|
||
|
|
rendered.append('\n'.join(table_html))
|
||
|
|
|
||
|
|
if 'image' in item:
|
||
|
|
image_url = Template(item['image']).render(context)
|
||
|
|
rendered.append(f'<img src="{image_url}" alt="{title}" style="max-width: 100%; height: auto; margin: 20px 0;">')
|
||
|
|
|
||
|
|
if 'html' in segment:
|
||
|
|
html_template = Template(segment['html'])
|
||
|
|
rendered_html = html_template.render(context)
|
||
|
|
rendered.append(rendered_html)
|
||
|
|
|
||
|
|
return '\n'.join(rendered)
|
||
|
|
|
||
|
|
def render_template(template_segments, context_data):
|
||
|
|
final_output = []
|
||
|
|
for segment in template_segments:
|
||
|
|
segment_html = render_universal_segment(segment, context_data)
|
||
|
|
final_output.append(f'<div class="segment {segment.get("segment_type", "")}">{segment_html}</div>')
|
||
|
|
return '\n'.join(final_output)
|