Category : Resources

zfHow to Create an Image Slider Using Foundation Orbit and Reveal Modal

How to Create an Image Slider Using Foundation Orbit and Reveal Modal

Are you having trouble finding an image slider for your images? Why not try making one for yourself quickly using Foundation Orbit and Reveal Modal. The process is straight forward and quite simple. Although, there are many ways to do this, but here’s the one that I’ve used:

As my project was based on Ruby on Rails, here’s how my models were related:

User ← Album ← Photo

Album model holds all your albums, while Photo model holds all your images. You may wanna save different versions of your image, as I’ve saved ‘profile, medium and giant’ version of my images.

Before we get started, I will assume, you are familiar and have configured Foundation in your Rails app. If not, go through the following links:

Configuring foundation in rails: https://github.com/zurb/foundation-rails

Foundation Reveal Modal http://foundation.zurb.com/docs/components/reveal.html

Foundation Orbit http://foundation.zurb.com/docs/components/orbit.html

Ok, now lets get started!
Step 1: First of all, list all of your images in your view:

#/albums/show.html.erb
@photos.each do |photo|
# display a thumbnail version of your image here
=image_tag photo.photo.profile
 end
#/albums_controller.erb
def show
@album = current_user.profile.albums.find(params[:id])
@photos = @album.photos
end

Step 2: You may want to associate link_to with your images, So upon clicking, you could show up your images in a Reveal Modal. Also remember to define your Modal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#/albums/show.html.erb
 @photos.each do |photo|
 =link_to user_album_photo_path(current_user, @album, photo), remote: true do
<div class="thumbnail">
= image_tag photo.photo.profile
<div class="caption">
<h3 class="title text-center">=truncate(photo.title, length: 50) </h3>
</div>
<div class="thumbnail-filler"></div>
</div>
 end
 end
<div id="photo_modal" class="reveal-modal small" data-reveal="">
</div>

Set remote: true, so we could make ajax call to the server
Step 3: In the corresponding controller, define your action as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#PhotosController
def show
@user = current_user
@album = @user.albums.find(params[:album_id])
<a name="__DdeLink__0_1861686962" id="__DdeLink__0_1861686962"></a> @photo = @album.photos.find(params[:id])
respond_to do |format|
format.html
format.js
end
end

And define the corresponding js and html file as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<a name="__DdeLink__2_1861686962" id="__DdeLink__2_1861686962"></a> #/photos/show.js
$('#photo_modal').html('=j render 'photos/orbit_photos', album: @album, photos: @album.photos')
$('#photo_modal').foundation('reveal','open');
#/photos/show.html.erb
<div id="photos">
= image_tag @photo.photo.giant
</div>

Step 4: Define your partial file ‘orbit_photos’, which contains code for Foundation Orbit for your images:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#/photos/_orbit_photos.html.erb
<div id="photo_container">
<ul class="orbit-photos" data-orbit="" data-options="pause_on_hover: false; timer_speed: 4000; animation_speed:1500; slide_number: false; next_on_click: true;">
 photos.each do |photo|
<li>
<div class="text-center">
<h2 class="page-header">= link_to(photo.title, user_album_photo_path(current_user, album, photo)) </h2>
= link_to(image_tag(photo.photo.medium), user_album_photo_path(current_user, album, photo))
</div>
</li>
 end
</ul></div>

You can customize your orbit differently, by passing different attributes in data-options, you should reference Foundation Orbit documentation for more details.

Step 5: Now, you are almost done, but you may get different issues with your slider, now lets deal with them. Your images could be of different sizes, so, set options variable height equal to true for Orbit:

1
2
3
4
5
6
7
#/photos/show.js
$(".orbit-photos").foundation(orbit: {
variable_height: true,
});

Also, as images are dynamically loaded to Reveal modal, you may want to adjust its size, after orbit-photos have been loaded into it:

1
2
3
4
5
$("#photo_modal").on "opened", ->
$(window).trigger "resize"
return

 

