Railscast's Deploying to a VPS

I have been using Ryan Bate’s Railscasts deployment recipes as long as it has been up. I’ve deployed projects for some startups that needed help, for my own startup projects and soon, another project that I have been cooking up for a while.

A few days ago, I have started tinkering with this script and have test deployed a few applications. I tried a few things and updated my deployment gist that I have been using to deploy.

A lot has changed for this deployment recipe.

  1. Ubuntu 10.04 is mostly not made available anymore by VPS providers
  2. A lot has changed since 10.04. Some commands may or may not work. You have to do some of your own research
  3. It still uses ruby version, 1.9.3

I have no problem using ruby version, 1.9.3. So, I left it at that. I am of course still using Unicorn and deploying with Capistrano.

Notable Changes

I urge anyone try it out!

 Textile

I have always looked at html as the best markup I can use for blogging or anything remotely connected to the web.

Through the years, I have had chances to work with lightweight markup languages like Markdown through Github and Stackoverflow and Textile through Trac.

The thing is, I like it now more than ever. Especially after tingling a bit more with TextPattern. I chose Textile instead of Markdown with no particular reason. However, here’s a comparison from Stackoverflow if you want see one.:

Textile
  • Used by Redmine and the Ruby community
  • 5 questions currently tagged on Stack Overflow
  • The most similar to HTML, but least readable source
  • Easiest nested lists of all three languages
  • Not understandable to non-programmers or the HTML-ignorant
  • Ideal for complex short documents (with links, nested lists, code, custom HTML); for example: short documentation, how-tos, blog or CMS content
Markdown

Doesn’t seem to have a home language “community” but…

  • … 47 questions tagged on Stack Overflow
  • Emphasizes source code readability, similar to email traditions
  • Straightforward HTML embedding (you just type the tags out)
  • No way to make tables besides embedding HTML
  • You know it already if you know Stack Overflow
  • Easy to learn if you already know reStructuredText
  • Automatic email address obfuscation for the format (with angle brackets)

I have modified my blog to use Textile. In fact, this is first post I am writing in Textile. It’s kind of weird. Fun in a way, like learning a new language. I can’t say that it’s the best way to blog, but I trust it. I trust that the formatting will be better than most WYSIWYG editors I have tried though. Something which we will get to later on.

Using Textile (even in other lightweight markup languages) can make you very expressive. Using tons of ways to present your writing. I can write tables without being bombarded by the need to put < and > signs everywhere just to create tags.

Full table with summary, caption, colgroups, thead, tfoot, 2x tbody

Title Starring Director Writer Notes
This is the tfoot, centred
The Usual Suspects Stephen Baldwin, Kevin Spacey Bryan Singer Chris McQuarrie One of the finest films ever made
Se7en Morgan Freeman, Brad Pitt David Fincher Andrew Kevin Walker Great psychological thriller

I can write Chemical formulas without thinking of matching tags.

Calcium borate: Ca3(BO3)2

Truly impressive!

WYSIWYG Editor Problems

One of problems with WYSIWYG editors, aside from the fact that they are heavy, is that they don’t produce clean markup. Yes, I am looking at you TinyMCE and CKEditor. You would see cluttered <br/>s, which I don’t favor, everywhere. You see excessive unneeded <p>s.

Lack of control on what you produce. I find myself switching to HTML view to modify the HTML produced by these editors. It can be cumbersome.

Thanks Dean Allen

I have to hand it to Dean Allen, the creator of both TextPattern and the Textile markup language. I have borrowed the classTextile.php class from TextPattern to convert my posts from Textile to HTML. And to tell you frankly, I am having fun with this.

Sidenote

On a side note, I just learned that Sublime Text 3 Beta has just been released. I’ve just downloaded it. There is a considerable slowness though, compared to the second version. It’s still Beta, so I must say I forgive them.

 jQuery selectors for KnockoutJS applyBindings

In the previous blog post, we used the second applyBinding's second parameter. This optional parameter determines which part of the document KnockoutJS will search for data-bind attributes. What you may have noticed is that, I've used the element's id attribute for this.

