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

Finding Available Mura CMS Content with getAllValues()

One of the first things I wanted to know as I started working with Mura CMS templates, is how I can dump out all the available variables.

I'm used to the versatility of CFML's CFdump tag, outputting the contents of any query or other CF object to the page for easy reading and reference as I wire up the css and html to display the dynamic content. In Mura, where everything is returned by a 'bean' via specifically named CF functions, cfdump doesn't always have the expected results.

For example, in a content-driven page in mura, dumping out #$.content()# will show the methods available, but not the actual values they'll return for the page you're working on.

In comes another Mura one-liner "getAllValues()". This can be attached to almost any Mura root-level object, to show all the values available, just as if you were dumping out the results of a single cfquery record, struct or nested array.

So, to get all the available goodies for a standard page or content-based item, simply add the getAllValues() function at the end of your cfdump:


<cfdump var="#$.content().getAllValues()#">

This also works for other Mura beans, such as a Mura feed:


<cfdump var="#variables.feedBean.getAllValues()#">

or any record being parsed by Mura's "iterator":


<cfdump var="#arguments.item.getAllValues()#">

or even the content of another page, by ID:


<cfdump var="#application.contentManager.getActiveContent('[content id]', '[site id]').getAllValues()#">

or by filename (the filename is the name of the content-node, same as seen in url):


<cfdump var="#application.contentManager.getActiveContentByFilename('[filename]', '[siteid]').getAllValues()#">

As I understand it, most of these values are directly available via the CF request scope, but dumping out #request# in mura is huge, and takes a while to dig through. GetAllValues() is the one you want.

The Mura Docs list a number of methods for getting content via the Mura API. I believe the getAllValues() method can be used with all of the 'read' functions.

Persist form values on reload w/ jQuery & ColdFusion

A designer friend presented me with a somewhatlong and complicated HTML form. It is a survey/contest entry for employees of a specific industry, with dozens of fields which include regular text inputs, text areas, and radio buttons.

My task is to create a routine to submit this form via e-mail and store the contents in the database. ColdFusion makes that easy with the built-in #form# scope. And for validation, I simply made his HTML < form > into a <cfform>, and all of the <input> and < textarea > elements into <cfinput> and <cftextarea>, adding 'required="true"' and a validation rule and/or message for each. Whipping up a quick server-side validation for the required fields was also a snap with CF.

Then it occurred to me - if there is in fact some error with the user submission, we will return the user to the form showing an error message at the top of the page.

However, unless we somehow persist the values that were entered, the form will be blank, and the user will no doubt be a little frustrated. This is a long form!

one method would be to create <cfparam> values for each element in the form, and then give each input the a value like value='#form.thisFieldName#" - that's common practice, and works great, but I don't want to do the tedious work. Also, I will be passing this form back to the designer, and don't want him to have to create the default value if he decides to change the names of any inputs, or at other input to the form.

So, I came up with this.

Assuming you already have jQuery in your page, this little block of code will loop through all of the posted values in the ColdFusion form scope, then, using jQuery, will assign the given value to any form element with a matching "name" attribute, allowing us to easily re-populate all the form fields in the page, in one fell swoop with javascript.

Since i only had input / textarea / select / radio button inputs, this just handles those types, but could easily be ammended to include checkboxes and more.

<!--- if form scope exists --->
<cfif isDefined('form.fieldnames')>
    <cfsavecontent variable="hcode">
    <script type="text/javascript">
    $(document).ready(function(){
    <cfloop list="#form.fieldNames#" index="ff">
    <cfset rawVal = form[ff]>
    <cfset ffVal = jsStringFormat(form[ff])>
    <cfoutput>
    $('input[type="text"][name="#lcase(ff)#"]').val('#ffval#');
    $('select[name="#lcase(ff)#"]').val('#ffval#');
    $('textarea[name="#lcase(ff)#"]').text('#ffval#');
    $('input[type="radio"][name="#lcase(ff)#"][value="#rawval#"]').attr('checked','checked');
    </cfoutput>
    </cfloop>
    //end jQuery
    });
    </script>
    </cfsavecontent>
<cfhtmlhead text="#hcode#">
</cfif>


Yes, this makes a big long looped jQuery script in the head of the user's page. But in this instance, it is working perfectly, with no noticeable slowing of page load, or other drawbacks that i can see.

jQuery Masked Input: change masking based on a selected value with unmask()

Along with standard jQuery form validation, the jQuery masked input plugin provides a really nice way to preformat user-entered text. For example, a phone number might be masked so that it always ends up in the format "(999) 555-1234", even if the user just types in 9995551234 .

There are a number of ways this can be applied to a form, including the formatting of credit card numbers. Along with jQuery's validation methods for minlength and maxlength, you may also want to make sure the values entered are numeric only, or perhaps break up the user-entered data into hyphenated blocks, i.e. "9999-1234-1234-1234". This works really well and from what I can tell, helps cut down on errors due to mistyped card numbers.