That’s all folks, the image slider is all set!

Read More
Migrate-Data-From-PostGres-to-MySQLHow to Migrate Data From PostGres to MySQL on a Remote Server for a Ruby on Rails Application

How to Migrate Data From PostGres to MySQL on a Remote Server for a Ruby on Rails Application

When it comes to migrating data from postgres to mysql, a developer might face some compatibility issues for which finding the right solution becomes a hectic task. I went through a lot of hassle when migrating data of an application from postgres local server to a remote mysql cloud based server. This small step by step process will guide you through the practical solution of how to migrate data when such a situation arises.

Assuming you have mysql installed on the remote machine and access to cmd interface on local server.

1. Access your localmachine/local server with postgres database using from terminal using the following command:

run ssh -X username@localserver.ip.addresss -p

2. Navigate to the rails application folder:

cd var/data/myapplication

3. There are two options to export your data:

a) Using Postgres dump command from terminal:

pg_dump -h localhost -p 5432 -U postgres -F p -b -a -f "/path/to/file/for/dumping/examplefile.sql" databasename

where

-h= –hostname e.g. localhost

-p= –port (usually 5432 for postgres)

-U= –Username is the database username (default postgres)

-F p= –format=format Selects the format of the output. format can be one of the following

p plain : Output a plain-text SQL script file (the default).

c custom : Output a custom-format archive suitable for input into pg_restore.

d directory : Output a directory-format archive suitable for input into pg_restore

-b=–blobs Include large objects in the dump. This is the default behavior except when –schema, –table, or –schema-only is specified, so the -b switch is

only useful to add large objects to selective dumps.

-a=–data-only Dump only the data, not the schema (data definitions). Table data, large objects, and sequence values are dumped.

-f=–filename is the file name with path where to dump the data. (Create the examplefile.sql before hand at the path)

For more information on pg_dump extensions visit: http://www.postgresql.org/docs/9.3/static/app-pgdump.html

b) Using the GUI of Posgtres my admin:

– Open terminal and run:

 pgmyadmin3

– When the GUI is open, Connect to the database server using the login credentials for your account

– When connection is made, press the + sign on the hierarchical menu and go to the public directory

– Right click, from options choose Backup from bottom

– A new window appears, Enter the name of file, and options from different tabs including plain format, blobs and excluding privileges, owner name etc

– Make sure to check data only options in the second tab to extract only data from the tables, and column inserts in column inserts options

– Select all /required tables for which data needs to be exported

– When you have chosen the desired options, press Ok button and the data will be generated in the external file

4. Now that postgres dump file has been created there is a need to convert the data to mysql compatible format:

– Download pg2sql.tar.gz2 from http://www.lightbox.ca/pg2mysql.php (you may copy paste the code from the data file to the online version of the converter but for large data files, copy pasting is not a desirable option so its better to use the local copy of software)

– unzip the files to some directory using command | tar xjvf pg2mysql-1.9.tar.bz2 (in my case the directory was /tmp, and the file was also dumped to /tmp folder)

– Go to the pg2mysql folder using command | cd /tmp/pg2mysql-1.9

– To convert the examplefile.sql to mysql compatible format run command in the pg2mysql directory:

php pg2mysql_cli.php /tmp/myexamplefile.sql /tmp/myexamplefile_mysql.sql innodb

Command format is = php pg2mysql_cli.ph /[path-file-to-convert] /[output-file-path-with-name] [engine]

In case you get an error (in my case I did) running the pg2mysql_cli.php, do the following:

-emacs pg2mysql.inc.php [you may use any other editor like vi]

-Press Ctrl+S, and search for &$ , change it to $ only as in newer versions of php, & will be a deprecated option with the code

-Press Ctrl+X+S to save changes and then Ctrl+X+C to exit emacs

-re run the php command in the last step and wait till your file is converted

-You may view the converted file using command | less /filepath/filename.extension

