0001-misc-add-title-field-to-text-cells-42968.patch
combo/data/migrations/0058_textcell_title.py | ||
---|---|---|
1 |
# Generated by Django 2.2.26 on 2022-08-10 16:32 |
|
2 | ||
3 |
from io import StringIO |
|
4 | ||
5 |
import lxml |
|
6 |
import lxml.html |
|
7 |
from django.db import migrations, models |
|
8 | ||
9 |
from combo.data.models import TextCell |
|
10 | ||
11 | ||
12 |
def forward_title_migration(apps, schema_editor): |
|
13 |
TextCell = apps.get_model('data', 'TextCell') |
|
14 |
for cell in TextCell.objects.all(): |
|
15 |
if not cell.text: |
|
16 |
continue |
|
17 |
parser = lxml.etree.HTMLParser() |
|
18 |
html_document = lxml.etree.parse(StringIO(cell.text), parser) |
|
19 |
root = html_document.getroot() |
|
20 |
title_nodes = root.xpath('/html/body/h2[1]') |
|
21 |
if title_nodes: |
|
22 |
assert len(title_nodes) == 1 |
|
23 |
title_node = title_nodes[0] |
|
24 |
body = title_node.getparent() |
|
25 |
title = title_node.text or '' |
|
26 |
title += ''.join([lxml.html.tostring(child).decode() for child in title_node]) |
|
27 |
text = title_node.tail or '' |
|
28 |
text += body.text or '' |
|
29 |
text += ''.join([lxml.html.tostring(child).decode() for child in body[1:]]) |
|
30 |
cell.title = title |
|
31 |
cell.text = text |
|
32 |
cell.save() |
|
33 | ||
34 | ||
35 |
def reverse_title_migration(apps, schema_editor): |
|
36 |
TextCell = apps.get_model('data', 'TextCell') |
|
37 |
for cell in TextCell.objects.all(): |
|
38 |
if cell.title: |
|
39 |
cell.text = f'<h2>{cell.title}</h2>{cell.text}' |
|
40 |
cell.save() |
|
41 | ||
42 | ||
43 |
class Migration(migrations.Migration): |
|
44 | ||
45 |
dependencies = [ |
|
46 |
('data', '0057_pagesnapshot_label'), |
|
47 |
] |
|
48 | ||
49 |
operations = [ |
|
50 |
migrations.AddField( |
|
51 |
model_name='textcell', |
|
52 |
name='title', |
|
53 |
field=models.CharField(blank=True, max_length=150, null=True, verbose_name='Title'), |
|
54 |
), |
|
55 |
migrations.RunPython(forward_title_migration, reverse_title_migration), |
|
56 |
] |
combo/data/models.py | ||
---|---|---|
1475 | 1475 | |
1476 | 1476 |
@register_cell_class |
1477 | 1477 |
class TextCell(CellBase): |
1478 |
title = models.CharField(_('Title'), max_length=150, blank=True, null=True) |
|
1478 | 1479 |
text = RichTextField(_('Text'), blank=True, null=True) |
1479 | 1480 | |
1480 | 1481 |
default_template_name = 'combo/text-cell.html' |
... | ... | |
1533 | 1534 | |
1534 | 1535 |
text = re.sub(r'src="(.*?)"', sub_src, text) |
1535 | 1536 |
text = re.sub(r'href="(.*?)"', sub_href, text) |
1536 |
extra_context['text'] = mark_safe(text) |
|
1537 |
extra_context["text"] = mark_safe(text) |
|
1538 |
if self.title: |
|
1539 |
extra_context["title"] = mark_safe(self.title) |
|
1537 | 1540 |
return extra_context |
1538 | 1541 | |
1539 | 1542 |
combo/public/templates/combo/text-cell.html | ||
---|---|---|
1 | 1 |
{% block cell-content %} |
2 | 2 |
{% include "combo/asset_picture_fragment.html" %} |
3 |
{% if title %}<h2 class="cell--title text-cell--title">{{ title }}</h2>{% endif %} |
|
3 | 4 |
{{text}} |
4 | 5 |
{% endblock %} |
tests/test_cells.py | ||
---|---|---|
122 | 122 |
assert 'href="/plop"' in cell.render(ctx) |
123 | 123 | |
124 | 124 | |
125 |
def test_text_cell_title(): |
|
126 |
page = Page() |
|
127 |
page.save() |
|
128 | ||
129 |
cell = TextCell(page=page, order=0) |
|
130 |
cell.text = '<p>body</p>' |
|
131 |
cell.title = 'Cell Title' |
|
132 |
cell.save() |
|
133 |
ctx = {} |
|
134 |
assert re.search(r'<h2[^>]*>Cell Title</h2>', cell.render(ctx)) |
|
135 | ||
136 |
cell = TextCell(page=page, order=0) |
|
137 |
cell.text = '<p>body</p>' |
|
138 |
cell.title = None |
|
139 |
cell.save() |
|
140 |
ctx = {} |
|
141 |
assert not re.search(r'<h2[^>]*>.*</h2>', cell.render(ctx)) |
|
142 | ||
143 | ||
125 | 144 |
def test_link_cell(): |
126 | 145 |
page = Page(title='example page', slug='example-page') |
127 | 146 |
page.save() |
128 |
- |