Skip to content

Commit aac689e

Browse files
authored
Merge pull request #2698 from isAltoTech/add-coldfusion-documentation
Add ColdFusion (CFDocs) documentation
2 parents 5a03438 + c618f56 commit aac689e

7 files changed

Lines changed: 217 additions & 1 deletion

File tree

assets/javascripts/news.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[
22
[
33
"2026-07-03",
4-
"New documentations: <a href=\"/celery/\">Celery</a>, <a href=\"/rabbit_mq/\">RabbitMQ</a>"
4+
"New documentations: <a href=\"/celery/\">Celery</a>, <a href=\"/rabbit_mq/\">RabbitMQ</a>, <a href=\"/coldfusion/\">ColdFusion</a>"
55
],
66
[
77
"2026-06-02",
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
module Docs
2+
class Coldfusion
3+
class CleanHtmlFilter < Filter
4+
def call
5+
# Listing/category pages (Tags, Functions, a category, or a guide index)
6+
# use a different layout; keep their main container as-is after cleanup.
7+
@doc = build_root
8+
9+
# Remove site chrome and interactive widgets.
10+
css('nav', 'footer', 'script', 'noscript', '#cfbreak', '.newsletter').remove
11+
css('.modal', '.add-example-modal-lg', '.example-modal').remove
12+
css('.example-btn', '.copy-btn', '.issuebutton', '.issuecount').remove
13+
css('button').remove
14+
css('br').remove
15+
css('#search2').remove
16+
17+
# Drop the "Add An Example" / edit / fork affordances.
18+
css('a[href*="github.com"]', '#forkme', '#foundeo').remove
19+
css('a.label.label-danger').remove # Edit links
20+
21+
# Clean up the breadcrumb: keep the engine-version labels (they convey
22+
# ColdFusion/Lucee/BoxLang availability) but drop navigation links and
23+
# the issue tracker widget.
24+
if (crumb = at_css('.breadcrumb'))
25+
crumb.css('.label-warning').remove
26+
crumb.css('.divider').remove
27+
crumb.css('a[rel="nofollow"]').remove
28+
# Remove navigation breadcrumb items (CFDocs > Functions > cf45 > …)
29+
# that are not engine-availability labels.
30+
crumb.css('li:not(.pull-right)').each do |li|
31+
li.remove unless li.at_css('.label-acf, .label-lucee, .label-boxlang, .label-railo')
32+
end
33+
end
34+
35+
# Code blocks: tag them so DevDocs applies CFML syntax highlighting.
36+
css('pre.prettyprint', 'pre').each do |node|
37+
node.remove_attribute('class')
38+
node['data-language'] = 'coldfusion'
39+
end
40+
41+
# Inline code: nothing special needed, but strip prettyprint hints.
42+
css('code').each { |node| node.remove_attribute('class') }
43+
44+
# Unwrap Bootstrap `.container` layout wrappers; DevDocs supplies its own
45+
# page width, so these only add centering/padding we don't want.
46+
css('.container').each { |node| node.before(node.children).remove }
47+
48+
# Remove now-empty wrappers left behind by the source template's many
49+
# conditional blank lines.
50+
css('div', 'p', 'span', 'ul', 'ol').each do |node|
51+
node.remove if node.inner_html.strip.empty? && node.element_children.empty?
52+
end
53+
54+
doc
55+
end
56+
57+
# cfdocs splits an entry's content across the `.jumbotron` header (name,
58+
# description, syntax), the `.breadcrumb`, and the main `.container`
59+
# (arguments, compatibility, links, examples). Merge them into one root.
60+
#
61+
# NOTE: between filters the document is re-parsed as an HTML *fragment*
62+
# (there is no <body>), so selectors must not depend on `body >`.
63+
def build_root
64+
# First .jumbotron is the page header; #cfbreak is the trailing
65+
# newsletter jumbotron, which we ignore.
66+
header = css('.jumbotron').reject { |n| n['id'] == 'cfbreak' }
67+
.map { |n| n.at_css('.container') || n }
68+
.first
69+
breadcrumb = at_css('.breadcrumb')
70+
71+
# The main content container holds the reference sections. It is a
72+
# `.container` that is not the breadcrumb and not inside a jumbotron or
73+
# nav. Identify it by the section headings it contains.
74+
main = css('.container').find do |node|
75+
next false if node.matches?('.breadcrumb')
76+
next false if node.ancestors('.jumbotron').any? || node.ancestors('nav').any?
77+
node.at_css('h2, .param, .panel') || node.at_css('#examples')
78+
end
79+
80+
root = Nokogiri::HTML.fragment('<div></div>').at_css('div')
81+
root << header.dup if header
82+
root << breadcrumb.dup if breadcrumb
83+
root << main.dup if main
84+
85+
# Fall back to the full document/fragment if the expected structure is
86+
# missing (e.g. some guide pages).
87+
root.element_children.any? ? root : (at_css('body') || doc)
88+
end
89+
end
90+
end
91+
end
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module Docs
2+
class Coldfusion
3+
class EntriesFilter < Docs::EntriesFilter
4+
# Category/listing slugs that aggregate other entries and must not appear
5+
# as entries themselves. Categories generally end in "-functions" or
6+
# "-tags", but list the fixed index pages explicitly.
7+
INDEX_SLUGS = %w(index tags functions all).freeze
8+
9+
def include_default_entry?
10+
entry_page?
11+
end
12+
13+
def get_name
14+
if (h1 = at_css('#docname'))
15+
h1.content.strip
16+
elsif (h1 = at_css('h1'))
17+
# Guide pages: use the heading text without anchor noise.
18+
h1.content.strip
19+
else
20+
super
21+
end
22+
end
23+
24+
def get_type
25+
return 'Guides' if guide_page?
26+
27+
# Use the second breadcrumb link (Tags / Functions) as the category.
28+
crumb = css('.breadcrumb a').map { |a| a.content.strip }
29+
if crumb.include?('Tags')
30+
'Tags'
31+
elsif crumb.include?('Functions')
32+
'Functions'
33+
else
34+
'Guides'
35+
end
36+
end
37+
38+
private
39+
40+
# A real reference entry: a tag or function page. These have a `data-doc`
41+
# whose value matches the slug (no spaces) and usually a `#syntax` block.
42+
def entry_page?
43+
return false if index_slug?
44+
return true if guide_page?
45+
46+
doc_name = at_css('[data-doc]').try(:[], 'data-doc')
47+
return false if doc_name.nil?
48+
# Category pages have human titles with spaces (e.g. "String Functions").
49+
!doc_name.include?(' ')
50+
end
51+
52+
def guide_page?
53+
# Guides have no breadcrumb but do have content; they are neither tags
54+
# nor functions nor category indexes.
55+
return false if index_slug?
56+
at_css('.breadcrumb').nil? && at_css('h1')
57+
end
58+
59+
def index_slug?
60+
s = slug.to_s.downcase
61+
return true if INDEX_SLUGS.include?(s)
62+
s.end_with?('-functions', '-tags')
63+
end
64+
end
65+
end
66+
end

lib/docs/scrapers/coldfusion.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module Docs
2+
class Coldfusion < UrlScraper
3+
self.name = 'ColdFusion'
4+
self.slug = 'coldfusion'
5+
self.type = 'simple'
6+
self.base_url = 'https://cfdocs.org/'
7+
self.root_path = 'index.cfm'
8+
self.links = {
9+
home: 'https://cfdocs.org/',
10+
code: 'https://github.com/foundeo/cfdocs'
11+
}
12+
self.release = '2026-04-30'
13+
14+
html_filters.push 'coldfusion/entries', 'coldfusion/clean_html'
15+
16+
options[:root_title] = 'ColdFusion'
17+
18+
# cfdocs links categories with an encoded dash (e.g. /array%2Dfunctions);
19+
# decode and clean those so entry paths look like /array-functions.
20+
options[:decode_and_clean_paths] = true
21+
22+
# cfdocs.org renders a page for every tag/function/guide at the site root,
23+
# e.g. /hash or /cfhtmltopdf. Category "listing" pages (such as /tags,
24+
# /functions and /array-functions) are crawled to discover entries, but the
25+
# Entries filter excludes them from the index.
26+
#
27+
# Skip site chrome, utilities, reports and other non-reference pages.
28+
options[:skip] = %w(
29+
404.cfm contributors.cfm trycf.cfm ucase.cfm llms.cfm
30+
how-to-contribute opensearch.xml robots.txt)
31+
32+
options[:skip_patterns] = [
33+
/\Aassets\b/,
34+
/\Areports\b/,
35+
/\Autilities\b/,
36+
/\Aslack\b/,
37+
/openimage/,
38+
/\.json\z/,
39+
/\.png\z/,
40+
/\.ico\z/,
41+
/\.xml\z/,
42+
/\.css\z/,
43+
/\.js\z/
44+
]
45+
46+
options[:attribution] = <<-HTML
47+
&copy; 2012&ndash;present Foundeo, Inc. and the CFDocs contributors.<br>
48+
Licensed under the MIT License.<br>
49+
ColdFusion is a trademark of Adobe Systems Incorporated.
50+
HTML
51+
52+
def get_latest_version(opts)
53+
# CFDocs is continuously updated and has no formal version number; use the
54+
# date of the latest commit as a proxy version.
55+
get_latest_github_commit_date('foundeo', 'cfdocs', opts)
56+
end
57+
end
58+
end
725 Bytes
Loading
1.19 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://cfdocs.org/apple-touch-icon.png

0 commit comments

Comments
 (0)