Skip to content

Commit 511bbaa

Browse files
committed
feat(ProseMirror): Implement ProseMirror content rendering and add related Twig templates
1 parent 7549cd0 commit 511bbaa

9 files changed

Lines changed: 170 additions & 1 deletion

File tree

examples/dotcms-symfony/src/Twig/DotCMSExtension.php

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public function getFunctions(): array
2222
return [
2323
new TwigFunction('getGridClass', [$this, 'getGridClass']),
2424
new TwigFunction('generateHtmlBasedOnProperty', [$this, 'generateHtmlBasedOnProperty'], ['is_safe' => ['html']]),
25-
new TwigFunction('htmlAttr', [$this, 'htmlAttr'], ['is_safe' => ['html']])
25+
new TwigFunction('htmlAttr', [$this, 'htmlAttr'], ['is_safe' => ['html']]),
26+
new TwigFunction('renderProseMirrorContent', [$this, 'renderProseMirrorContent'], ['is_safe' => ['html']])
2627
];
2728
}
2829

@@ -75,4 +76,88 @@ public function getContainersData(array $containers, array $containerRef): array
7576

7677
return $containerData;
7778
}
79+
80+
public function renderProseMirrorContent($content): string
81+
{
82+
if (empty($content) || !isset($content['content'])) {
83+
return '';
84+
}
85+
86+
$html = '';
87+
foreach ($content['content'] as $block) {
88+
$html .= $this->renderProseMirrorBlock($block);
89+
}
90+
91+
return $html;
92+
}
93+
94+
private function renderProseMirrorBlock(array $block): string
95+
{
96+
$type = $block['type'] ?? '';
97+
$template = 'dotcms/prosemirror/' . $type . '.twig';
98+
99+
if ($this->twig->getLoader()->exists($template)) {
100+
return $this->twig->render($template, ['block' => $block]);
101+
}
102+
103+
// Fallback rendering for unknown block types
104+
return $this->renderFallbackBlock($block);
105+
}
106+
107+
private function renderFallbackBlock(array $block): string
108+
{
109+
$type = $block['type'] ?? 'unknown';
110+
111+
switch ($type) {
112+
case 'paragraph':
113+
return $this->renderParagraph($block);
114+
case 'bulletList':
115+
return $this->renderBulletList($block);
116+
case 'listItem':
117+
return $this->renderListItem($block);
118+
default:
119+
return '';
120+
}
121+
}
122+
123+
private function renderParagraph(array $block): string
124+
{
125+
$content = $this->extractTextContent($block);
126+
return $content ? "<p>{$content}</p>" : '';
127+
}
128+
129+
private function renderBulletList(array $block): string
130+
{
131+
$items = '';
132+
if (isset($block['content'])) {
133+
foreach ($block['content'] as $item) {
134+
$items .= $this->renderProseMirrorBlock($item);
135+
}
136+
}
137+
return $items ? "<ul>{$items}</ul>" : '';
138+
}
139+
140+
private function renderListItem(array $block): string
141+
{
142+
$content = '';
143+
if (isset($block['content'])) {
144+
foreach ($block['content'] as $item) {
145+
$content .= $this->renderProseMirrorBlock($item);
146+
}
147+
}
148+
return $content ? "<li>{$content}</li>" : '';
149+
}
150+
151+
private function extractTextContent(array $block): string
152+
{
153+
$text = '';
154+
if (isset($block['content'])) {
155+
foreach ($block['content'] as $item) {
156+
if (isset($item['text'])) {
157+
$text .= htmlspecialchars($item['text']);
158+
}
159+
}
160+
}
161+
return $text;
162+
}
78163
}

examples/dotcms-symfony/templates/blog-detail.html.twig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
<div class="col-start-1 col-end-13">
1111
<article>
1212
<h1>{{ pageAsset.page.title }}</h1>
13+
14+
{% if pageAsset.urlContentMap.blogContent is defined %}
15+
<div class="blog-content">
16+
{{ renderProseMirrorContent(pageAsset.urlContentMap.blogContent) }}
17+
</div>
18+
{% endif %}
1319
</article>
1420
</div>
1521
</div>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{%- if block.content is defined -%}
2+
<blockquote>
3+
{%- for item in block.content -%}
4+
{{ renderProseMirrorContent({'content': [item]}) }}
5+
{%- endfor -%}
6+
</blockquote>
7+
{%- endif -%}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{%- if block.content is defined -%}
2+
<ul>
3+
{%- for item in block.content -%}
4+
{{ renderProseMirrorContent({'content': [item]}) }}
5+
{%- endfor -%}
6+
</ul>
7+
{%- endif -%}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{%- set language = block.attrs.language|default('') -%}
2+
{%- set content = '' -%}
3+
{%- if block.content is defined -%}
4+
{%- for item in block.content -%}
5+
{%- if item.type == 'text' -%}
6+
{%- set content = content ~ item.text -%}
7+
{%- endif -%}
8+
{%- endfor -%}
9+
{%- endif -%}
10+
{%- if content -%}
11+
<pre><code{% if language %} class="language-{{ language }}"{% endif %}>{{ content }}</code></pre>
12+
{%- endif -%}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{%- set level = block.attrs.level|default(1) -%}
2+
{%- set textAlign = block.attrs.textAlign|default('left') -%}
3+
{%- set content = '' -%}
4+
{%- if block.content is defined -%}
5+
{%- for item in block.content -%}
6+
{%- if item.type == 'text' -%}
7+
{%- set content = content ~ item.text -%}
8+
{%- endif -%}
9+
{%- endfor -%}
10+
{%- endif -%}
11+
{%- if content -%}
12+
<h{{ level }} class="text-{{ textAlign }}">{{ content }}</h{{ level }}>
13+
{%- endif -%}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{%- set textAlign = block.attrs.textAlign|default('left') -%}
2+
{%- if block.content is defined -%}
3+
<li class="text-{{ textAlign }}">
4+
{%- for item in block.content -%}
5+
{%- if item.type == 'paragraph' -%}
6+
{%- set content = '' -%}
7+
{%- if item.content is defined -%}
8+
{%- for textItem in item.content -%}
9+
{%- if textItem.type == 'text' -%}
10+
{%- set content = content ~ textItem.text -%}
11+
{%- endif -%}
12+
{%- endfor -%}
13+
{%- endif -%}
14+
{{ content }}
15+
{%- else -%}
16+
{{ renderProseMirrorContent({'content': [item]}) }}
17+
{%- endif -%}
18+
{%- endfor -%}
19+
</li>
20+
{%- endif -%}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{%- if block.content is defined -%}
2+
<ol>
3+
{%- for item in block.content -%}
4+
{{ renderProseMirrorContent({'content': [item]}) }}
5+
{%- endfor -%}
6+
</ol>
7+
{%- endif -%}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{%- set textAlign = block.attrs.textAlign|default('left') -%}
2+
{%- set content = '' -%}
3+
{%- if block.content is defined -%}
4+
{%- for item in block.content -%}
5+
{%- if item.type == 'text' -%}
6+
{%- set content = content ~ item.text -%}
7+
{%- endif -%}
8+
{%- endfor -%}
9+
{%- endif -%}
10+
{%- if content -%}
11+
<p class="text-{{ textAlign }}">{{ content }}</p>
12+
{%- endif -%}

0 commit comments

Comments
 (0)