Friday, July 13, 2012

Building a structured and distributed CMS

As a first step of oDesk's rebranding project, we had to move our home-grown CMS into a more robust and full featured one. Having in mind that we'll eventually need to develop the rest of the visitor site in the same infrastructure and after benchmarking drupal vs django-cms (see here analysis) we picked django-CMS. So currently all our static pages are build via our django-CMS installation.

Building static pages with reusable SCSS components


One of our primary goals was to be able to use reusable CSS components in our static pages, so that we don't end up with high level of customized CSS in our static pages. We were using Compass to define CSS components but we wanted to expose them in our CMS also. So we had to create a custom plugin for django-CMS. The plugin includes 5 basic fields which you can see here:


And the way this works is the following:

class SassStylesheetPlugin(CMSPlugin):
    name = models.CharField(...)
    css_media = models.CharField(...)
    scss_body = models.TextField(...)
    compiled_css_body = models.TextField(...)
    upload = models.BooleanField(...)

    def _get_compiled_css(self):
        compiled_body = scss_compiler.compile_scss(self.scss_body)
        content = '<style type="text/css" media="%s">%s</style>' % (
            self.css_media, compiled_body)
        if not self.upload:
            return content
        return compressor.output()

    def save(self, commit=False):
        self.compiled_css_body = self._get_compiled_css()
        return super(SassStylesheetPlugin, self).save(commit=commit)

The plugin reads the input SCSS and compiles it to a CSS output. The compressor we use is django-compressor and the SCSS compiler we use is pyScss.

This way writing static pages in our CMS becomes easier and less messy. CMS administrators can @import reusable SCSS components that are globally defined in our stylesheets and use them in their pages. As a result we can have static pages that are using less CSS code and actually look and feel similar to the rest of the site.

Using S3 as a shared resource


One of the things we always have in mind while developing the visitor site is that we are operating in a distributed environment in the cloud—our services are replicated on multiple EC2 instances in multiple availability zones. As a result, a single server instance failure or even a whole availability zone failure should not impact our reliability.

When admins create static pages or upload content such as images, these files need to be stored in a central location so that they can be accessed by all servers. S3 provides an ideal solution for this, as it is a storage service that can also serve the content directly to the visitors.

Every time a page on the CMS is modified we automatically compile the SCSS to CSS, we create a file and upload it to S3 (just as we do with images and other files) and then just append in the HTML of the page a link to the stylesheet.

Monday, July 2, 2012

New oDesk brand launched!

After a long period of silence, I'm back! About a year ago I transitioned to oDesk, where I got the chance to learn and implement many new technologies.

The new oDesk visitors site (ie whatever the user sees before they signup) is built on a django stack, using apache and running on multiple EC2 instances, with an RDS backend. We also use continuous integration with jenkins and have an automated deployment process which allows us to easily push our code changes in multiple servers seamlessly. In our FE we are using HTML5, Compass and OOCSS to make our code cleaner and more reusable and django compressor to minify it.

The road was long, rough and exciting. I learned way too many things and still learning during this project...since its not over yet. :)

I'll try to share my experiences in the following months, but for now please browse through the odesk site as a visitor and enjoy the experience.

Stay tuned for more updates.