5. Now that the file is converted on your local server, copy the file from there to the cloud project directory using SCP or RSYNC Command from local server:

scp /tmp/rmyexamplefile_mysql.sql cloudhostname@ip.addrress.of.cloud.instance:/tmp

6. Now log in to the cloud server using the login credentials using terminal (In our example we used Google Cloud).

7. Copy file from temporary folder to the upload folder of PHPMyAdmin (Default directory to upload PHPMyAdmin import files):

cp /tmp/myexamplefile_mysql.sql /var/lib/phpMyAdmin/upload/

8. Considering you have mysql2 gem installed in your cloud application, and config/database.yml file of rails app filled with correct database user credentials, to create your database tables automatically, Go to your application directory and run database migrations based on your environment. In case of plugins in application, make sure to run plugin migrations separately as well:

rake db:migrate RAILS_ENV=production

9. Migrations may have some dummy data present in the tables so its a good practice to truncate any default data to upload the converted mysql2 data:

 mysql -uUSERNAME -pPASSWORD -Nse 'show tables' DATABASENAME | while read table; do mysql DATABASENAME -uUSERNAME -pPASSWORD -e "SET FOREIGN_KEY_CHECKS=0;truncate table $table;SET FOREIGN_KEY_CHECKS=1;"; done

10. Now that tables are truncated, you may import the myexamplefile_mysql.sql data file which is mysql2 compatible. File may be chosen from upload directory using PHPMyAdmin UI view but if the files are large >8 MB, it may create problems in uploading them directory. Its recommended to use command line interface:

mysql -uUSERNAME -pPASSWORD DATABASENAME

This takes in username, password and database name to upload the file, takes in the path to file and uploads the data to the tables no matter how large the file is.

11. Now that the file is uploaded, restart mysql service on the cloud instance and you are ready to use the database with the application:

sudo /etc/init.d/mysqld restart

This effort will surely help you save a lot of time and hassle of migrating database from postgres to mysql. This blog will also give you basics of how to work with terminal to upload large import files to mysql/phpMyAdmin, manually truncate databases, and copying files between servers and systems.

Make sure to transfer files between servers you have the right permissions (e.g. ssh keys added to permissible list of keys). Feel free to give your comments or imporvements in the steps if you feel are important.

Read More
developer-tools_0Web Developer Tools: A Must Add-on for Web Development

Web Developer Tools: A Must Add-on for Web Development

Web Developer tool, is the add-on for your firefox, chrome, seamonkey browsers. It gives you extra tools to debug your website, HTML, layout, javascript and even images. It lets you control your browser’s cache and cookies etc. as well. Following is a quick overview of how this can be useful to you:

Disable

Cookies

CSS

Forms

Images

Information

Miscellaneous

Outline

Resize

Tools

View Source

Options

Installation

1. Choose your browser, compatible browsers are firefox, chrome and seamonkey. 2. Follow the link Web Developer Tools  3. Click the button “Download Now” and it will download and install for your browser. You need to restart your browser to make it work. Special thanks to developer of this tool.

Read More
significant-doc-signingSignicat Authentication and Document Signing in Ruby on Rails

Signicat Authentication and Document Signing in Ruby on Rails

Signicat is an e-id authentication service provider that operates in Europe and extends that functionality further by providing users the ability to electronically sign and store documents. They provide authentications for several others e-id’s as well, the complete list can be seen here.

They have plentiful resources and documents on how to integrate their service into your website however I found it really difficult to make the ends meet with the help of those documents, as most of them are good as individual problem solvers but don’t help much in the bigger picture.

I will give several references and links to their documentation here but the problems I faced in finding the links and connecting the dots will be ironed out in this document.

Furthermore their code is in C# and/or Java which is translated to ruby.

When everything fits together it works great and looks easy, but putting it together is the hard part. So buckle up.

 

Starting Off

