|
2 | 2 | from plone.indexer.decorator import indexer |
3 | 3 | from plone.restapi import HAS_PLONE_6 |
4 | 4 | from plone.restapi.behaviors import IBlocks |
| 5 | +from plone.restapi.blocks import visit_blocks |
5 | 6 | from plone.restapi.blocks import visit_subblocks |
6 | 7 | from plone.restapi.interfaces import IBlockSearchableText |
| 8 | +from typing import List |
7 | 9 | from zope.component import adapter |
8 | 10 | from zope.component import queryMultiAdapter |
9 | 11 | from zope.globalrequest import getRequest |
@@ -65,6 +67,40 @@ def __call__(self, block): |
65 | 67 | return block.get("plaintext", "") |
66 | 68 |
|
67 | 69 |
|
| 70 | +@implementer(IBlockSearchableText) |
| 71 | +@adapter(IBlocks, IBrowserRequest) |
| 72 | +class PlateTextIndexer: |
| 73 | + """Searchable Text indexer for plate blocks.""" |
| 74 | + |
| 75 | + def __init__(self, context, request): |
| 76 | + self.context = context |
| 77 | + self.request = request |
| 78 | + |
| 79 | + def __call__(self, block) -> str: |
| 80 | + texts = [self.extract_plate_text(block["value"])] |
| 81 | + for subblock in visit_subblocks(self.context, block): |
| 82 | + texts.append(extract_text(subblock, self.context, self.request)) |
| 83 | + result = text_strip(texts) |
| 84 | + print(result) |
| 85 | + return result |
| 86 | + |
| 87 | + def extract_plate_text(self, value) -> str: |
| 88 | + if isinstance(value, list): |
| 89 | + return " ".join(self.extract_plate_text(item) for item in value) |
| 90 | + elif isinstance(value, dict): |
| 91 | + if "@type" in value: |
| 92 | + # sub-block, will be processed via visit_blocks |
| 93 | + return "" |
| 94 | + texts = [] |
| 95 | + for key in ("text", "children"): |
| 96 | + if key in value: |
| 97 | + texts.append(self.extract_plate_text(value[key])) |
| 98 | + return " ".join(texts) |
| 99 | + elif isinstance(value, str): |
| 100 | + return value.strip() |
| 101 | + return "" |
| 102 | + |
| 103 | + |
68 | 104 | def extract_text(block, obj, request): |
69 | 105 | """Extract text information from a block. |
70 | 106 |
|
@@ -93,23 +129,16 @@ def extract_text(block, obj, request): |
93 | 129 | # Use server side adapters to extract the text data |
94 | 130 | adapter = queryMultiAdapter((obj, request), IBlockSearchableText, name=block_type) |
95 | 131 | result = adapter(block) if adapter is not None else "" |
96 | | - if not result: |
97 | | - for subblock in visit_subblocks(obj, block): |
98 | | - tmp_result = extract_text(subblock, obj, request) |
99 | | - result = f"{result}\n{tmp_result}" |
100 | 132 | return result |
101 | 133 |
|
102 | 134 |
|
103 | | -def get_blocks_text(obj): |
| 135 | +def get_blocks_text(obj) -> List[str]: |
104 | 136 | """Extract text to be used by the SearchableText index in the Catalog.""" |
105 | 137 | request = getRequest() |
106 | | - blocks = obj.blocks |
107 | | - blocks_layout = obj.blocks_layout |
108 | | - blocks_text = [] |
109 | | - for block_id in blocks_layout.get("items", []): |
110 | | - block = blocks.get(block_id, {}) |
111 | | - blocks_text.append(extract_text(block, obj, request)) |
112 | | - return blocks_text |
| 138 | + texts = [] |
| 139 | + for block in visit_blocks(obj, obj.blocks): |
| 140 | + texts.append(extract_text(block, obj, request)) |
| 141 | + return texts |
113 | 142 |
|
114 | 143 |
|
115 | 144 | def text_strip(text_list): |
@@ -139,5 +168,4 @@ def SearchableText_blocks(obj): |
139 | 168 | blocks_text = get_blocks_text(obj) |
140 | 169 | # Extract text using the base plone.app.contenttypes indexer |
141 | 170 | std_text = SearchableText(obj) |
142 | | - blocks_text.append(std_text) |
143 | | - return text_strip(blocks_text) |
| 171 | + return text_strip([std_text] + blocks_text) |
0 commit comments