Wednesday, 29 July 2015

CFB profiles and Preferences

CFB profiles and Preferences

Profiles is one of my favourite features of CFB3. It allows you to keep separate preferences as schemes(profiles we call it). For example when you are developing or writing code, you want to see your comments in yellow but when you demo your application you want to keep your comments in grey so they are not catchy. You don't have to change your comment colors always but you just have to switch your profile. To be specific you can maintain different color schemes, code-assist preferences, typing preferences, task tags, outline and syntax checking preferences with different profiles. For most developers modifying these small preferences increase their productivity, so trust me these are very helpful.

Here we will talk about how to maintain different profiles and also a bit about all these preferences that you can modify and play with and will be starting with Code Assist Preferences. To find them in CFB open Window->Preferences in your menubar. A preferences dialog will open. On left panel you have to reach to "ColdFusion->Profiles->Editor->Code Assist". On clicking it, in right panel you will see all related preferences.

Code Asisst:
For most of preferences, you will be able to understand what they do by their name, like in case of Code Assist they will help you modify what you see in code assist and how you get it and some related stuff. BTW code assist is the small popup you get regarding code when you are typing it. You can also forcefully call code assist by pressing ctrl+space. If you want to try it right now, go to some closing tag, remove part of it from end and hit ctrl+space, you will get a popup suggesting to auto complete that tag. Now quickly moving to the preferences.

  • Code Assist Dictionary version: you can select which ColdFusion server version you are running your code. You never want tags/functions in code assist which will not work for your version of ColdFusion.
  • Reload Dictionaries: In case you have modified the dictionary, you can reload them to reflect changes.
  • Cycling Code Assist Proposals: type "<cfset x = " and hit ctrl+space, you will get some suggestions for variable names, but what if you wanted to type a function here. If cycling is enabled, on hitting space 2 times, you will get functions suggestions. The funda is keep ctrl pressed and keep hitting space until you get correct suggestion.
  • Filter proposals containing text: On typing "<cfa" you will get suggestions like "<cfabort>, <cfajaximport>", all of them starting with "cfa". If this is enabled, you will also get "<cfbreak>" because it has c,f,a characters in it. Filter proposal CONTAINING text.
  • Automatically display Code Assist when typing: pretty simple, if enabled, you start typing and you will see code assist wherever necessary, otherwise you have to hit ctrl+space everytime.
  • Automatically display SQL Code Assist when typing: same as above, just that this is applicable if you are typing in sql editor.  If you do not know whats sql editor, then type this shortcut while typing, "ctrl+alt+W S"
  • Delay before showing code assist(in milliseconds): As name says, code assist popup will open after this many milliseconds.
  • Automatically insert a single proposal: Say you type "<cfoutpu" and call code assist(by hitting ctrl+space), you will get a popup with one proposal called "<cfoutput>", and then you hit enter on it to insert it. That is a overhead if it was a single proposal, you can directly insert it without getting a popup, it was anyways a single proposal. Enable this option to directly insert single proposal without getting a popup.
  • Automatically insert a closing tag: If you insert a tag from code assist when typing starting tag and this preference is enabled, then closing tag will be autoinserted.
  • Insert closing tag on a new line: enable this if you want closing tag on next line.
  • Append space after inserting selection: a space will be appended on insertion of proposal, it helps if you add a lot of attributes by code assist.
  • Automatically insert equals sign: equals sign will be appended automatically after attribute name is selected from proposal.
  • Auto insert required attributes: name itself explains, type "<cfhtt", call code assist, hit proposal cfhttp, see url attribute is added on its own, because it's a required attribute, I can't think of a scenario, when you will use cfhttp without typing url attribute.
  • Automatically quote attributes: On selecting attribute proposals, if enabled, you will automatically get quotes after equals sign. And it will not work if you have disabled auto insert equals sign.
  • Character to use when quoting attribute: If you quotes attributes values with single quotes, you have an option to do that here, auto quoting will quote with character you specify here.

