Skip to content

Commit 146cc0c

Browse files
Merge pull request #210 from canonical/WD-22501
[WD-22501] feat: include and parse markdown files in project trees on content system
2 parents 39e9710 + 8d493d0 commit 146cc0c

File tree

3 files changed

+96
-48
lines changed

3 files changed

+96
-48
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"start": "yarn run build && concurrently --raw 'yarn run watch' 'yarn run serve'",
1414
"test": "vitest",
1515
"watch": "watch -p 'static/client/**/*.{js,jsx,ts,tsx,scss}' -c 'yarn run build'",
16-
"dev": "vite"
16+
"dev": "vite",
17+
"lint-python": "flake8 webapp tests && black --check --line-length 79 webapp tests",
18+
"format-python": "black --line-length 79 webapp tests"
1719
},
1820
"dependencies": {
1921
"@canonical/react-components": "0.60.0",

static/client/pages/Webpage/Webpage.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ const Webpage = ({ page, project }: IWebpageProps): JSX.Element => {
2222
window.open(page.copy_doc_link);
2323
}, [page]);
2424

25+
const pageExtension = useMemo(() => {
26+
return page.ext || ".html";
27+
}, [page.ext]);
28+
2529
const openGitHub = useCallback(() => {
2630
if (page.children.length) {
27-
window.open(`${config.ghLink(project)}${page.name}/index.html`);
31+
window.open(`${config.ghLink(project)}${page.name}/index${pageExtension}`);
2832
} else {
29-
window.open(`${config.ghLink(project)}${page.name}.html`);
33+
window.open(`${config.ghLink(project)}${page.name}${pageExtension}`);
3034
}
31-
}, [page, project]);
35+
}, [page.children.length, page.name, pageExtension, project]);
3236

