), elements using an ID, and classes if you use a '.' to prefix the class name.
Usage to remove our postData tag that indicates that LD+Json is being used: removeStr(value, "postData")
Usage to remove the 'foo' class from a string: removeStrBetween(str, '.foo');
*/
var removeStrBetween = function(str, selector) {
// Create a new container to operate on
var wrapped = $("
" + str + "
");
// Remove the content between the tags.
wrapped.find(selector).remove();
// Return it
return wrapped.html();
}
// Function to truncate and add an elipsis if the text exceeds a certain value
function truncateWithEllipses(text, max) {
return text.substr(0,max-1)+(text.length>max?'...':'');
}
function stripHtml(html){
html.replace(/<[^>]*>?/gm, '');
return html;
}
// Determine if a string has a space
function hasWhiteSpace(s) {
const whitespaceChars = [' ', '\t', '\n'];
return whitespaceChars.some(char => s.includes(char));
}
// ColdFusion like string functions
// ReplaceNoCase, scope is either 'all' or 'one'.
// Gregory Alexander
function replaceNoCase(string,subString,replacement, scope){
if (scope == 'all'){
// i is a RegEx ignore case flag, g is global flag
var regEx = new RegExp(subString, "ig");
} else {
// i is an RegEx ignore case flag
var regEx = new RegExp(subString, "i");
}
// i is an ignore case flag, g is global flag
var regEx = new RegExp(subString, "ig");
var result = string.replace(regEx, replacement);
return result;
}
// ColdFusion like list functions
function listLen(list, delimiter){
// Gregory Alexander
if(delimiter == null) { delimiter = ','; }
var thisLen = list.split(delimiter);
return thisLen.length;
}
function listGetAt(list, position, delimiter, zeroIndex) {
// Gregory Alexander
if(delimiter == null) { delimiter = ','; }
if(zeroIndex == null) { zeroIndex = true; }
list = list.split(delimiter);
if(list.length > position) {
if(zeroIndex){
// Better handling for JavaScript arrays
return list[position];
} else {
// Handles like the CF version without a zero-index
return list[position-1];
}
} else {
return 0;
}
}
function listFind(list, value, delimiter) {
// Adapted from a variety of sources by Gregory Alexander
var result = 0;
if(delimiter == null) delimiter = ',';
list = list.split(delimiter);
for ( var i = 0; i < list.length; i++ ) {
if ( value == list[i] ) {
result = i + 1;
return result;
}
}
return result;
}
// Compares two lists of comma seperated strings. Used to determine if the selected capabilities match the default capabilities for a given role. Function based on the listCompare method found in cflib.
function listCompare(string1, string2){
// Adapted from a variety of sources by Gregory Alexander
var s = string1.split(",");
for(var k = 0 ;k < s.length; k++){
if(string2.indexOf("," + s[k] + ",") ){
return true;
}
}
return false;
}
// Adds a value to a comma separated list. Will not add the value if the list already contains the value.
function listAppend(list, value) {
// Adapted from a variety of sources by Gregory Alexander
var re = new RegExp('(^|\\b)' + value + '(\\b|$)');
if (!re.test(list)) {
return list + (list.length? ',' : '') + value;
}
return list;
}
// Removes a value to a comma separated list. Based on the ListDeleteValue function by Ben Nadel CF fuction https://gist.github.com/bennadel/9753040
var listDeleteValue = function(list, value){
// Adapted from a variety of sources by Gregory Alexander
var values = list.split(",");
for(var i = 0 ; i < values.length ; i++) {
if (values[i] == value) {
values.splice(i, 1);
return values.join(",");
}
}
return list;
}
// URL functions
//
// parseUri 1.2.2
// (c) Steven Levithan
// MIT License
/*
Splits any well-formed URI into the following parts (all are optional):
----------------------
- source (since the exec method returns the entire match as key 0, we might as well use it)
- protocol (i.e., scheme)
- authority (includes both the domain and port)
- domain (i.e., host; can be an IP address)
- port
- path (includes both the directory path and filename)
- directoryPath (supports directories with periods, and without a trailing backslash)
- fileName
- query (does not include the leading question mark)
- anchor (i.e., fragment) */
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};
Cfblogs.org has had some major updates in the last couple of months.
I incorporated several suggestions made by the incomparable Chalie Arehart. I already have the ability to filter personal blogs, Adobe/Lucee and Ortus blogs, and software-related blogs, such as my own Galaxie Blog documentation site. However, Charlie pointed out that the Adobe, Lucee, and Ortus sites have two different types of sites: blogs and forums. The Adobe and Ortus blog posts occur occasionally; however, user-generated forum threads can be much more prolific and support-related. Charlie wanted the ability to filter community-related forum threads and company-related blog posts.
I also added a site search feature that lets users filter by a search term. This should be useful, as there is a lot of data and posts dating back to 2006!
I have also added several new blogs. Please reach out if you have another blog you'd like added or any other suggestions!
Galaxie Blog 2025 Year In Review
2025 was a great year for Galaxie Blog. Other than adding CSS gradient support for the hero section, I met most of my 2025 goals. The performance goals were accomplished- Galaxie Blog is now one of the fastest open-source blogs anywhere! I also made significant progress in incorporating CMS features over the last year.
2026 Galaxie Blog Roadmap
External Page CMS
While CMS features are abundant in Galaxie Blog and nearly everything can be customized, it still lacks the ability to create external pages. I can manually create external pages by hardcoding the page's content; however, they are not database-driven and can't be created in a visual interface. Over the last several months, I have been developing interfaces that allow blog owners to easily create sophisticated external pages using a WYSIWYG editor. I hope to have this new functionality done in the coming year.
New Widgets
Galaxie Blog already supports a wide variety of media, including images, videos, carousels, galleries, Azure Maps, and other rich media; however, I want to create additional widgets, such as event calendars, photography-oriented galleries, sign-up forms, forum functionality, and more. I may also look into creating e-commerce custom carts this year.
New Layouts
Galaxie Blog has over 30 themes that use major layouts: the classical two-column layout used with many blogs, including BlogCfc, and a modern layout with a single column and a background. Every major element can be independently sized horizontally. After I finish creating a few new widgets, I hope to introduce several new layouts that divide the page vertically and horizontally. However, these new layouts will depend upon the new widgets that I hope to introduce, and I may not be able to get to them this year.
Future Plans
I want to eventually investigate using AI to convert the tag syntax to cfscript. Additionally, I still plan to enhance image capabilities, add forum support, and potentially create a BoxLang version, but these plans are not achievable in the upcoming year.
2026 Blogging Roadmap
My blogging focus over the next year is to do a better job documenting Galaxie Blog. I have been planning to diversify a bit and write more non-technical web-tech articles; however, I plan on creating a series of technical articles on how to incorporate TinyMCE into web pages.I also hope to share some of my photography once I finish a new gallery widget for photography.
Hi, my name is Gregory! I have several degrees in computer graphics and multimedia authoring, and I have been developing enterprise web applications for the last 25 years. I love web technologies and the outdoors and am passionate about giving back to the community.
This entry was posted on February 21, 2026 at 9:03 PM and has received 10 views.