Outline: You can see the outline of your file in Outline view. Shortcut: "Alt+Shift+Q O", or "WIndow->Show View->Outline" in menubar. Outline gives you brief summary of tags/functions used in your file and on clicking on a particular tag/function in outline, it will take you to your particular code where it is used. It is very helpful in very long files.

  • Show All tags: By default, you will get all tags in your outline view.
  • Show selected tags: Or you can chose which all tags to show in outline. You can add or remove the tags you want.

Syntax Checking: In case you made a typo while typing or you inserted a wrong attribute, wont it be beautiful to know right there that something is wrong with code before even running your file on server. Syntax checking helps you in that.

  • Enable syntax checking: enable or disable this feature.
  • Display syntax errors only on file save: if enabled, it will check for errors only on file save. You can enable this for better performance.

Task Tags: Task tags are very useful while coding. Suppose you are building a feature and for testing purposes you have hardcoded a path, but ideally in production server you want to manipulate it and make it safe. You can insert a "TODO" task by typing "<!--- TODO --->"(or "// TODO" in cfscript) where you have hardcoded path. Later on before moving your project to production, you can open Tasks view and check all the TODO tasks you have left pending in your code.

  • By default there are two tasks: TODO and FIXME are provided but you can add your tags too and there is no limit on that. You can also select/modify the priority of the tasks, If high priority is selected, then in Tasks view, red exclamation mark will appear in front of your task.

Typing: Some preferences which will help you while typing.
Enable Auto insertion: This is a parent preference for following six preferences. If disabled, auto insertion of matching character will not be performed. Like on typing a double quotes, another double quotes following it is automatically inserted.Or on typing {, } this will be automatically inserted.

  • Double Quotes: typing " will insert following " on its own.
  • Similarly we have Single Quotes, Round brackets, Curly Brackets, Square brackets, Pound sign.
  • Auto close tags: When to auto close the starting tag. You can disable this by  choosing never.
  • Auto-indent on carriage return: If enabled, on hitting enter, a "TAB" will be automatically inserted on new line. It helps in beautifying the code.
  • Auto adjust indentation on closing tags: If you typed closing tag with wrong indentation, if enabled, it will adjust the indentation according to the starting tag.
  • Replace whitespace with indentation character: If you are editing a legacy file, it might be possible that whitespaces are used for indentation, enabling this preference will replace those characters with indentation character wherever you edit. This indentation character can be specified in Formatter preferences.

Syntax Coloring: Syntax Coloring is one the most important feature of any editor. CFB gives you option to have different colors for different language. Like you can keep comments in yellow for ColdFusion but grey in HTML or JS. You can do chose colors for CFML, CFScript, HTML, JS, CSS. But all these colors will be applied in CFML or a CFC page. If you are editing a html file(file with extension html or htm) or JS file(file with extension js), these settings will not be applied. For that you need to refer "HTML->EDitor->Syntax Coloring" in left pane or "JavaScript->EDitor->Syntax Coloring" or "CSS->EDitor->Syntax Coloring".

  • We have two panes in these preferences. In left pane you will see tree of keys like Tag key under CFML or Attribute Name under CFML and so on. If you a select a key under a particular langauge, then on right pane you will see few preferences you can change. Like foreground color, Enable option, Bold, italic, Underline, Strikethrough options. With these you can controll each and every keys behavior in detailed manner. 

I will not discuss each and every key as their names pretty much explains them. You just need to play with them to understand it.

  • One more important feature in Syntax Coloing is importing and exporting colors. CFB2 colors are not compatible with CFB3, so importing CFB2 colors will not work. On exporting .col file will be generated with all the color information. Similarly to import colors, a compatible .col has to be provided.