3337
const createNewPage = useCallback(() => {
3438
setChangeType(ChangeRequestType.NEW_WEBPAGE);

webapp/parse_tree.py

Lines changed: 86 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,31 @@
99
"templates/one-column.html",
1010
"_base/base.html",
1111
]
12+
MARKDOWN_TEMPLATES = [
13+
"legal/_base_legal_markdown.html",
14+
"appliance/shared/_base_appliance_index.html",
15+
]
1216
TEMPLATE_PREFIXES = ["base", "_base"]
1317
TAG_MAPPING = {
1418
"title": ["title"],
1519
"description": ["meta_description", "description"],
16-
"link": ["meta_copydoc"],
20+
"link": ["meta_copydoc", "copydoc"],
1721
}
1822

1923
EXCLUDE_PATHS = ["partials"]
2024

2125

2226
def is_index(path):
23-
return path.name == "index.html"
27+
return path.name == "index.html" or path.name == "index.md"
2428

2529

2630
def check_has_index(path):
27-
return (path / "index.html").exists()
31+
if (path / "index.html").exists():
32+
return True, ".html"
33+
elif (path / "index.md").exists():
34+
return True, ".md"
35+
else:
36+
return False, None
2837

2938

3039
def is_template(path):
@@ -43,7 +52,7 @@ def is_template(path):
4352

4453
def is_partial(path):
4554
"""
46-
Return True if the file name starts with an underscore,
55+
Return True if the file name starts with an underscore,
4756
that indicates it as a partial
4857
4958
Partials are templates that are not meant to be rendered directly, but
@@ -81,7 +90,7 @@ def extends_base(path, base="templates"):
8190
else:
8291
# extract absolute path from the parent path
8392
absolute_path = str(path)[
84-
0 : str(path).find(base) + len(base)
93+
0: str(path).find(base) + len(base)
8594
]
8695
# check if the file from which the current file
8796
# extends extends from the base template
@@ -139,7 +148,7 @@ def get_extended_copydoc(path, base):
139148
with base.joinpath(path).open("r") as f:
140149
file_data = f.read()
141150
if match := re.search(
142-
"\{\% block meta_copydoc *\%\}(.*)\{\%( *)endblock", file_data
151+
r"\{\% block meta_copydoc *\%\}(.*)\{\%( *)endblock", file_data
143152
):
144153
return match.group(1)
145154

@@ -155,6 +164,9 @@ def get_tags_rolling_buffer(path):
155164
# We create a map of the selected variants for each tag
156165
variants_mapping = {v: "" for v in available_tags}
157166

167+
# check if the path is html or md file
168+
is_md = path.suffix == ".md"
169+
158170
with path.open("r") as f:
159171
for tag in available_tags:
160172
buffer = []
@@ -168,44 +180,63 @@ def get_tags_rolling_buffer(path):
168180
# Return to start of file
169181
f.seek(0)
170182

171-
for line in f.readlines():
172-
if is_buffering:
173-
buffer.append(line)
174-
175-
if not is_buffering and (
176-
match := re.search(f"{{% block {variant}( *)%}}", line)
177-
):
178-
# We remove line contents before the tag
179-
line = line[match.start() :] # noqa: E203
180-
181-
buffer.append(line)
182-
is_buffering = True
183-
variants_mapping[tag] = variant
184-
185-
# We search for the end of the tag in the existing buffer
186-
buffer_string = "".join(buffer)
187-
if is_buffering and re.search(
188-
"(.*){%( *)endblock", buffer_string
189-
):
190-
# We save the buffer contents to the tags dictionary
191-
tags[tag] = buffer_string
192-
193-
# We extract the text within the tags
194-
tags[tag] = extract_text_from_tag(
195-
variants_mapping[tag], tags[tag]
183+
if not is_md:
184+
185+
for line in f.readlines():
186+
if is_buffering:
187+
buffer.append(line)
188+
189+
if not is_buffering and (
190+
match := re.search(
191+
f"{{% block {variant}( *)%}}", line
192+
)
193+
):
194+
# We remove line contents before the tag
195+
line = line[match.start() :] # noqa: E203
196+
197+
buffer.append(line)
198+
is_buffering = True
199+
variants_mapping[tag] = variant
200+
201+
# We search for the end of the tag in the existing
202+
# buffer
203+
buffer_string = "".join(buffer)
204+
if is_buffering and re.search(
205+
"(.*){%( *)endblock", buffer_string
206+
):
207+
# We save the buffer contents to the tags
208+
# dictionary
209+
tags[tag] = buffer_string
210+
211+
# We extract the text within the tags
212+
tags[tag] = extract_text_from_tag(
213+
variants_mapping[tag], tags[tag]
214+
)
215+
216+
# We now reset the buffer
217+
buffer = []
218+
is_buffering = False
219+
tag_found = True
220+
break
221+
222+
else:
223+
for line in f:
224+
match = re.match(
225+
rf"^\s*{variant}\s*:\s*\"?(.+?)\"?\s*$",
226+
line,
227+
re.IGNORECASE,
196228
)
197-
198-
# We now reset the buffer
199-
buffer = []
200-
is_buffering = False
201-
tag_found = True
202-
break
229+
if match:
230+
variants_mapping[tag] = variant
231+
tags[tag] = match.group(1).strip()
232+
tag_found = True
233+
break
203234

204235
if tag_found:
205236
break
206237

207238
# We add the name from the path
208-
raw_name = re.sub(r"(?i)(.html|/index.html)", "", str(path))
239+
raw_name = re.sub(r"(?i)(.html|/index.html|/index.md)", "", str(path))
209240
tags["name"] = raw_name.split("/templates", 1)[-1]
210241

211242
return tags
@@ -216,11 +247,10 @@ def is_valid_page(path, extended_path, is_index=True):
216247
Determine if path is a valid page. Pages are valid if:
217248
- They contain the same extended path as the index html.
218249
- They extend from the base html.
250+
- Does not live in a shared template directory.
251+
- They are markdown files with a valid wrapper template.
219252
"""
220-
221-
path = Path(path)
222-
223-
if not path.is_file() or is_template(path) or is_partial(path):
253+
if is_template(path):
224254
return False
225255

226256
if not is_index and extended_path:
@@ -229,6 +259,17 @@ def is_valid_page(path, extended_path, is_index=True):
229259
if match := re.search("{% extends [\"'](.*?)[\"'] %}", line):
230260
if match.group(1) == extended_path:
231261
return True
262+
263+
if "index.md" in str(path):
264+
with path.open("r") as f:
265+
for line in f.readlines():
266+
if match := re.search(
267+
r"wrapper_template:\s*[\"']?(.*?)[\"']?$", line
268+
):
269+
template = match.group(1)
270+
if template in MARKDOWN_TEMPLATES:
271+
return True
272+
232273
# If the file does not share the extended path, check if it extends the
233274
# base html
234275
return extends_base(path)
@@ -288,9 +329,9 @@ def scan_directory(path_name, base=None):
288329
is_index_page_valid = False
289330

290331
# Check if an index.html file exists in this directory
291-
has_index = check_has_index(node_path)
332+
(has_index, index_type) = check_has_index(node_path)
292333
if has_index:
293-
index_path = node_path / "index.html"
334+
index_path = node_path / ("index" + index_type)
294335
# Get the path extended by the index.html file
295336
extended_path = get_extended_path(index_path)
296337
# If the file is valid, add it as a child
@@ -299,6 +340,7 @@ def scan_directory(path_name, base=None):
299340
# Get tags, add as child
300341
tags = get_tags_rolling_buffer(index_path)
301342
node = update_tags(node, tags)
343+
node["ext"] = index_type
302344

303345
else:
304346
node["ext"] = ".dir"

0 commit comments

Comments
 (0)