We will be authenticating a user through Signicat. This exercise will also help in listing down what is needed and in knowing how to get a user for this testing and how these processes work.

 

Creating a Test User

We can create a fully working application but to know if its truly working we will need some test users for credentials authentication. For this document I will use Nem-id’s. The information stored in the response received from Signicat depends on which e-id is used for authentication.

The link mentioned below explains in detail how to get the users in working order:

https://support.signicat.com/display/SUP/NemID,+creating+test+users

However just skip the first step, and instead of filling the form in second step, use ‘Autofill’ button.

Once the user is good to go, we need to authenticate him through the service (this was the point of creating him in the first place to test our application with his credentials).

‘https://env.signicat.com/std/method/service?id=method:profile:language&target=target

Quick brief on what is what in this url. The blue part is all generic and the colored ‘RED’ part is explained in different paragraph for each ‘RED’ placeholders.

Env: is just telling signicat what environment you are currently running. Test is for development and test phase for production it is replaced with ‘id’

Service: name of your service, for testing ‘Shared’ is used once you get the service name for which you have paid for it should be replaced with the service name, as it is configured separately for each service and might need to be adjusted. Code that worked on shared doesn’t necessarily will work on production (trust me it happened and after emailing with Signicat the service was adjusted to our needs, PHEW!!!).

Method: it specifies which e-id provider credentials the user will provide, for the scope of this article I will use ‘NEMID’.

Profile: is the name of the graphical profile, you would like to use. If you don’t have a graphical profile, you can omit the value and the default profile will be used. I in my case used default, that doesn’t interfere in any way and is a good place holder for future in case one does use a profile.

Language: the language that the interface will be shown in. Its better to use a language one is comfortable with and once everything is finalized then change the language as required.

Target: It’s the URL on which the response from Sigincat would be received. This method would be an encoded URI.

More can be read on this here.

 

What to do With the Response Received

What received is SAML 1.1 response (if authentication is successful), and it will be received on the target url described above, so it will have a proper route defined. In my case I have a controller whose action receives the response. Now how that response is handled is a different story, because it does need to be translated into a readable format because SAML can’t be used directly.

I used Omniauth-SAML gem for this purpose, all was good and hay, the response was being translated but the problem occurred when the SAML was being validated. All the gems I came across were build for SAML 2, and Omniauth-SAML will throw an error in validating the translated response, so I had to hack the gem or should I say remove the ‘validate’ part (wink, wink).

My hack involved overriding the ‘callback_phase’ function in the GEM and commenting out the validate part, I am commenting it out here and not entirely removing it because it was later included with change in validation policy, I won’t go into that because it is out of scope of this article, and right now we should be focusing on running the application so we can concentrate on how the data will be used in our application I did was to store the information in the Database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require 'omniauth/strategies/saml'
module OmniAuth
module Strategies
class SAML
def callback_phase
unless request.params['SAMLResponse']
raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing")
end
response = Onelogin::Saml::Response.new(request.params['SAMLResponse'], options)
response.settings = Onelogin::Saml::Settings.new(options)
node = REXML::XPath.first(response.document,
"/Response[@ResponseID='#{response.document.
signed_element_id}']/Assertion/AttributeStatement/Subject/NameIdentifier[@Format='#{
options[:name_identifier_format]}']")
@name_id = node.text#response.nem_id
@attributes = attributes_patch(response)
if @name_id.nil? || @name_id.empty?
raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing 'name_id'")
end
# response.validate!
super
rescue OmniAuth::Strategies::SAML::ValidationError
fail!(:invalid_ticket, $!)
rescue Onelogin::Saml::ValidationError
fail!(:invalid_ticket, $!)
end
end
end
end

We just required the file that we will be overriding the functions in, and just commented out the response.validate! line.

Instead of hitting the url directly I used ‘Omniauth’ gem because it is well integrated with

‘OmniauthSAML’.

