You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

Checking your syntax on commit

A good IDE can spot programming syntax errors and alert you to them before they ever make it into a git commit. However, sometimes when you’re in a hurry, tired, or distracted, these alerts go unnoticed and there is a greater risk that you’ll commit broken files to your git branch. Git makes it a snap to revert changes, but wouldn’t it be nicer if you could prevent it from happening in the first place?

To that end, git has a nice feature called client-side hooks. In particular, you can create a hook known as a pre-commit hook that executes right before you commit something. It gives you the option to abort if something doesn’t look right. Using this feature, I created a simple script to check PHP and Javascript syntax on commit. It’s helpful for those mornings when I haven’t quite had enough coffee yet.

Yii Javascript redirect: jsredirect

One of the platforms I have to develop for is iSites. This is a Harvard grown LMS that is complicated and annoying, but functional.

Since I have to develop tools that fit within this framework I have to work around its limitations. One of the simpler to understand limitations is the idea of not having control of the headers sent. Since by the time it gets to my tool, the page has already started loading, output has already been sent, so doing a redirect with PHP’s header function is impossible.

Yii has 2 ways to forward things through the controller. redirect and forward. Redirect uses header and forward doesn’t change the URL. So the best way to forward within isites is to use a js forward. I.e. document.location = “www.google.com”

So in the controller.php in components which extends CController I added a method jsredirect:
https://github.com/jazahn/Quizmo/blob/master/quizmo/protected/components/Controller.php

	protected function jsredirect($url){
		// set the redirect in a session
		Yii::app()->session['jsredirect'] = $url;

		// forward to the jsredirect action
		$this->forward('/site/jsredirect');
	}

This just sets a session var for the redirect and forwards to site/jsredirect so in SiteController.php I have

public function actionJsredirect(){
		
		if(isset(Yii::app()->session['jsredirect'])){
			$this->render('jsredirect',array(
				'url'=>Yii::app()->session['jsredirect'],
			));
		}
		
	}

And then in the jsredirect template file we have

<script>
window.location.replace("{$url}");
</script>
Posted in ATG, Javascript, PHP, Yii. Tags: , , , . Comments Off on Yii Javascript redirect: jsredirect »

JavaScript is a Trap

Note: opinion

JavaScript is the most important part of web development. It’s what separates web applications from a collection of web pages.

The trap is one that I’ve fallen into multiple times and I’ve seen other developers fall into, unable to help them. They have these grandiose ideas and the way they see it working is with a mass of JavaScript. So they get this ridiculous mess of code, and they may not admit it’s a mess, but the trap with JavaScript is there is no way to write a lot of it without it becoming a mess.

One of my greatest offenses in this has been my use of extjs. This is a js framework that requires writing the code in a specialized fashion. You end up with classes that sometimes look clean but the more you stray away from exactly what the code was specialized for, the more it becomes a mess. And this happens fast.

Sometimes it’s a necessary mess. Innovation is often a mess. The problem is differentiating innovative in terms of JavaScript and otherwise innovative. Lots of people are doing innovative things, but it’s very rarely innovative in terms of the JavaScript.

So what’s the solution?

In my opinion, JavaScript in general should be minimal. 99.9% of what needs to be done for any web application can be done with jQuery, underscore, jQueryUI, and not a lot of it. I don’t believe you should ever be writing more than what you can copy paste directly from the jquery documentation. And you can replace “jquery” with any major js library. Don’t go outside of what the library was designed for, you really don’t need it most of the time. Really.

Maybe I should update this to be more about how JavaScript Frameworks are the trap, but it doesn’t matter if you’re using a framework or not, the more you write, the shittier it becomes.

Posted in Javascript. Tags: , . 1 Comment »

Using Smarty variables inside Javascript

I looked for appropriate answers for this on the smarty site, and the resounding answer was escaping javascript’s {}s with {literal}’s

Smarty template vars and Javascript functions
How to use Javascript codes in template files?
Access Smarty value with javascript

They basically all say to do something like this:

// $question_ids_json = ["1","2","3","4","5"]
{literal}
<script>
$(document).ready(function(){
	var question_ids = {/literal}{$question_ids_json}{literal};
	
	alert(question_ids[0]);

});
</script>
{/literal}

So they want to put everything in a literal tag, and then basically escape that literal tag when smarty needs to be used.

I didn’t like this, so I put the value in a hidden input and then just retrieved that input in the javascript, thereby keeping the js clean of smarty shenanigans:

<input type="hidden" id="question_ids" value='{$question_ids_json}'/>

<script>
$(document).ready(function(){
	//var question_ids = {$question_ids_json};
	var question_ids = eval($('#question_ids').val());
	
	alert(question_ids[0]);


});
</script>

But this is just a matter of personal preference.

Bootstrap Alerts with Backbone Views

One of the nice things about Bootstrap is that it provides reusable HTML/CSS components for common tasks such as displaying buttons, tabs, forms, and alerts (among other things). The markup for an alert is very simple:

<div class="alert alert-error">
<a href="#" class="close">&times;</a>
<strong>Oops!</strong> Something went terribly wrong.
</div>

A jQuery plugin that comes with Bootstrap is used for the close button. I found myself duplicating this markup in a Backbone.js project with various Underscore templates scattered around the view classes, so for the sake of DRYness, I decided to whip up a simple view to encapsulate the markup and behavior. Here’s the result:

var AlertView = Backbone.View.extend({
	className: 'alert fade in',
	alerts: ['success', 'error', 'info'],
	template: _.template([
		'<a href="#" class="close">&times;</a>',
		'<%= message %>'
	].join('')),
	initialize: function(options) {
		var message = options.msg || '';
		var alert = options.hasOwnProperty('alert') ? options.alert : 'info';

		if(_.indexOf(this.alerts, alert) === -1) {
			throw new Error('Invalid alert: [' + alert + '] Must be one of: ' + this.alerts.join(', '));
		}

		this.alert = alert;
		this.message = message;
	},
	render: function() {
		var output = this.template({ message: this.message });
		this.$el.addClass('alert-'+this.alert).
			html(output).
			alert(); // jquery plugin
		return this;
	}
});

AlertView.msg = function($el, options) {
	var alert = new AlertView(options);
	$el.html(alert.render().el);
	return alert;
};

Now I can use it from my other views for simple alert messages like this:

AlertView.msg(this.$el, { 
     alert: 'error', 
     msg: 'Something went terribly wrong.' 
});

Of course, it can still be improved with shortcut methods and general cleanup, but the goal is not to make it work for every possible alert, just the most common ones.

Posted in ATG, Backbone, Bootstrap, Javascript. Tags: , , . Comments Off on Bootstrap Alerts with Backbone Views »