However, not all credit cards use the same format. Amex is 13, Visa and others 16... and I believe there are some 14 or 15 digit variations.  The brilliant and thoughtful masked input plugin provides two solutions to this issue:

1) Variable (flexible) masking
With a recent release, you can now add a ? character to imply optional trailing digits
So, for an input that should accept 13-16 characters, like a credit card number:
    $('#cc-number').mask("9999999999999?999");
The same works for the CCV code, which can be either 3 or 4 digits
    $('#sec-code').mask("999?9");

2) Change the mask based on a user selection
Also introduced in a recent version, we now have the "unmask()" function.

So, to change the masking format based on the selection of another field - in this case, the type of credit card - is very easy.

In my form, I have a select box with the id of #cardType, which allows the user to select the type of card, and the options have values such as 'visa,amex,disc', etc.

To adjust the masking based on the user's card type, we simply need to grab the value of the dropdown when it is changed - if the value is 'amex' , set the mask for 13 digits, and 4 for the ccv (amex standard). If otherwise, set it to 16 and 3 digits. }

Here's my code, using unmask():

    // change mask for cc type
    $('#cardType').change(function(){
        var ctype = $(this).find('option:selected').attr('value');
        if(ctype=='amex'){
            // amex masking
            $('#
cc-number').unmask().mask("9999999999999");
            $('#
sec-code').unmask().mask("9999");
        } else {
            // standard masking
            $('#
cc-number').unmask().mask("9999999999999999");
            $('#
sec-code').unmask().mask("999");
        }
    });



Once again a superbly elegant and simple solution via jQuery.
From here, you can easily edit these rules to allow for specific masks based on other values.

 

 

 

Filtering content in Mura CMS

In my ongoing adventures w/ Mura ColdFusion CMS , I have been setting up a calendar of events for a local tourism website.  A 'calendar' is a built in content type in Mura, with many options for showing and filtering the content.

For this calendar, we want our events to show up as soon as they are entered, remain on the site until 2 days after the event date has passed , and then be removed from view. So, we need a filter that compares the current date to a date two days in the future - easy with ColdFusion's dateAdd() function, but the trick was getting that function into the Mura "filter" settings.

Here's how I set it up:

1) create the calendar

- in site manager, click the "+" next to home page (or wherever) and choose 'add calendar'

- give your calendar a title, and click 'publish' (other details can be added as desired)

2) create the "content collection" to show the calendar's info

- click 'content collections' , then select 'add new Local Index'

- give it a name

-  next to the heading "Choose content from section:", click the (less than obvious) "[select section]" link , and type in part of the name of your calendar to search for that content**

- in the search results, click the "+" on the far right to add your calendar, making sure "include features only" is set to "no"

** this has been one of the key Mura admin concepts I've had to adjust to - this type of content search is used a lot in the admin, rather than dropdowns or other standard ways of presenting existing selections. It works well once you get used to it.

3) set up the filtering

- on the "advanced filters" tab, add two filters, with the following selections:

i) Start Date / Time : Greater Than or Equal To : [mura]dateAdd('d',2,now())[/mura]

ii) Or : Stop Date / Time : Greater Than or Equal To : [mura]dateAdd('d',2,now())[/mura]

The key was the use of The Mura Tag , which allows you to use any standard CF functions in place of a static value ( documentation here ) - in this usage, we are comparing today's date to a date 2 days from now (if you wanted to be more specific you could add 48 hours instead of 2 days ... or anything you like )

As I am quickly learning, Mura contains a number of filtering options for its content collections. I'm interested in seeing your examples if you've got 'em!

 

How to set up local vs. production settings for Mura CMS

In an effort to become acquainted with Mura CMS, I have been spending some time looking at the overall way the application is structured - what is included into what, where settings are stored or specified, and what the options are for modifying the default way things are done, in order to retain some of the in-house workflow concepts I have developed over the years.

One of the main aspects of my production workflow involves the easy use of both a local and live server, running from the same database. Generally, when starting a new ColdFusion project, I like to:

