Fork me on GitHub

println by fbettag

println is a blogging / publishing software written in Scala with the Lift Web Framework. It tries to fulfill the need for an un-obustrive approach of writing, publishing and managing ones blog posts with it's overlay-editor-window.

It is heavily inspired by Nesta CMS a Ruby based CMS Software and also uses parts of its default layout (since i like it for its simplicity).

All my websites (Bettag Systems UG and uberblogs) currently run println.

There also is a Demo site. Screencast will follow.

Features

Currently, println caches by default every response for an URL for 60 seconds.

This only applies for non-authenticated requests, authenticated users will have uncached Responses.

Caveats

Currently it is text-only. I will implement media-management as soon as possible. For now i suggest storing your images elsewhere (Flickr, Picasa) as they offer better upload-possibilities from mobile devices anyway.

Another caveat is, that JavaScript is not rendered in the Live-Preview (but properly on the resulting published page). Meaning that if you enter into the Live-Editor, it won't show in the Live-Preview, but will be perfectly normal on the website.

Layout and Widgets

The main layout is in src/main/webapp/template-hidden/default.html and has all the widgets that are currently implemented. Here is the overview:

If you want to implement your own, feel free to look at src/main/scala/code/snippets/Helpers.scala for how to do so.

Dependencies

PostgreSQL (or any other JDBC-Driver that Liftweb supports)
Scala
MongoDB (optional for Statistics)

Download

You can download this project in either zip or tar formats.

You can also clone the project with Git by running:

$ git clone git://github.com/fbettag/println mysite.com

Preparing the database (PostgreSQL)

After installing PostgreSQL, run the following in your shell:

$ createuser -Upostgres printlndemo
$ createdb -Upostgres --owner println printlndemo

Setup and keeping track of Development

Sometimes it can be hard for newcomers to see how git helps you manage this, but here is how i recommend doing it.

cd mysite.com/
git branch -t mysite.com		# create your own branch
git checkout mysite.com			# check it out
git branch -D master			# delete the local master
edit templates in src/main/webapp	# edit your templates
git commit -a -m 'My Layout changes.'	# save your changes

Now whenever we publish an update, you simply do:

git rebase origin/master

The best thing would be, to push your new branch to a remote repository for backup. To find out more about stuff like that check gitready.com and sometimes my blog.

Configure your Project and Database: (use default.props as example)

src/main/resources/props/default.props            (Development)
src/main/resources/props/pilot.default.props      (Preview - copy from dev)
src/main/resources/props/production.default.props (Production - copy from dev)

If you want your production. and pilot.default.props in your repository, make sure you uncomment the line in .gitingore!

SMTP Setup is straight forward. Either you have your SMTP Host on localhost, or you have a remote-host which lets you relay. In Postfix this can be easily done with my_networks.

Whenever you're done making changes, make sure you commit! Otherwise rebase won't work and you will encounter other problems like backing up.

Run in development-mode:

mvn jetty:run

Production

Deploy for production:

mvn package

Download David Pollak's jetty_instance.tgz and do the following:

tar -jxf jetty_instance.tgz
cd jetty
echo 9090 > base_port (or whatever your Port should be)
echo 64M > ram_size (change to appropriate size!)

Copy your packaged .war-file to jetty/webapps/root.war and run:

./start_prod.sh (and ./shutdown_prod.sh)

Point your nginx to the port of the jetty and follow the on-screen instructions.

Without MongoDB

MongoDB is solely used for statistical analysis like Browser-, Referer- or Target-URL-tracking. This is not fully tested yet, but it has interesting results and more flexibility as opposed to other commercial products.

If you want to try it without MongoDB, feel free to do so. Just make sure you unset/comment "mo.host" in your .props-files.

Page title

Instead of writing stupid SQL-Queries to get the default pagetitle, the pagetitle is defined in the properties files (default.props, production.default.props). IMHO this is a performance-saver as well as practiable.. How often do you change your main-site title?

Remarks

Some of the JavaScript- and Request-Routing-Stuff is very hackish, but it also shows the capabilities Lift has to offer or how you can reuse or abuse them.

Todo

Thanks

to everybody in the Lift Community and on Liftweb Google Groups.

Author

Franz Bettag (franz@bett.ag)

License

  Copyright (c) 2011, Franz Bettag 
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
     * All advertising materials mentioning features or use of this software
       must display the following acknowledgement:
       This product includes software developed by the Bettag Systems UG
       and its contributors.

  THIS SOFTWARE IS PROVIDED BY BETTAG SYSTEMS UG ''AS IS'' AND ANY
  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL BETTAG SYSTEMS UG BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.