CFML debugging: cfdump shown to specific site visitor

Here's a quick little snippet to show CFDUMP content only to your IP, without interrupting the flow of traffic for anyone else who may be using the same site:



<cfif cgi.REMOTE_ADDR is 'My.IP.Address.Here'>
<cfdump var="#form#">
<cfabort>
</cfif>

If you aren't sure of your outward-facing IP address, visit www.whatismyip.com

In this example we are dumping out the #form# scope, but you can dump out whatever you like (by changing the "var" attribute of the cfdump tag) or put any code at all inside the and it will only be executed for views from your specific location.

I wouldn't leave this in a live site but for a quick view of what's going on, without interrupting the experience of others, I find it quite useful.

Importing Events Calendar Data into Mura CMS

I needed a quick 'n dirty way to import an existing spreadsheet of events data into a Mura calendar. After a little trial and error, and much cobbling together of snippets from the Mura forums, here's my result.

Events from XLS data are imported into a table "temp_data" then gathered using the query below. This could be the base for a mura plugin, with an upload option and cfspreadsheet.

Before I ran the import, I created a custom extended attribute set and a page subtype of 'event listing', so we could import this client's custom data attributes.

I also made a parent page called 'events' and got the ID from the mura admin, which is used as the parent ID for all the new entries.

The page subtype is also hard coded below, you'll want to change that to match your own subtype (if not called 'event listing'), and remove the custom attributes stuff, or change those to match your own extended attributes for your events.

This is a crude-but-working example of adding custom attributes, categories, and the main content data all in a single pass, along with the 'start and stop' dates for each event, which I'll use on the front end to group and display the coming events (rather than using those dates to actually show or hide the content directly).

Ideally, the parent ID, site ID and other things would be set by the plugin or site you were working on. But for a one-time import this worked great.



<!--- IMPORT FROM TEMP TABLE --->
<cfquery name="dataQ" datasource="#application.configBean.getDatasource()#">
SELECT *
FROM temp_data
</cfquery>    

<!--- loop data, save content for each --->
<cfoutput>
    <cfloop query="dataQ">
        <cfset contentBean = application.contentManager.getBean() />
        <cfset contentBean.setSiteID('calendarsite')>
        <cfset contentBean.setType('Page')>
        <cfset contentBean.setSubtype('Event Listing')>
        <!--- data --->
        <cfset contentBean.setBody('#dataQ.eventName#') />
        <cfset contentBean.setTitle('#dataQ.eventName#') />
        <!--- to use display per start/stop dates, set to type '2' --->
        <cfset contentBean.setDisplay(2)>
        <cfset contentBean.setDisplayStart('#dateFormat(dataQ.datestart,'yyyy-mm-dd')#') />
        <cfset contentBean.setDisplayStop('#dateFormat(dataQ.dateend,'yyyy-mm-dd')#') />
        <!--- import categories from our data 'type' (this data only uses one category or 'type' per entry)--->
        <cfset c = trim(dataQ.type)>
        <cfset category = application.categorymanager.getBean("category").loadBy(name="#c#",siteid='calendarsite')>
        <!--- save category if not already available for this site --->
        <cfif category.getIsNew() eq 1>
            <cfset category.setName(c)>
            <cfset category.setSiteID('calendarsite')>
            <cfset category.save()>    
        </cfif>
        <!--- add category ID --->
        <cfset contentBean.setCategories(category.getCategoryID())>
        <!--- events custom attributes --->
        <cfset contentBean.setLocation('#dataQ.location#') />
        <cfset contentBean.setChannel('#dataQ.channel#') />
        <cfset contentBean.setLevel('#dataQ.level#') />
        <!--- events calendar parent id --->
        <cfset contentBean.setParentID('A48EAF6D-1EC9-549D-5210B43882960200')>
        <cfset contentBean.save() />
    </cfloop>

// #dataQ.recordCount# events imported //
</cfoutput>

I put that into a blank page called 'import.cfm' right in the root of this site, and pointed my browser at it... done!

Enforce 'www' prefix with .htaccess

On our Windows/ColdFusion servers at www.gowesthosting.com we run Helicon APE (and on our older servers, ISAPI Rewrite, also by Helicon) which lets you use standard Apache .htaccess files to create rewrite rules for any website. 