- Set up a local directory for the project, where i can work in the browser via a local host url
(something like http://172.16.17.5:8500/SiteName/wwwroot/  or http://localhost:8500/sitename/wwwroot )

- Set up a database on my live production server at www.GoWestHosting.com

- Create a DSN on the live server, pointing to the database

- Create a DSN on my local CF server, pointing to the same remote database

Now I can work locally and view my changes instantly without the need for FTP.

Or, as needed, I can push changes to the live site with a few clicks, and view the changes there as well (such as posting work for clients, or working with routines that require server-specific settings, launched from the site's "real" location)

My application.cfc contains both sets of DSN info, and uses a switch, based on the current cgi. server variables , to determine which DSN to run from, along with other server specific settings (such as google map key). So, wherever the site is viewed, my application 'knows' which content paths and other settings to use for each page request or query.

(So... what about MuraCMS?)

One of the first things I noticed when installing Mura locally was the way that it cached the local directory structure. So if my Mura site was installed in a subdirectory of the local site, e.g. http://localhost:8500/sitename/wwwroot/test/ , Mura would store the setting "/sitename/wwwroot/test" automatically, and prepend this path to all required assets. Wonderful. Superb. But...

Then I pushed the Mura files to the live server, uploading the works via FTP. And found I had a problem. That path was still being prepended to all assets... but didn't exist.
On the live server i was simply working from http://sitename.com/test/ , so everything was instantly broken - images, javascript, css.

Unlike my own usual practices, where all primary templates or pages live in the site root,  Mura is designed to use 'root relative' paths, rather than location relative, which makes sense if content will be served from different directory levels.

So instead of simply looking in ../css/ for a css file, it wants to use the path /sitename/wwwroot/test/css

(So... how did I fix this? Get to the point already... )

Half of any solution is identifying the problem. In this case, I needed to find out "how to use two different sets of configuration variables" , and set out to find the answer.

On setup, mura creates and populates a file called 'settings.ini.cfm', which is a simple text file with variables and values stored one per line. And inside, I could see the paths were being stored as text strings. Cool. Now I know where it lives... but how to change it on the fly, and keep two different versions?

I asked my question to the very friendly, patient guys on the Mura Show , but must not have asked correctly, or clearly enough. I came away thinking the solution was to set up a domain 'alias' and somehow map a direct IP to my subfolder locally , which doesn't work since you can't put paths in the Windows hosts file... and i got into a right frustrating mess.

Deciding to take another crack at it with fresh morning-coffee eyes, I got smart and did a bit of googling. And I found this, the settings.ini reference from the Mura site: http://docs.getmura.com/index.cfm/installation-set-up/settingsinicfm-reference/

and... AHA! a classic RTFM moment.

(finally... the fix !)

wouldn't you know it, the very first line of the settings.ini.cfm file is for the "mode", (which i completely overlooked before, and the Mura team must not have thought of in reference to my seemingly vague questions. )

The default mode is 'production' and beyond the first few lines, all settings in the file are under a heading of [production]. The light started coming on right about now... they really did think of everything!

So, all I had to do was create another grouping, and change that master 'mode' setting. I simply duplicated all the lines below [production], added a new heading of [localdev] , and changed the settings to match those of my local server. (I also changed 'production' paths to match the settings of my live production server with the simpler root directory structure)

Just a few more steps - upload the changed file to the live server, and click 'reload application' in the Mura admin.  Then, change my local copy of the settings.ini.cfm file to 'mode=localdev' , and click 'reload application' in my local admin as well.

This caused the local settings to be loaded for the local site, and the production settings to be loaded for the production site ... and i am back in business, working in both locations with ease!

Bearing in mind that any uploaded images will need to be manually copied with FTP, and some other things might need a little hand-holding, I am very pleased to be back in business with the freedom to work the way I am used to, with live, functioning copies of the complete site on both my local server and the live location.

The only caveat at this stage - I'll have to be careful not to upload the settings.ini.cfm file, since I still don't have an 'automatic' switch for which group of settings to use. But as long as my production version of the file says "mode=production" and my local file says "mode=localdev" , I should be good to go.

 

Tools to Live By: ClearContext plug-in for Outlook

I've used MS Outlook for a few years now, as part of my GTD-ish system for tracking tasks, appointments, and of course email messages. After quite a while of using a tricked-out routine using some variations on the built-in outlook categories (those colored dots that outlook lets you tack onto any message, task or appointment), along with the usual gazillions-of-folders for projects, customers, billing, personal messages and every other possible categorization of outlook info - all managed by clicking and dragging messages and tasks here and there - I went looking for a better solution... and I am so glad I did.

Enter "Clear Context" from http://www.clearcontext.com/ - this little add-in makes such a big difference to my day. While it boasts a long list of features ( see the user guide, here: http://www.clearcontext.com/user_guide/ ), I'll touch briefly on the ones I use the most, and let you see for yourself why i am so excited about this tool.

1) Folders as 'projects'. ClearContext analyzes your Outlook folders and uses those as the basis for what it calls 'projects'. The entire application runs based on those folders - replacing outlook's somewhat limited category options with a limitless number of options for filing. When i get a new client or project, i create a folder, and once i've put a message from a client in that folder, CC 'suggests' that future messages from the same person go there as well. Unlike regular message folders, these same project/folder names are applied to your tasks, and CC's easy 'dashboard' view lets me see all messages, tasks, attached files and contact information for anything in that folder or related to that 'project'.

2) Put stuff where it goes with keyboard shortcuts, and smart suggestions. With any message highlighted, i can hit ctrl+shift+m for an intuitive list of likely folders where this message belongs (ClearContext gets to know who you put where and suggests it back to you, becoming more accurate as time goes on). So, without taking my hands off the keys, i can file an entire day's worth of email in a matter of seconds. This is big, and the way it works is super slick.

