Skip to content

Instantly share code, notes, and snippets.

@tyre
Created September 12, 2012 23:58
Show Gist options
  • Save tyre/3710862 to your computer and use it in GitHub Desktop.
Save tyre/3710862 to your computer and use it in GitHub Desktop.

= LivingSocial Corporate web site CMS application

== Code: The project is hosted at http://code.livingsocial.net/unified-experience/corporate-site.

== Project management: The tracker project is hosted at https://www.pivotaltracker.com/projects/388437

== Setup

  • run ruby ./bootstrap.rb

== Database: Running on MySQL. Use the included db/development_structure.sql to seed the database. (bootstrap.rb will do this for you)

=== Staging

=== Basic usage

This app runs on port 3038. If you'd like to use it in ringleader, checkout: dir: path/from/yml/to/corporate/site/root/ rvm: foreman start app_port: 3038 server_port: 4038 idle_timeout: 1000

And that's it!

=== Running tests:

bundle exec rake spec

==== Authentication Authentication is done by Google through Open ID. To sign in use your livingsocial email account. If you are refused access you need a Google apps account administrator to add you to the "corp_website_manager" group.

=== Gotchas: When asking a page about it's root right after a new page has been created may lie to you! To avoid this always reload the page that you want to find the root of before hand. Example: p1 = Page.make p2 = Page.make p2.root # => correct!

p1.children.make p2.root # => lie! p2.reload.root # => correct!

=== Integrations:

==== Google Apps Auth:

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj '/C=SE/ST=VG/L=Ostra hamngatan 4/CN=elabs.se' -keyout elabs_googleapp_auth_private_key.pem -out elabs_googleapp_auth_cert.pem

==== Job board: The application uses content from the job board application (https://github.com/livingsocial/job_board). It does this by embedding pages from the job board application in iframes on this application. In those request a special param "referrer" is sent with the value of "lscorp". This tells the job board application to do two things:

  • Use the this application's css file (currently the one at Heroku, can be changed from within the job board application).
  • Change the urls of the job links to point back to this application. (which in turns calls another page on the job board application). Worth noticing is that the application uses instances of the Box model of type "External" and sub_type "iframe" to achieve this.

==== ImageHacker: Replacing images on in the application is done through the CMS. There is no way to upload images from disk but the CMS instead takes a url to an image and uses that. If the image url leads to ImageHacker the CMS supports scaling up the size of the images when viewing them in the fancy box overlay.

=== Optimization opportunities:

  • The tree menu currently does a recursive set of queries to fetch all levels of pages. This could be optimized with a smarter query and have ruby take care of building a tree out of the flat data received.
  • Page#is_or_is_related_to could probably reduced to one query.
  • Currently all the tree methods on Page instances are just active record query cached. Some performance could be gained by cache the result on each method in memory.
  • The CMS aren't using any page or fragment caching at the moment. Introducing this would help deliver the to visitors faster and more scalable.
  • How the active entry in a list box is selected can probably be greatly approved.

=== Implementation descriptions:

==== Boxes aka Modules: The CMS is composed up of a set of different boxes. Each box has the possibility to include a header, sub header, body, link text, link url, image url, and source url. The current types of boxes includes:

  • General - To add normal type of content.
  • List - Can have a set of sub ordered general boxes.
  • Html - Where you can add any type of HTML to make something custom that isn't supported natively in the CMS.
  • External - Can parse RSS feeds or render an iframe.

The List and External boxes can also have a sub type that furthers defines the box. The external box has two very distinct sub types: rss and iframe. While the List box has sub types like: gallery, product list and carousel.

==== Data structure: The application revolves around pages which has versions (two for each language: one which holds the current draft mode and one that represents what signed out visitors see.) Page versions in turn has boxes which makes up the content on the pages. A template file then defines how those boxes are positioned on the page.

Please consult db/schema.rb or export an ERD for details.

==== Languages: The application supports all its content (expect for the admin UI) to be translated. This is done with two strategies.

===== Static translations: Handles translations of content that isn't editable through the CMS. This is currently only the footer and the today's offer. This content is translated with standard Rails I18n translation files. If no translation is found for the given language I18n falls back on the translations in config/locales/en.yml. If there's no translation in that file a humanized version of the translation key is displayed.

===== Dynamic translations: Handles the translations of all content that can be edited through the CMS. This includes page names, menus, headers, paragraphs and images to name a few. This content is translated by navigating to a language version of a page and hovering (while signed in) over the content box you want to translate and click the "Translate" link. The content you change here will override the content from the english version of the page.

To translate page names, urls (and menu names) click the "Translate page settings" button in the admin header.

Notice that it is possible to translate just one "box" at the time. Other boxes on that page will still fallback to the English version. However when you have translated a box "untranslated" properties of that specific box will no longer be in sync with the english version.

===== Language picker: The CMS supports about 784 languages (the limitation is that we're currently using two ascii characters to identify the languages). Which languages that can be translated and which languages can be visited by the audience is controlled from config/app_config.yml. The actual names of the languages is controlled from config/locales/en.yml

== TODO:

  • See: Optimization opportunities
  • See: Pivotal Tracker

== User guide:

== License information:

  • For license information about the dependencies of this app see LICENSES
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment