Skip to content

Commit f76d2e7

Browse files
committed
Update guides in wheels
Updated the guides in wheels to work in adobe coldfusion. Before it would throw error because of function redefinition.
1 parent 4ae7eae commit f76d2e7

File tree

3 files changed

+136
-138
lines changed

3 files changed

+136
-138
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
component {
2+
3+
public array function parseSummary(required string summaryPath) {
4+
local.nav = [];
5+
6+
if (fileExists(expandPath(arguments.summaryPath))) {
7+
local.summaryContent = fileRead(expandPath(arguments.summaryPath));
8+
local.lines = listToArray(local.summaryContent, chr(10));
9+
10+
local.currentSection = "";
11+
local.currentSubsection = "";
12+
local.currentItems = [];
13+
local.currentSubItems = [];
14+
15+
for (local.line in local.lines) {
16+
local.trimmedLine = trim(local.line);
17+
18+
if (!len(local.trimmedLine)) continue;
19+
20+
if (reFind("^##{1,2}\s", local.trimmedLine)) {
21+
if (len(local.currentSection)) {
22+
arrayAppend(local.nav, {
23+
"title": local.currentSection,
24+
"items": local.currentItems
25+
});
26+
}
27+
28+
local.currentSection = trim(reReplace(local.trimmedLine, "^##+\s*", ""));
29+
local.currentItems = [];
30+
local.currentSubsection = "";
31+
local.currentSubItems = [];
32+
}
33+
34+
else if (reFind("^\*\s+[^\[]+$", local.trimmedLine)) {
35+
if (len(local.currentSubsection) && arrayLen(local.currentSubItems)) {
36+
arrayAppend(local.currentItems, {
37+
"title": local.currentSubsection,
38+
"items": local.currentSubItems
39+
});
40+
}
41+
42+
local.currentSubsection = trim(reReplace(local.trimmedLine, "^\*\s+", ""));
43+
local.currentSubItems = [];
44+
}
45+
46+
else if (reFind("^\*\s+\[", local.trimmedLine)) {
47+
local.linkMatch = reMatch("\*\s+\[([^\]]+)\]\(([^\)]+)\)", local.trimmedLine);
48+
49+
if (arrayLen(local.linkMatch)) {
50+
local.title = reReplace(local.linkMatch[1], "\*\s+\[([^\]]+)\]\(([^\)]+)\)", "\1");
51+
local.link = reReplace(local.linkMatch[1], "\*\s+\[([^\]]+)\]\(([^\)]+)\)", "\2");
52+
53+
local.link = reReplace(local.link, "\.md$", "");
54+
local.link = reReplace(local.link, "^/", "");
55+
56+
local.linkItem = {
57+
"title": local.title,
58+
"link": local.link
59+
};
60+
61+
if (len(local.currentSubsection)) {
62+
arrayAppend(local.currentSubItems, local.linkItem);
63+
} else {
64+
arrayAppend(local.currentItems, local.linkItem);
65+
}
66+
}
67+
}
68+
}
69+
70+
if (len(local.currentSubsection) && arrayLen(local.currentSubItems)) {
71+
arrayAppend(local.currentItems, {
72+
"title": local.currentSubsection,
73+
"items": local.currentSubItems
74+
});
75+
}
76+
77+
if (len(local.currentSection)) {
78+
arrayAppend(local.nav, {
79+
"title": local.currentSection,
80+
"items": local.currentItems
81+
});
82+
}
83+
}
84+
85+
return local.nav;
86+
}
87+
88+
public string function renderGuideItems(required array items, required string currentPath) output=true {
89+
for (var item in arguments.items) {
90+
if (structKeyExists(item, "link")) {
91+
// Determine if the link is external
92+
var isExternal = reFindNoCase("^(http|https)://", item.link) > 0;
93+
94+
// Clean internal .md links
95+
if (!isExternal) {
96+
var cleanLink = lcase(reReplace(item.link, "\.md$", ""));
97+
var isActive = (arguments.currentPath == cleanLink) ? " active" : "";
98+
}
99+
100+
if (isExternal) {
101+
// External Link
102+
writeOutput(
103+
'<a href="#item.link#" target="_blank" rel="noopener noreferrer" class="item">#item.title#</a>'
104+
);
105+
} else {
106+
// Internal Guide Link (routed through /wheels/guides/)
107+
writeOutput(
108+
'<a href="/wheels/guides/#cleanLink#" class="item#isActive#">#item.title#</a>'
109+
);
110+
}
111+
112+
} else if (structKeyExists(item, "items")) {
113+
// It's a subsection/group
114+
writeOutput('<div class="header">#item.title#</div>');
115+
writeOutput('<div class="list">');
116+
writeOutput(renderGuideItems(item.items, arguments.currentPath));
117+
writeOutput('</div>');
118+
}
119+
}
120+
121+
return "";
122+
}
123+
124+
}