Since we are done with all the preferences, I will explain the Profiles page. In profiles page you will see a drop down listing all the profiles. And Active profile will be selected. CFB comes with 4 default profiles which you will not be able to modify or delete. These are CFB1, CFEclipse, Dreamweaver and default(ColdFusion Builder's own) profiles, we call these as system profiles. So in case you have  migrated from dreamweaver to CFB, you must be used to dreamweaver's shortcuts or coloring scheme, just select dreamweaver profile, hit apply and all settings, colors, shortcuts will be applied as they are in dreamweaver. Pretty solid feature isn't it? Well that's for default profiles, but you can create your own custom profile too.
To create a custom profile, hit "Create New Profile", it will ask for a profile name and ofcourse you cannot name of system profile. On creating a new profile, all the settings in it will be copied from currently active profile. So if dreamweaver profile is active, and you created a new profile, all the dreamweaver's profile preferences will be copied in this new profile.
When you make any changes in the preference pages falling under profiles page, all these changes will be saved in your custom profile. So if your custom profile is selected, and you have changed the dictionary version, then even on restarting Builder, this setting will persist, which I think is the expected behaviour of Profiles. There is a catch in saving profile, if any system profile is selected let's say dreamweaver, and you change any preference under profiles, let's say you change dictionary version, then this settign will be saved(as expected). But earlier I said system profiles cannot be changed, so will they not be persisted? Don't worry, they will be. In this case a new profile will be created for you called "custom" and all the new changes will be saved in this custom profile. Now if you will try to change this profile, it will ask you whether you want to save this custom profile. So you can mistakenly delete or loose your preferences as it will always ask you to save or discard the changes first.
As I said, its pretty important and strong feature, play around it, you will enjoy it for sure.

Friday, 28 February 2014

CF New Mobile Project - Templates

You must be hearing about the mobile story in CF11, well yes, that is Huge. And if you haven't tried it yet, you are definitely missing a lot. Go on, try it but wait, don't you need a getting started tutorial. I bet you don't, only if you know that ColdFusion is providing templates for mobile project. Yes, you heard me right, templates. Isn't that great, you will get pre-baked code for your application. If you know what kind of application you want to create, just chose a template and wow! your application structure is ready. Alright, so now if you are interested enough to see how this works just read along otherwise still read along, I am sure you will feel like using it.

First thing first, this template feature is available in CFBuilder and being said that let me make you aware of the importance of CFBuilder3 with ColdFusion11. With CFB3 you will feel the actual power of mobile in CF11. Why is that? because with CFBuilder you can start right from scratch, use templates to create a mobile project, use builder's code assist to help you with new mobile functions, create a packaged application for iOS/Android, download it and install, DEBUG it from you device, inspect it with WEINRE and so much...

Now coming to the template feature, here are the steps you need to perform before you can try it.

  1. Install CFBuilder3
  2. ColdFusion server will be installed with it(if you opt for it while installation)
  3. Start CFBuilder
  4. Create a New Mobile Project
This is where you will see a template page. Just to get you familiar with, here is a screenshot.

Notice I have marked the areas of screenshot so it will be easier to refer them while explaining. I know the red markers look ugly but please bear with me. I'll explain area one by one
  1. System Templates: These are the templates provided by ColdFusion. Right now there are only few templates but with future releases you may enjoy more templates here.
    Very first template listed is Blank. You can opt this template if you don't want to go with the other templates provided by ColdFusion. This template will create index.cfm in your project, with just cfclient tags in it and you are free to create app the way you want. This will be the default template selected every time you open this wizard.
    Second one is Master-Detail template. This is a pretty common and famous one in mobile devices. The index.cfm generated using this template will contain all the required code to show a basic master-detail UI in page/device-app. The settings page in smartphones is a very good example of such a layout. Initially you will get a list of items, called as mater page and on clicking on an item, you will see details about it, called as detail page.
  2. User Templates: If you want much more than default templates, this is just the right section for you. You can create your own templates and use them every time you create a project. Even more, you can share it in ColdFusion community to let CF developers take full benefit of it. I will talk more about creating your own template in separate section.
  3. Type: After selecting a template, this is where you can select the type using which you want to create the template. With each template there could be multiple types associated. There are many libraries available to create mobile apps like JQuery Mobile, bootstrap etc.. So it's possible to create same layout using different libraries which is why multiple types with each template. You can chose the one you like. By default the very first type listed will be auto-selected. Once you select the type, Next button in wizard will be enabled and you can navigate to next page.
  4. Description: This is where you will read the description about the template. Description changes according to your selection of template and type.
  5. Import: You can import the templates too, be that your self created template or community shared template. Once imported you will see the template added in User Templates section, chose it and create your project.
  6. Next: Next button will be enabled if both the Template and it's respective Type is selected. By default Blank template and None type will be selected. Once done, navigate to next page.

Creating custom template
Before I start on creating custom template let me tell you that where these templates are saved. Both System templates and User templates are picked from this path: CFBuilder_installation_directory/templates/mobile/

You will see two directories in it, System and User. System directory is to keep templates provided by ColdFusion and the User one is to keep User templates. For further reference I will refer these as System Template directory and User Template directory.

At beginning User Template directory will be empty but System Template directory must be containing few templates. Though you can refer the the templates present in it but I will recommend not to change anything in it.

Templates are supported in both zipped and directory format. So let's start with the directory format because for zipped format all we need to do is zip the template directory. Follow the steps

  1. Create an empty folder, give it a name of your choice(can be used as template name in case name not provided in configuration file).
  2. Create config.xml file in it. Config file is used by CFBuilder to scan through valid templates and their information. Here is a sample code for config.xml
    • The name of the template will be picked from root element template attribute name. If name is absent then directory's/zipped-file's name will be shown as template name.
    • Description will be read from description element, child of root element. This description will only be shown if type specific description is missing.
    • type element inside types will be used for specifying type information. The name of the type will be picked form attribute value. The type description will be picked from description element present as child of type. If this description is missing then generic description will be shown.
    • You can give as many types as you want.
    • We map each type to a directory, so there should be a directory present in parallel to config file, with the same name you have specified in value attribute of each type. For this example there should be 2 directories present namely: JQuery Mobile and Bootstrap, each directory mapping to each type. Any extra directories kept parallel to config file will be ignored
    • If the directory is missing for a type then that particular type will not be listed in Type section.
    • On successful completion of project, the directory that is mapped to type will be exploded in your project. Files/Folders present in this directory will be copied to your project location.
    • There should be at least one type mentioned in config.xml with mapped directory present otherwise template will be considered as invalid.
  3. As specified in previous steps create required directories parallel to config.xml
  4. In directories(created in previous steps) create the files/folders you want in your project. If index.cfm is present here then on successful completion of project it will be opened for you automatically.
  5. Place the directory you created in step one inside User Templates directory or you can use import feature of wizard. I will recommend to use import functionality, that way you will know if your template is valid or not. If your template is not valid and you have placed it in User Template directory by yourself, then your template will not be listed in wizard. 
  6. To import you have to create a zip file of your template. Create a zip in a way that zipped file should directly contain config file and directories that are mapped to type.
  7. From import section of wizard, press import, browse to zipped template you have created and wola! If it was a valid template then you will get successful message otherwise a descriptive error about the problem with your template.
  8. Template that you imported in previous step will be copied to User Template directory, in case you want to check. And no need to close CFB or wizard, just after importing you can see your template right under User Templates.

After this I think you are good to go. Once you will create your project, you will see your template files in project and you can test it either by running it as ColdFusion application or creating a packaged app and installing it in device. For other details like packaging application or debugging it or inspecting it, keep looking for more blogs but I think this is good point for you to start. Go on now, build your apps.


Wednesday, 9 January 2013

Javascript Date Time parsing rules

Though these rules vary from browser to browser but still I am trying to put basic rules which are implemented by majority of popular browsers. To be on safer side please try these in your browser first.

JavaScript by default uses a simplified version of the ISO 8601 extended format to convert strings to Date objects

You can specify strings to construct Date objects either with Date(dateStr) or with Date.parse(dateStr). JavaScript first attempts to parse a date string by using the ISO format. If the date string is not in that format, JavaScript attempts to parse the date by using other date parsing rules.

The ISO format is a simplification of the ISO 8601 extended format. The format is as follows:
To return a date in ISO format, you can use the toISOString.

If a date string is not in the ISO format, JavaScript uses the following rules to parse it.
Short dates
  • The format must follow the month/day/year order, for example "06/08/2010".
  • Either "/" or "-" can be used as a separator.
Long dates
  • The year, month, and day can be in any order. "June 8 2010" and "2010 June 8" are both valid.
  • The year can have two or four digits. If the year has only two digits, it must be at least 70.
  • Month and day names must have at least two characters. Two character names that are not unique are resolved to the last matching name. For example, "Ju" specifies July, not June.
  • A day of the week is ignored if it is inconsistent with the rest of the supplied date. For example, "Tuesday November 9 1996" resolves to "Friday November 9 1996" because Friday is the correct day of the week for that date.
  • Hours, minutes, and seconds are separated by colons. However, some of the parts can be omitted. The following are valid: "10:", "10:11", and "10:11:12".
  • If PM is specified and the specified hour is at least 13, NaN is returned. For example, "23:15 PM" returns NaN.
  • A string that contains an invalid date returns NaN. For example, a string that contains two years or two months returns NaN.
  • JavaScript supports all standard time zones, and Universal Coordinated Time (UTC) and Greenwich Mean Time (GMT). (The ISO format does not support time zones.)
  • Text enclosed in parentheses is treated as a comment. The parentheses can be nested.
  • Commas and spaces are treated as delimiters. Multiple delimiters are permitted.

You may find this link useful - ECMA script date time string format

Friday, 13 July 2012

Axis-2 and Axis-1 compatibility issues

 Axis-2 and Axis-1 compatibility issues


With ColdFusion 10 you can leverage power of Axis-2 WebServices. But you might get into issues if you are mixing Axis-2 with Axis-1. Axis-2 services are incompatible with Axis-1 services in ColdFusion because of the way their WSDL's are formed. Though by design Axis-1 and Axis-2 are compatible but in ColdFusion you might run into issues if you are using ColdFusion complex data types.

Since Axis-1 and Axis-2 are incompatible in ColdFusion, this means that if you are publishing your WebServices using Axis-2, then they should be consumed using Axis-2 only. Similarly if you are publishing your WebServices using Axis-1 then they should be consumed using Axis-1 only.

ColdFusion 10 Solution:

ColdFusion has taken all the measures to support backward compatibility with it's earlier versions. ColdFusion allows you to specify the version of Axis in which WebServices should be published or consumed. ColdFusion has given a control at three levels:
  1. Server level
  2. Application level
  3. Component level


  1. Server level: In ColdFusion 10 WebServices administrator page there is a new setting called as wsversion. This setting defines the default version of Axis that will be used to publish the WebServices in ColdFusion if you have not specified it at Application/Component level.

    Default value of this setting is set to '2', which means by default your WebServices will be published using Axis-2. You can anytime change it to '1' if you are facing the problems.

    This will be very handy if you are consuming all your WebServices from ColdFusion 9. In ColdFusion 9 Axis-2 is not supported and hence your WebServices will be consume by Axis-1 only, so that is why if all your WebServices are consumed in ColdFusion 9 then you can set this to default '1' for whole server.
  2. Application level: In Application.cfc you can specify an attribute as this:

    <cfset this.wssettings.version.publish = "2">

    Setting this attribute at Application level will ensure that all WebServices in this Application will be published using this version of Axis if not overridden at component level.
  3. Component level: In you WebService component (mywebservice.cfc) you can specify this attribute as this:

    <cfcomponent wsversion="1">Specifying this attribute will ensure that this WebService will be published using Axis-1


ColdFusion understands that WebServices could be published from any platform and can be consumed from CF so to make it easy CF automatically detects if the service is published in Axis-2 or Axis-1. If it's published in Axis-2, CF will consume it using Axis-2 unless overridden and same goes for Axis-1 too.

You can however override this behavior if you are very sure of the published verison, at two levels:
  1. Application level: In Application.cfc you can specify an attribute as this:

    <cfset this.wssettings.version.consume = "2">Setting this attribute at Application level will ensure that all WebServices in this Application will be consumed using this version of Axis if not overridden at component level.
  2. Invoking level: While invoking the WebService you can specify an attribute 'wsversion' to tell CF from which version the Service should be consumed.

    <cfinvoke webservice = "http://localhost:8500/mycfc.cfc?wsdl" method="echo" wsversion="2" returnVariable="foo" >

I am sure that if you read this post, you will never stuck in Axis-1/Axis-2 compatibility issues.
Specially it is a must for any user who is publishing WebService as in ColdFusion 10 but consuming them in ColdFusion 9 or earlier releases. It's because in CF 10 by default Axis-2 will be used whereas in earlier CF releases only Axis-1 was supported, so you might run into issues if will not take measures.

ColdFusion 10 WebServices - Axis2 vs Axis1

I have seen many people getting confused between Axis-2 and Axis-1 WebServices in ColdFusion 10. ColdFusion 10 has added the support for Axis-2 WebService, earlier till ColdFusion 9 only Axis-1 WebServices were supported.

So to begin with what exactly is this Axis-2 and Axis-1.

Intro Axis:
Apache Axis (Axis-1) is an open source, XML based Web service framework. ColdFusion internally uses Axis to publish and consume WebServices.  Apache Axis-2 is a complete re-design and re-write of the widely used Apache Axis but achieves same purpose. Axis-2 supports many new and flexible features over Axis-1 which means ColdFusion has implemented it not only to provide you latest features like Soap1.2 but also to give you more flexibility and power in your hand. You can always search for 'Axis-1 vs Axis2' if you want to study the advantages of Axis-2.

New in ColdFusion 10
 So let's see what ColdFusion 10 is offering with Axis-2
  1. SOAP 1.2 support (SOAP 1.1 was there with Axis-1) 
  2. WSDL2 support
  3. Wrapped styled WSDL support
  4. Easy switching from Axis-2 to Axis-1 and vice-versa.

Taking these points one by one.
  1. SOAP 1.2 support - SOAP is a standard protocol specification for exchanging messages and 1.2 is it's latest version. Being a ColdFusion user you should not worry about the implementation part but you should know that now you can consume much wider range of WebServices and also publish for a much wider userbase.
  2. WSDL2 support - WSDL is a standard XML format to expose your WebServices to outer World. Versoin 2 is the latest version of WSDL and now with ColdFusion 10 you can leverage it. Implementation is as expected way too simple.
    The WebService WSDL links are like these : http://myip/mywebservice.cfc?wsdl

    The WebService WSDL2 links are like these : http://myip/mywebservice.cfc?wsdl2
    Now to consume these WebServices using WSDL2 format just update the WSDL link by appending a numeric '2' in the end and you will be done. No change required from publishing side.
  3. Wrapped styled WSDL - A user who has already used WebServices in any platform might be aware of terms like RPC style, Document-literal, Document-wrapped style WSDL. WSDL publishing formats could be in either of these widely used formats. Earlier RPC and Document-literal styles were supported but now Document-wrapped style is also supported.To use this a style attribute is provided at two level: Application level and Component level.
    1. Application level:
      <cfset = "Wrapped | Document | RPC">
    2. Component level:
      <cfcomponent wsversion="2" style="Document | Wrapped | RPC" >
      For in-depth details about new attributes in ColdFusion 10 WebServices read this blog here.
  4.  Easy Switching - Axis-1 and Axis-2 has few compatibility issues because of their architecture which means if you are publishing in Axis-1, it has to be consumed by Axis-1 only and if a WebService is published in Axis-2 then it has to be consumed using Axis-2 only. ColdFusion is well aware that the users could face problem because of this behavior. So to it make very easy for users, ColdFusion 10 has taken few steps which are discussed in detail in this blog here.

    You may also like reading this ->

Monday, 18 June 2012

Node.js to ColdFusion - REST api

In my earlier post I explained how to expose a pdf service using ColdFusion REST api here.
In that post we saw that from the client side if I will pass a html document to this service it will convert it into pdf document and will return it back to the client. Also in my earlier post I gave an example to consume it using CF client itself. But there are times when your client side may not be ColdFusion. For that purpose I am giving an example to consume it using Node.js

Node.js server will act as a client over here and will contact ColdFusion to convert a document into pdf document.

Let's take a look at the code.

/*---code starts---*/
function handlepdf(data) {
var http = require('http');
var fs = require('fs');

var options = {
  host: CFip,
  port: CFport,
  path: '/rest/services/pdf',
  method: 'POST',
  headers: {
   'Accept': 'text/xml'
 var req = http.request(options, function(res) {
  var allchunk = "";

  res.on('data', function (chunk) {
   allchunk += chunk;
  res.on('end', function () {
   var file = allchunk;
   fs.writeFile( 'sample.pdf', allchunk, 'base64', function(err) {
    if(err) {
     } else {
     console.log("The file was saved!");
/*---code ends--*/

Now lets understand the code:

I have written a function handlepdf(data), which accepts the html document as an argument. You can call this function as a callback handler for any event you like.

In this function I am making a http call to ColdFusion server because finally http request is all required for REST to work. I am setting the options of this request to match the CFC I created in my previous blog here

  1. method - post
  2. ip - CF server ip
  3. port - CF server port
  4. path - rest/services/pdf
  5. accept header - "text/xml"
Now moving ahead there is another function which will be called when this http.request will be ready.
In this function I am initializing a variable "allchunk", this is the variable where our complete pdf will be saved.
And on res.on('data'), I have called another function. This function will be called whenever data will be received on response of this request. Inside this function I am appending all the data to 'allchunk'.

One more way to do this was I could have taken allchunk in res.on('data') function itself but the limitation with that approach is that sometimes if the file is big then the response comes in small chunks several times. So using the above used approach will give you complete file.

Once I recieved complete file then on res.on('end'), I am writing this file from server itself, you can however pass to any client. For writing this file I am using filesystem package and writing it with encoding base64. Please take care of the encodings used while calling http request and saving the file otherwise your file could be corrupt.

In the end I am writing the html data in request and closing it, which will call function we have discussed above.

And extremely sorry for incomplete code of node.js but I just wanted to focus on calling ColdFusion part.

Sunday, 17 June 2012

ColdFusion html to pdf service - rest api

Convert a html document to PDF using ColdFusion <cfdocument> and REST power.

If you are not sure about how to start with REST, you can read my blogs here.

So let's write a CFC which will be exposed as pdf service using REST api.

Over here we have exposed a ColdFusion component as a REST resource - pdf, which will accept an html body and will return a pdf file in binary.

In the only function present, I am accepting POST request and will produce the content in "application/xml" format. POST request will be accepted because my httpmethod attribute in the function is POST and produces attribute is "application/xml" so it will produce xml content.

There is a point to note that even though I am producing xml content but still the produced string will not contain any xml tags. That is because ColdFusion only serializes the return variable in xml/json if it is complex variable like an Array, a Struct, a CFC etc.. As we are producing a binary which is a simple data type, so it will not be serialized rather will be returned as it is.

For consuming the data I am looking for argument in body of the request. Generally you will find the restargsource attribute present in <cfargument> tag to tell you where to look for the data. But if it's absent ColdFusion looks for the argument in the body of request.

Inside the function I am using <cfdocument> tag to convert the HTML body passed from client into PDF file. This PDF file will be saved in a variable name "pdffile" in binary format. And then returning this pdffile as it is in binary format back to the client.

Client side can be written in any language but here I will write an exmaple in ColdFusion itself.

All we need to do in client side is to call this service with POST http request and pass the HTML content in the body of the request.
In this example I am reading a html file from local directory and passing it's content to the service we just exposed.
And finally we are saving the result we have got back to sample.pdf

That's it. We are done.