1
2
3
4
5
6
7
8
Rails.application.config.middleware.use OmniAuth::Builder do
provider :saml,
:issuer => issuer_name,
:idp_sso_target_url => target_url,
:idp_cert_fingerprint => idp_cert_fingerprint,
:name_identifier_format => name_identifier_format
end
require 'saml_patch'

This code goes in config/initializers/omniauth.rb. The code is explained below.

Issuer: takes the registered name of your service, it is an Omniauth required field as some of the authentication services require the issuer name to be present, in Signicat’s case they don’t have any such compulsion, so the value can be anything, just to surpass Omniauth field requirement validation.

Idp_sso_target_url: the Signicat’s structured url will be placed here.

Idp_cert_fingerprint: The SHA1 fingerprint of the certificate. This is provided from the identity provider when setting up the relationship.

Name_identifier_format: This will tell omniauth what kind of packaging method would be used. Again this is required by omniauth because Signicat sends the  package depending on methods specified in the url. So in NEM-ID’s case the value is “urn:kantega:ksi:3.0:nameid-format:fnr”.

And in the end we have required the patch we created to override ‘callback_phase’ method.

Now when we want to hit the target we will assign this code to any variable and it will hold the response from Signicat.

1
2
foo = request.env["omniauth.auth"].extra.raw_info
bar = foo.to_hash

The response will be be available in a hash in ‘bar’ variable and valid (for now) for use.

Now as the framework is more or less created we will move onto signing the document.

For signing we need to make SOAP calls to Signicat’s document service url.

The url to which the call’s are being made for this purpose is:

https://test.signicat.com/ws/documentservice-v2?wsdl

It is recommended that you visit their site or contact their support to know which service is being lately used, and adjust your SOAP call accordingly.

Now to make the SOAP call I used a nifty little gem called SAVON. The methods created is given below followed by explanation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def send_signature_request(user, task_id, completion_callback_url)
document_id = id
ref_sds_id = upload_file
client = Savon.client(wsdl: 'https://test.signicat.com/ws/documentservice-v2?wsdl', raise_errors: false)
response = client.call(:create_request,
message: {
service: 'shared',
password: 'password',
request: {
profile: 'default',
language: 'en',
task: [{
:@id => task_id,
:@bundle => false,
subject: {
:@id => user.id,
"national-id" => user.cpr,
},
:attributes! => {"document-action" => {type: "sign",
"order-index" => 1, "send-result-to-archive" => false, optional: false}},
"document-action" => {
:attributes! => {
document: {
id: document_id, "ref-sds-id" => ref_sds_id,
"send-to-archive" => false,
'xsi:type'=> 'tns:sds-document'
}
},
document: {
description: 'description of file goes here'
}
},
signature: {
method: ["nemid-sign"]
},
"on-task-complete" => completion_callback_url
}],
}
})
response.success? && response.body[:create_request_response]
end

So the way it is structured is that we created a function which takes a user (which is called subject in Signicat’s terminology), task_id, every task requires a unique id, by which its status can be requested and identified on our end. I am sending this to our function you can create it inside the function as well, its a choice of personal preference or requirement of the scenario.

Completion_callback_url, this is the url which will accept the response from Signicat on completion of task, similarly there are can be 2 more url’s one for postponing the task and other for on task cancel. However here we will just cater the completion of task for the sake of simplicity and more or less it will act in the same way to this.

This url is made by appending the controller’s action route defined to the base url of your application.

Since I had created this function inside my model which stored the files(pdf’s) for signing, so the id

is being assigned to document_id is readily available as model’s attribute. Since there are more than one way of providing the file to Signicat which can be read about here.

I went with sds-document which is session data storage provided by Signicat. And in my function called another model function created called upload_file

1
2
3
4
5
6
7
8
9
10
11
def upload_file
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
file = File.open("file_path/file.name", 'rb')
request = Net::HTTP::Post.new(url.path, {"Content-Type" => file.content_type,
"Content-Disposition" => "form-data; name=\"datafile\"; filename=\"file.name\"\r\n"} )
request.basic_auth('shared', 'password')
response = http.request(request, file.read)
response.body
end