3) Defer / Unsubscribe. These are two separate features but both of them serve the same purpose - getting things out of your face that you don't want to see! With a single click i can 'defer' any message for a set number of hours or days, or until a set time and date - it is removed from view, and at the set time, it comes back to my inbox as a new message. So, if stuff piles in for 'later' while i am working on correspondence for 'now', i can defer everything else until i am ready to deal with it, and don't even have to look at it until then. 'Unsubscribe' uses the message subject to create a rule which puts all messages using that same subject line into a special folder 'clear context deferred', which i look at and then empty to deleted items every few days. This is also huge - repeat emails, junk alerts, group messages where i am bcc'd but really don't need to be - they all go away, never to be seen, clicked or managed again (unless i want to ... then they are easy to find) 

4) Tasks from messages. More keyboard shortcuts, or a click on a single toolbar icon, allows me to create an outlook 'task' from any message. Even if I file or delete the email message (which i often do, once a task is made) , CC saves a task with the due date i specify, and the email text as the body of the message, with the original message attached. This makes it uber-easy to look through my to-do list , by category, and see what needs to be done. If i mark the task complete, or delete it, the original message is still where i put it, for future reference, without the need to refile it from 'to do' to the project it belongs to. This is incredibly useful for the way i work, and the way i use Outlook.

5) Do not disturb. Turns off auto send/receive for a limited time, and hides the 'you have mail' icon along with any sounds related to same. Click that, leave me alone, I am working.

6) Follow-up. When sending any message, there's an easy option to 'follow up'. This creates an automated alert, again at a time and/or date i specify, which is automatically cancelled when somebody replies to the message (lots of options there for who must reply to cancel the follow-up, etc) . If i send off a proposal (or even more importantly, a bill) and want to make sure the client receives it , I simply click the follow-up button and can put the whole thing out of mind. If the client replies, the alert is cancelled - if they don't, i get reminded to follow up. Super simple, super useful. 

Overall, my goal is to keep things organized and my inbox empty so i don't have to think about any of it. By making easy to file and find all email messages, tasks and other important 'to do' data, I can free my 'mental RAM' from carrying those things around, and focus on whatever i am doing at the time. (Now, what was I doing... ?)

If you use Outlook's tasks, or file your messages by folder, or just like to keep your inbox clean, I suggest you take a test drive (30 day free trial, $89.95 to buy w/ money-back guarantee) of this super useful, well-maintained and carefully implemented add-in. 
You can also check in with other users in the active, well-supported Clear Context forums: http://online.clearcontext.com/forums/  to find how it can help you get more done.

 

 

jQuery AJAX get() function cached in IE

From the 'how the heck were we supposed to know this?' department, a little tidbit I'd like to share, perhaps saving some poor, frustrated developer from the same type of mystifying madness:

jQuery "get()" operations are cached in IE unless you pass in a unique URL !

By cached, I mean, you can have a remote page with a query or other function, which responds to a unique set of values being passed in, and it will work fine in Firefox, but in IE, you'll get the same results from the remote page, even if the response is unique (like query results that have changed, for the same record), unless the values you are passing in via get() are also unique (i.e. you haven't looked up that particular record yet).

So, before you go banging your head on the floor and screaming out 'why oh why can't i find the problem, let alone the solution?!?' (not that i would ever do that), read this post, which i found via a quick Google search for 'jquery get IE cache' : http://www.sitecrafting.com/blog/ajax-ie-caching-issues/ 

I only had the presence of mind to run that search once i got my ajax results to display as an alert on the calling page, and deduced that the displayed content was based on the first values passed in, while all other updates and requests were ignored.

The fix, as that post suggests, is to create a unique url. In this case, i use javascript to append a random number to my function, - in this case, I just use javascript to create a random number right inline, then add that as a meaningles url variable to the page in the get() function:

                           // set up unique url
                            var randomNo = Math.floor(Math.random()*9999999);
                            var urlStr = 'journalLookup.cfm?r=' + randomNo;
                            // run get function using randomized URL
                            $.get(urlStr,{jdate:dateLookup}, function(data){  .... [ function here ]

If this saves you some aggravation, let me know in the comments ... maybe i'll feel better about the time i just wasted chasing this mystery 'feature' in IE!!

 

More Entries

blogcfc 5.9.1.002 by raymond camden
contact michael evangelista