Here are a few quick useful snippets for rewriting any URL to include the 'www' prefix. This is good practice, preventing the 'duplicate content' penalty from Google which can occur when a site is available under two addresses, as well as forcing consistency to visitor sessions. This is especially critical in eCommerce sites where a user's session may not be persisted when jumping from a 'www' to 'non-www' page. 

 

RewriteEngine on
rewritecond %{http_host} ^domain.com [NC]
rewriterule ^(.*)$ http://www.domain.com/$1 [R=301,nc]

just replace "domain.com" with your actual domain, and you should see http://yoursite.com/ gets redirected to add the 'www' prefix automatically.

TIP: be sure to use the 'www' anywhere you link to your site, or when connecting any third-party services like PayPal, since a form 'post' from any external source will not be persisted if the page gets redirected. 

 

CKeditor options for Mura CMS (and other CK things)

Now that Mura has been using the new CKeditor (formerly FCKeditor) , I have been looking at the various configuration options available: 

http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html

These configuration options can be added to your styles.js.cfm , stored in the Mura file structure at
[siteid]/includes/themes/[theme]/js/editor/


Force HTTP:// prefix in url form inputs w jQuery

Here's a quick n' dirty way to make sure any URL in a form input starts with "http://"



    $('form input.url').keyup(function(){
        if (
            ($(this).val().length >
6) && ($(this).val().substr(0,7) != 'http://')
            || ($(this).val() == '')
            ){
            $(this).val('http://' + $(this).val());    
        }
    });

This ensures that the contents of the input will start with http://. The length > 6 is a bit of a hack, but if you delete everything in the field, or start typing over 6 chars (i.e. long enough to look for http:// at the beginning of the string), the prefix gets inserted for you. I am also loading my input with value="http://", but this could also be done w/ the function above by triggering it on page load rather than just on keyup for the specified input.

Adding Styles to Mura CMS Wysiwyg Editor

In the Mura interface you can select predefined text styles to add to your rich text content, right from the editor toolbar.

To extend the list of available styles is simple

Find the 'styles.js' file, usually at: \[site]\includes\themes\[theme]\js\editor\styles.js **

Then, add your styles, using the same format as those already in the file, for example



    { name : 'Caption Paragraph', element : 'p', attributes : { 'class' : 'caption-text' } },
    { name : 'Center Text', element : 'p', attributes : { 'class' : 'center' } },
    { name : 'Large Intro Paragraph', element : 'p', attributes : { 'class' : 'intro' } },
    { name : 'Image w/ Spacing', element : 'img', attributes : { 'class' : 'imageborder' } },

In general all you need to do is apply a class to an element. While you could provide other attributes, it is recommended to let your stylesheet handle those wherever possible.

** (Update: I had trouble with the browser caching this file, even on a forced reload. However, I found you can also use "styles.js.cfm" as the file name, and it will be included and updated as expected when making changes and refreshing the page)

As for how those actually look inside the editor window, the editor gets its CSS styles from a file

[site]\includes\themes\[theme]\css\editor.css

and, opening that you can see, below the long mura comment, something like


@import url(../../../../css/reset.css);
@import url(../../../../css/mura.css);
@import url(typography.css);

So as long as one of those imported files has a class to match your styles in the editor.js, e.g.


.caption-text{
font-size 11px;
padding:15px;
}
the style will be applied in the editor just as it will on the front end (presuming your display templates are using the same css files).

Fast easy 'current link' highlighting with CFML and jQuery

First the snippet (watch for line wrapping when copy/pasting this):



// current link highlighting
$('#topLinksNav a[href="<cfoutput>#listLast(cgi.script_name,'/')#</cfoutput>"]').first().addClass('currentLink').parents('li').addClass('currentLink');
// make sure top level link for this element is also highlighted
$('#topLinksNav ul').has('.currentLink').siblings('a').addClass('currentLink');

This finds any link with an 'href' attribute matching the name of your current page, e.g. "pagename.cfm" , and adds a class of 'currentLink' (note this is in a site where all pages are in the root directory - obviously this needs to be changed to match your site structure, but the same idea applies).

A sample of the ul/li menu structure I'm using is below.

Then you just need a CSS rule for the '.currentLink' class, perhaps



#topLinksNav li.currentLink{
set some background color here
}

or

#topLinksNav >
li > a.currentLink{
set a highlighted text color here only for top level links
}

Here's the sample menu structure for the syntax above something like



