feat: implement dynamic training course tab system and modular PDF data migration scripts
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import os
|
||||
|
||||
templates_to_update = [
|
||||
'src/main/resources/templates/dao-tao-detail.html',
|
||||
'src/main/resources/templates/posts/full-width.html',
|
||||
'src/main/resources/templates/posts/livestream.html',
|
||||
'src/main/resources/templates/posts/sidebar.html',
|
||||
'src/main/resources/templates/posts/standard.html'
|
||||
]
|
||||
|
||||
switch_script = """
|
||||
<script>
|
||||
document.addEventListener('click', function(e) {
|
||||
if (e.target.classList.contains('custom-tab-btn')) {
|
||||
var btn = e.target;
|
||||
var container = btn.closest('.custom-tabs-wrapper');
|
||||
if (!container) return;
|
||||
var idx = btn.getAttribute('data-tab-idx');
|
||||
|
||||
container.querySelectorAll('.custom-tab-btn').forEach(function(b) {
|
||||
b.classList.remove('active');
|
||||
b.style.background = '#f8f9fa';
|
||||
b.style.color = 'black';
|
||||
});
|
||||
btn.classList.add('active');
|
||||
btn.style.background = '#0055a5';
|
||||
btn.style.color = 'white';
|
||||
|
||||
container.querySelectorAll('.custom-tab-panel').forEach(function(p) {
|
||||
p.style.display = 'none';
|
||||
});
|
||||
var activePanel = container.querySelector('.custom-tab-panel[data-tab-idx="' + idx + '"]');
|
||||
if (activePanel) activePanel.style.display = 'block';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
"""
|
||||
|
||||
for filepath in templates_to_update:
|
||||
if not os.path.exists(filepath):
|
||||
continue
|
||||
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# First, remove the script from wherever it is (at the bottom)
|
||||
if "document.addEventListener('click', function(e) {" in content:
|
||||
# Find the script block
|
||||
start_idx = content.find("document.addEventListener('click', function(e) {")
|
||||
script_start = content.rfind("<script>", 0, start_idx)
|
||||
script_end = content.find("</script>", start_idx) + 9
|
||||
|
||||
# Remove it
|
||||
content = content[:script_start].rstrip() + "\n" + content[script_end:].lstrip()
|
||||
|
||||
# Now find where layout:fragment="content" ends
|
||||
# We can just look for the last closing </div> inside the document before </body>
|
||||
# Wait, the easiest way is to inject it right after the Editor parsing script which is INSIDE the fragment!
|
||||
# The editor parsing script ends with `});\n </script>\n </div>` in standard.html.
|
||||
# Actually, in standard.html, the script is inside `<div class="post-content ..."> ... </div>` which is inside `<div layout:fragment="content">`.
|
||||
# Let's just find the last `</script>` that is inside the content.
|
||||
# A better way: Replace the end of the script block that parses Editor content.
|
||||
# We know that script ends with `});` and `</script>`.
|
||||
|
||||
# In standard.html, `parseEditorContent` is not there. It uses `h.parentNode.replaceChild(p, h);`
|
||||
# Let's just put our switch_script right before `</body>` if it's NOT a layout decorated file? No, all 5 are decorated!
|
||||
# Wait, they are all Thymeleaf files with `layout:decorate`. So they must be put inside the `layout:fragment="content"`.
|
||||
# Let's just put the switch_script right after `var html = finalHtml; }` or just at the end of the `switch_script` in the parser script!
|
||||
# Yes! Why add a NEW `<script>` tag? Just append the JS code to the existing `<script>` tag!
|
||||
|
||||
# Let's find `parseEditorContent` or the end of the inline script.
|
||||
|
||||
# Let's just insert the plain JS right after `html = finalHtml;`
|
||||
js_code = """
|
||||
document.addEventListener('click', function(e) {
|
||||
if (e.target.classList.contains('custom-tab-btn')) {
|
||||
var btn = e.target;
|
||||
var container = btn.closest('.custom-tabs-wrapper');
|
||||
if (!container) return;
|
||||
var idx = btn.getAttribute('data-tab-idx');
|
||||
|
||||
container.querySelectorAll('.custom-tab-btn').forEach(function(b) {
|
||||
b.classList.remove('active');
|
||||
b.style.background = '#f8f9fa';
|
||||
b.style.color = 'black';
|
||||
});
|
||||
btn.classList.add('active');
|
||||
btn.style.background = '#0055a5';
|
||||
btn.style.color = 'white';
|
||||
|
||||
container.querySelectorAll('.custom-tab-panel').forEach(function(p) {
|
||||
p.style.display = 'none';
|
||||
});
|
||||
var activePanel = container.querySelector('.custom-tab-panel[data-tab-idx="' + idx + '"]');
|
||||
if (activePanel) activePanel.style.display = 'block';
|
||||
}
|
||||
});
|
||||
"""
|
||||
if "document.addEventListener('click', function(e) {" not in content:
|
||||
# Wait, if we removed it, it won't be there.
|
||||
# Let's just replace `html = finalHtml;` with `html = finalHtml;` + js_code
|
||||
content = content.replace("html = finalHtml;", "html = finalHtml;\n" + js_code)
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
print(f"Fixed script position in {filepath}")
|
||||
|
||||
Reference in New Issue
Block a user