In this call we are just uploading the datafile to the shared session data storage provided by Signicat. And it sends back the ref_sds_id.

Now that file is uploaded and we have everything in order lets break the code in chunks and explain each chunk. So savon client call won’t be explained as plentiful of documentation is available, and what I found boggling in in implementation was the actual message that we send to the wsdl call which we post to :create_request.

In ‘message’ before we can define any kind of activity, we need to provide our credentials.

1
2
3
message: {
service: 'shared',
password: 'password',

With these credentials if we are authenticated, then we move further to the request part which holds all of the settings and the task.

request: { profile: ‘default’, language: ‘en’,

Here we tell the service which profile to use(if created), in my case I just used their default profile, and the preferred language in which the prompts will be displayed to the user. Then comes the most important part which is the defining the task in which the actual signing will take place.

1
2
3
task: [{
:@id => task_id,
:@bundle => false,

As mentioned previously @id is given the value of task_id, it is provided for checking the status and keeping track of the request made.

@bundle => false, as I am using the latest wsdl service of Signicat this functionality is not fully implemented at the moment and its removal causes the call to fail and nothing can be found about it in their currently available document, so setting its value to false will work.

Now we tell Signicat who would be signing the document. This is done by creating a subject block in the task.

1
2
3
4
subject: {
:@id => user.id,
"national-id" => user.cpr,
},

@id values will be used to identify the subject with. As I am using NEM_ID I used user CPR, if the person who is signing the document doesn’t match this CPR Signicat will not accept his sign. Exactly what you need to send to define the subject depends upon the method used for signing. Since I authenticated my user with Nemid I am also signing my document with the same method.

1
2
3
4
5
6
7
8
9
10
:attributes! => {"document-action" => {type: "sign",
"order-index" => 1, "send-result-to-archive" => false, optional: false}},
"document-action" => {
:attributes! => {
document: {
id: document_id, "ref-sds-id" => ref_sds_id,
"send-to-archive" => false,
'xsi:type'=> 'tns:sds-document'
}
},

Now we define what is to be done in the task on the document by creating the above block called the document-action.

Attributes in  SOAP call in RAILS is defined in the form shown below, and you will see that the code above is adhering to the format.

1
2
3
4
:attributes! => {foo: {all attributes of foo}}
foo:{
fields of foo
}

So we tell in our code that the type of document-action is sign and that we do not want to send the resulting document to be send to archive and order-index tells when to execute the particular action in case there are more than one action is defined. Since we are just signing a single document we only have one task and hence the value 1.

After the attributes we create the document block on which the action defined in document-action attributes will be performed.

Here we again have the document attributes in which the document unique identifier is present. Since we want to use the SDS provided we tell the document type to be sds-document, and ref_sds_id which we sat in the beginning of the function after uploading the file. And again I didn’t want to store the original file in the archive so it is set to value.

In the document there is only one field that I have used and that is document description.

1
2
3
4
document: {
description: 'description of file goes here'
}
},

and the part of document-action is completed. Now we create a block to tell about the kind of signature we will be using.

signature: { method: [“nemid-sign”] },

This is it, in signature we mentioned the method we would be using and that is nemid-sign. For complete list check the complete list of signature methods.

Now before we close the TASK block we will provide the url’s for each status of task i.e completion, postpone and cancellation. In our case its just the task completion.

1
2
3
"on-task-complete" => completion_callback_url
}],
}

I am putting all the closing brackets for the sake of closing the message block.

response.success? && response.body[:create_request_response]

now we check if we get a successful response if yes then we return the response.body[:create_request_reponse]

We store this in a variable let’s call it sign_request_response.

So the result will look something like this

1
2
sign_request_response = data_file.send_signature_request(current_user, task_id,
completion_callback_url)

Datafile here is the object of the model we created all the functions for.

Now we check sign_request_response exists and create the actual url where user will be signing the document.

1
2
3
4
5
if sign_request_response
sign_request_response[:request_id]}&task_id=#{task_id}"
redirect_to doc_signing_url
end