<ul id="topLinksNav">
<li>
<a href="index.cfm">Top Level Page</a>
<ul>
<li>
<a href="subpage1.cfm">Secondary Menu Page</a>
</li>
<li>
<a href="subpage2.cfm">Secondary Menu Page</a>
</li>
</ul>
</li>
<li>
<a href="contact.cfm">Top Level Page</a>
<ul>
<li>
<a href="subpage1.cfm">Secondary Menu Page</a>
</li>
<li>
<a href="subpage2.cfm">Secondary Menu Page</a>
</li>
</ul>
</li>
</ul>

Start and stop ColdFusion localhost with .bat files (Windows)

Here's a simple trick that saves a few clicks. If you are running a ColdFusion local server on a windows PC, you can start and stop the CF service with a simple bat file.

Make a new text file on your hard drive somewhere (i keep mine right on the desktop), and name it "cfstart.bat" - in your text editor of choice, enter this one line and save the file:

    NET START "coldfusion 9 application server"

(with the quotes, just like that)

You can make another called "cfstop.bat" and, you guessed it, 

    NET STOP "coldfusion 9 application server"

To use the files, on my Windows 7 PC, I just right click and select "Run as administrator", and the service stops or starts up right away. Now instead of running all the time, consuming memory, CF only runs on my local machine when i need it. 

Note: you may also want to remove the ColdFusion service from the list of items that run on startup - use start > run > mscofig to see the list.

 

 

Delay loading of ajax content with jQuery

I needed a function that would take the input of a form, show a loading graphic for a few seconds, and then load some content from an ajax page with jQuery load().

The loading is easy, but i had to experiment a little to get the right syntax for the 'wait a few seconds' part.

Here's what i came up with... this is all part of a function that runs 'onclick' from a link.

var loadingGraphic = '<img src="loading.gif">';
var gameContent = 'ajaxpage.cfm';

$('#gameSpace').html(loadingGraphic);

setTimeout(function(){
  $('#gameSpace').load(gameContent);
},2000);


this puts the loading graphic in place immediately with html(), and then waits 2 seconds before running the load() function to replace the contents via ajax. 

Mura CMS / CKeditor paste as plain text by default

Any developer who uses a CMS with a wysiwyg text editor knows the frustrations of clients pasting content from MS Word and other word processing programs directly into the editor, complete with unwanted styles, and even markup elements, causing all sorts of problems on our otherwise perfectly-formatted pages.

Mura CMS uses the ubiquitous CKeditor (formerly FCK) with a number of features enabled by default, including a "Paste as Plain Text" button. If clients remembered to use this, we would be all set. But, they don't.

Fortunately, there's an easy one-line fix.
Just open up [siteid]\includes\themes\[theme]\js\editor\styles.js

and paste in this line

CKEDITOR.config.forcePasteAsPlainText = true;

That's it. All pasting of content should now be clean, with extra styles and markup removed, just as if you had clicked "paste as plain text" in the editor toolbar. 

Adding Navigation Items to MuraCMS Admin

Here's a quick and easy enhancement you can make to the MuraCMS admin, adding links in the top-level navigation for quick and easy shortcuts to commonly-used sections of Site Manager.

Like so many things in Mura, the hooks already exist for this functionality, you just need to know what to put where. In this case, it is quite simple.

1. First, open up [siteid]/includes/eventhandler.cfc

2. Find the opening line <cfcomponent extends="mura.cfobject">, and paste these lines below it:

<cffunction name="onAdminModuleNav"> <cfargument name="event" /> <cfset var newLinks = ''> <cfsavecontent variable="newLinks"> <li><a href="index.cfm?fuseaction=cArch.list&siteid=... [shortened]">Blog Entries</a></li> <li><a href="index.cfm?fuseaction=cArch.list&siteid=... [shortened]">Photo Gallery</a></li> </cfsavecontent> <cfreturn newLinks /> </cffunction>

3. Change the <li><a> markup as needed, to insert the new links you want to create.
(In my examples above, I just copied the full URL from the admin view I wanted to link to.
There is probably a better way, dynamically generating the admin link by filename, but this works just fine, if your contentIDs stay intact.)

4. Save and upload the eventhandler.cfc, and reload the Mura application from within the admin - you should see the new links appear in your menu.

 

Some official Mura resources: 
http://docs.getmura.com/index.cfm/developer-guides/back-end-development/mapping-events-in-mura/

http://docs.getmura.com/developer-guides/back-end-development/plugins-event

More Entries

blogcfc 5.9.1.002 by raymond camden
contact michael evangelista