vendor/wheels/public/docs/guides.cfm

Lines changed: 11 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -7,123 +7,34 @@ param name="request.wheels.params.format" default="html";
77
local.docsPath = "/wheels/docs/src/";
88
local.summaryPath = local.docsPath & "SUMMARY.md";
99
10-
// Function to parse navigation from SUMMARY.md
11-
function parseSummary(summaryPath) {
12-
local.nav = [];
13-
14-
if (fileExists(arguments.summaryPath)) {
15-
local.summaryContent = fileRead(arguments.summaryPath);
16-
local.lines = listToArray(local.summaryContent, chr(10));
17-
18-
local.currentSection = "";
19-
local.currentSubsection = "";
20-
local.currentItems = [];
21-
local.currentSubItems = [];
22-
23-
for (local.line in local.lines) {
24-
local.trimmedLine = trim(local.line);
25-
26-
// Skip empty lines
27-
if (!len(local.trimmedLine)) continue;
28-
29-
// Main section headers: "# " or "## "
30-
if (reFind("^##{1,2}\s", local.trimmedLine)) {
31-
// Save previous section
32-
if (len(local.currentSection)) {
33-
arrayAppend(local.nav, {
34-
"title": local.currentSection,
35-
"items": local.currentItems
36-
});
37-
}
38-
39-
// Reset everything for new section
40-
local.currentSection = trim(reReplace(local.trimmedLine, "^##+\s*", ""));
41-
local.currentItems = [];
42-
local.currentSubsection = "";
43-
local.currentSubItems = [];
44-
}
45-
46-
// Subsection title (not a link)
47-
else if (reFind("^\*\s+[^\[]+$", local.trimmedLine)) {
48-
// If previous subsection exists, push it
49-
if (len(local.currentSubsection) && arrayLen(local.currentSubItems)) {
50-
arrayAppend(local.currentItems, {
51-
"title": local.currentSubsection,
52-
"items": local.currentSubItems
53-
});
54-
}
55-
56-
local.currentSubsection = trim(reReplace(local.trimmedLine, "^\*\s+", ""));
57-
local.currentSubItems = [];
58-
}
59-
60-
// Navigation items (Markdown links)
61-
else if (reFind("^\*\s+\[", local.trimmedLine)) {
62-
local.linkMatch = reMatch("\*\s+\[([^\]]+)\]\(([^\)]+)\)", local.trimmedLine);
63-
64-
if (arrayLen(local.linkMatch)) {
65-
local.title = reReplace(local.linkMatch[1], "\*\s+\[([^\]]+)\]\(([^\)]+)\)", "\1");
66-
local.link = reReplace(local.linkMatch[1], "\*\s+\[([^\]]+)\]\(([^\)]+)\)", "\2");
67-
68-
local.link = reReplace(local.link, "\.md$", "");
69-
local.link = reReplace(local.link, "^/", "");
70-
71-
local.linkItem = {
72-
"title": local.title,
73-
"link": local.link
74-
};
75-
76-
if (len(local.currentSubsection)) {
77-
arrayAppend(local.currentSubItems, local.linkItem);
78-
} else {
79-
arrayAppend(local.currentItems, local.linkItem);
80-
}
81-
}
82-
}
83-
}
84-
85-
// Final section/subsection flush
86-
if (len(local.currentSubsection) && arrayLen(local.currentSubItems)) {
87-
arrayAppend(local.currentItems, {
88-
"title": local.currentSubsection,
89-
"items": local.currentSubItems
90-
});
91-
}
92-
93-
if (len(local.currentSection)) {
94-
arrayAppend(local.nav, {
95-
"title": local.currentSection,
96-
"items": local.currentItems
97-
});
98-
}
99-
}
100-
101-
return local.nav;
102-
}
103-
10410
// Get navigation structure
105-
local.navigation = parseSummary(local.summaryPath);
11+
local.docsHelper = new wheels.public.docs.DocsHelper();
12+
local.navigation = local.docsHelper.parseSummary(local.summaryPath);
10613
10714
// Determine which guide to display
10815
local.guidePath = "";
10916
local.guideContent = "";
11017
local.guideTitle = "Wheels Documentation";
11118
11219
if (len(request.wheels.params.path)) {
113-
local.guidePath = local.docsPath & request.wheels.params.path & ".md";
20+
if(right(request.wheels.params.path, 3) eq '.md'){
21+
local.guidePath = local.docsPath & request.wheels.params.path;
22+
} else {
23+
local.guidePath = local.docsPath & request.wheels.params.path & ".md";
24+
}
11425
11526
// Check if file exists
116-
if (fileExists(local.guidePath)) {
117-
local.guideContent = fileRead(local.guidePath);
27+
if (fileExists(expandPath(local.guidePath))) {
28+
local.guideContent = fileRead(expandPath(local.guidePath));
11829
local.guideTitle = request.wheels.params.path;
11930
} else {
12031
local.guideContent = "Guide not found: " & request.wheels.params.path;
12132
}
12233
} else {
12334
// Default content - show introduction
12435
local.readmePath = local.docsPath & "README.md";
125-
if (fileExists(local.readmePath)) {
126-
local.guideContent = fileRead(local.readmePath);
36+
if (fileExists(expandPath(local.readmePath))) {
37+
local.guideContent = fileRead(expandPath(local.readmePath));
12738
local.guideTitle = "Introduction";
12839
} else {
12940
local.guideContent = "## Wheels Documentation\n\nSelect a guide from the navigation menu.";

vendor/wheels/public/docs/layouts/guides.cfm

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<div class="item">
3030
<div class="header">#sectionData.title#</div>
3131
<div class="list">
32-
#renderGuideItems(sectionData.items, docs.path)#
32+
#local.docsHelper.renderGuideItems(sectionData.items, docs.path)#
3333
</div>
3434
</div>
3535
</cfloop>
@@ -63,43 +63,6 @@
6363
</div>
6464
</div>
6565

66-
<cffunction name="renderGuideItems" access="public" returntype="string" output="true">
67-
<cfargument name="items" required="true" type="array">
68-
<cfargument name="currentPath" required="true" type="string">
69-
70-
<cfloop array="#arguments.items#" index="item">
71-
<cfif structKeyExists(item, "link")>
72-
<!--- Determine if the link is external --->
73-
<cfset isExternal = reFindNoCase("^(http|https)://", item.link) GT 0>
74-
75-
<!--- Clean internal .md links --->
76-
<cfif !isExternal>
77-
<cfset cleanLink = lcase(reReplace(item.link, "\.md$", ""))>
78-
<cfset isActive = (arguments.currentPath EQ cleanLink) ? " active" : "">
79-
</cfif>
80-
81-
<cfif isExternal>
82-
<!--- External Link --->
83-
<a href="#item.link#" target="_blank" rel="noopener noreferrer" class="item">#item.title#</a>
84-
<cfelse>
85-
<!--- Internal Guide Link (routed through /wheels/guides/) --->
86-
<a href="/wheels/guides/#cleanLink#" class="item#isActive#">#item.title#</a>
87-
</cfif>
88-
89-
<cfelseif structKeyExists(item, "items")>
90-
<!--- It's a subsection/group --->
91-
<div class="header">#item.title#</div>
92-
<div class="list">
93-
<cfoutput>
94-
#renderGuideItems(item.items, arguments.currentPath)#
95-
</cfoutput>
96-
</div>
97-
</cfif>
98-
</cfloop>
99-
100-
<cfreturn "">
101-
</cffunction>
102-
10366

10467
<!--- JavaScript for enhanced functionality --->
10568
<script>

0 commit comments

Comments
 (0)