Both the codes(model function and the creation of doc_signing_url) are put together in a function called sign_document

def sign_document data_file = DataFile.find(params[:data_file_id]) base_url = ‘Applications base url’ completion_callback_url = “#{base_url}#{route to controller#index }?request_id=${requestId}” task_id = “#{current_user.id}-#{data_file.id}” response = data_file.send_signature_request(current_user, task_id, completion_callback_url) if sign_request_response doc_signing_url = “https://test.signicat.com/std/docaction/contracto.dk?request_id=#{ sign_request_response[:request_id]}&task_id=#{task_id}” redirect_to doc_signing_url end end

In this code the current_user is an application method that returns the session user.

the document is signed and by default you will receive DSIGXML.

What is done with this is entirely upto the application requirement. However I have used Signicat’s packaging method which creates a Signed PDF document.

Read More
Checklist-for-Code-Review-of-Web-ApplicationsChecklist for Code Review of Web Applications

Checklist for Code Review of Web Applications

Code review is a healthy exercise that should be performed on a regular basis, and helps in improving engineering sophistication of team members. Following are common best practices that should be applied to all code built for web applications built in any language or framework. Most of the points covered can be apply to other development domains, such as mobile applications as well.

 

General

  • Use meaningful names for functions, and variables
  • Avoid using globals
  • Avoid using singleton pattern. Pass the initialized object as parameter (to method or constructor) instead wherever possible.
  • Stick to a strict coding style and use code editor’s built-in helpers to format code every now and then.
  • Avoid keeping commented out code. Remove it! Version control system already takes care of keeping the history for reference later.
  • Comment as much as needed but not more (avoid stale comments)
  • Break longer running function into smaller functions, and then break them into even smaller functions.
  • Keep it DRY (Don’t repeat yourself). However, code should also have loose coupling, so don’t also over-do DRY! Code is DRY enough if you are defining helper functions within the appropriate model/view/controller layer.
  • Avoid heavily nested code (using nested for loops, nested if/else conditions)
  • Build on the shoulders of giants. Use existing developed open source libraries wherever possible to ensure flexibility/robustness

 

Model

  • Avoid making SQL calls directly from controller or views. Use models
  • Parameters of model function should require minimal (if any) validation. For the most part, all the validation should have been done in the layer above (like controller or lib function).
  • All SQL queries should use an appropriate index. Composite indexes should be introduced wherever possible.

 

Controller

  • Separate controller layer from view layer. At the very least, controller functions and view functions should be clearly separated.
  • Public function/interfaces/controller methods should always validate the parameters received. This is not mandatory for Private/Protected functions, so only expose those function/interfaces as public that provides such guarantees.

 

View

  • Views should be free of business logic. Conditional statements should be avoided through creating sub-views and calling the appropriate view through the controller.
  • Avoid using conditions in views (or view functions). Conditional views can be avoided by ensuring that controller calls the appropriate view (or view function)

 

Error Handling

  • See error handling as a separate concern. Don’t mix it with the program’s actual flow
  • Use exceptions rather than return codes. Abusing exceptions is however also not encouraged, and return codes are generally faster in practice.
  • Avoid passing or returning null values.

 

HTML

  • Verify the page loads correctly in all the major browsers (IE, Firefox, Chrome, Safari)
  • Avoid mixing javascript code with other technologies.
  • Ensure that appropriate maxlength and size limits are applied to input fields of the form.

 

Refactoring/Enhancement

  • Ensure that when a functionality is changed, you have identified all the ‘callers’ of the functionality before hand. Ensure that the change in functionality works for all the callers (be it be other standard functions, interaction points such as ajax call or other html GET/POST requests).

 

References

Read More