Fortunately, jQuery selectors can also be used. The trick is that you need to pass only a single element.

HTML code:


<div class="firstView offset2 span8 margin-bottom body">
  <h3>Concatenation!</h3>
  <p>First name: <input data-bind="value: firstName" /></p>
  <p>Last name: <input data-bind="value: lastName" /></p>
  <h4>Hello, <span data-bind="text: fullName"></span>!</h4>
</div>

<div class="secondView offset2 span8 margin-bottom body">
  <h3>Calculation!</h3>
  <p>First value: <input data-bind="value: firstValue" /></p>
  <p>Second value: <input data-bind="value: secondValue" /></p>
  <h4>Hello, <span data-bind="text: calculatedValue"></span>!</h4>
</div>



Javascript code


<script>
function ViewModel() {
    this.firstName = ko.observable("John");
    this.lastName = ko.observable("Smith");
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}

function calculatedModel() {
    this.firstValue = ko.observable(1);
    this.secondValue = ko.observable(2);
    this.calculatedValue = ko.computed(function() {
        return parseInt(this.firstValue()) + parseInt(this.secondValue());
    }, this);
}

ko.applyBindings(new ViewModel(), $('.firstView')[0]);
ko.applyBindings(new calculatedModel(), $('.secondView')[0]);
</script>



Neat!

 Multiple Models in a View with KnockoutJS

If there's something I have learned working with KnockoutJS, is that you cannot work with two models on the same view. If you do something like this,

<div class="offset2 span8 margin-bottom body">
  <h3>Concatenation!</h3>
  <p>First name: <input data-bind="value: firstName" /></p>
  <p>Last name: <input data-bind="value: lastName" /></p>
  <h4>Hello, <span data-bind="text: fullName"></span>!</h4>
  <h3>Calculation!</h3>
  <p>First value: <input data-bind="value: firstValue" /></p>
  <p>Second value: <input data-bind="value: secondValue" /></p>
  <h4>Hello, <span data-bind="text: calculatedValue"></span>!</h4>
</div>

<script>
function ViewModel() {
    this.firstName = ko.observable("John");
    this.lastName = ko.observable("Smith");
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}

function calculatedModel() {
    this.firstValue = ko.observable(1);
    this.secondValue = ko.observable(2);
    this.calculatedValue = ko.computed(function() {
        return parseInt(this.firstValue()) + parseInt(this.secondValue());
    }, this);
}

ko.applyBindings(new ViewModel());
ko.applyBindings(new calculatedModel());
</script>



you'd get an error like this:


Error: Unable to parse bindings.
Message: ReferenceError: firstName is not defined;
Bindings value: value: firstName, 



Knockout, of course, would have a workaround for something like this. ko.applyBindings() has a second parameter for us to define which part of the document we want to search data-bind attributes in. Let's apply this to our example.

HTML code:


<div id="firstView" class="offset2 span8 margin-bottom body">
  <h3>Concatenation!</h3>
  <p>First name: <input data-bind="value: firstName" /></p>
  <p>Last name: <input data-bind="value: lastName" /></p>
  <h4>Hello, <span data-bind="text: fullName"></span>!</h4>
</div>

<div id="secondView" class="offset2 span8 margin-bottom body">
  <h3>Calculation!</h3>
  <p>First value: <input data-bind="value: firstValue" /></p>
  <p>Second value: <input data-bind="value: secondValue" /></p>
  <h4>Hello, <span data-bind="text: calculatedValue"></span>!</h4>
</div>



Javascript code


<script>
function ViewModel() {
    this.firstName = ko.observable("John");
    this.lastName = ko.observable("Smith");
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}

function calculatedModel() {
    this.firstValue = ko.observable(1);
    this.secondValue = ko.observable(2);
    this.calculatedValue = ko.computed(function() {
        return parseInt(this.firstValue()) + parseInt(this.secondValue());
    }, this);
}

ko.applyBindings(new ViewModel(), document.getElementById('firstView'));
ko.applyBindings(new calculatedModel(), document.getElementById('secondView'));
</script>



Check it out a live example!