Introducing Publish It Yourself: a self-managed libre CMS

Publish It Yourself
===================
_Publish It Yourself_ is a self-managed CMS.
It is designed to create autonomous communities where users can directly create and manage content.
It is a mix between blogs and blogs platforms, digg-likes and open publishing websites such as (the Indymedia network)[http://www.indymedia.org].
It allows to publish and promote rich text articles and news. It includes many features: tagging with (triple tags)[http://en.wikipedia.org/wiki/Triple_tag#Triple_tags] support, comments, spam protection, themes, interface translation, registration system, peronnal users pages, Atom feeds, microformats,  and more!
Every pages are optimized for search engines, including expressives URLs and uniques titles.
It is wrote in PHP using the (symfony framework)[http://www.symfony-project.org]. It is modular and object oriented.
The Javascript part of the code uses (jQuery)[http://www.jquery.com], the built-in theme is (x)HTML 5 compliant.
This software is still in an early stage of developpement.
_Publish It Yourself_ is a free software covered by the (GNU Affero General Public License version 3)[http://www.fsf.org/licensing/licenses/agpl-3.0.html]. See the « LICENSE.txt«  file for futher informations.
For installation instructions, see the « INSTALL.markdown«  file.

Publish It Yourself is a self-managed CMS. It is designed to create autonomous communities where users can directly create and manage content.

It is a mix between blogs and blogs platforms, digg-likes and open publishing websites such as the Indymedia network.

It allows to publish and promote rich text articles and news. It includes many features: tagging with triple tags support, comments, spam protection, themes, interface translation, registration system, peronnal users pages, Atom feeds, microformats,  and more! Every pages are optimized for search engines, including expressives URLs and uniques titles.

It is written in PHP using the symfony framework. It is modular and object oriented. The Javascript part of the code uses jQuery, the built-in theme is (x)HTML 5 compliant.

This software is still in an early stage of development and probably has many bugs, please report them! It is a free software covered by the GNU Affero General Public License version 3.

You can try it online (database cleared periodically) or download it on GitHub. Contributions are welcome (see the TODO file inside the project root directory) and can be submitted directly on GitHub.

Tag Suggestion for symfony

I just have created a patch for sfFormExtraPlugin. It provides a new form widget called sfWidgetFormJqueryTagSuggestion designed to suggest tags. It is based on the Tag Suggestion jQuery plugin of Remy Sharp.

Capture d'écran

You can download it from GitHub, just copy the files to the corresponding directories of your existing sfFormExtraPlugin installation or wait for upstream inclusion of my patch.

This widget integrates easily with sfPropelActAsTaggableBehaviorPlugin. Here is how to use it with this plugin.

You must have sfFormExtraPlugin with my patch and sfPropelActAsTaggableBehaviorPlugin properly installed and working. We consider that you have a model called Article with the taggable behavior.

Add jQuery to your javascripts

Like many others sfFormExtraPlugin widgets, the sfWidgetFormJqueryTagSuggestion requires jQuery to work. If you already have it installed, you can skip this step. Either, download jQuery to the web/js/ directory of your project, open the config/view.yml file of your application and set it like that:

default:
  javascripts:    [jquery-1.3.2.min.js]

Of course, change the filename if needed.

Put Javascripts and CSS into your web directory

sfFormExtraPlugin need some CSS and Javascripts to work properly, run the symfony plugin:publish-assets command to put them into corrects directories.

Create a static function to retrieve matching tags

Its time to extend the TagPeer model class to add it a method allowing to retrieve tags corresponding to a query. Creates a new file called MyTagPeer.class.php into the lib/model/ directory of your project containing the following code:

class MyTagPeer extends TagPeer {
  /**
   * Gets tags for a selector
   *
   * @param string $q
   * @param int $limit
   * @return array
   */
  static public function retrieveForSelect($q, $limit = 10)
  {
    $criteria = new Criteria();
    $criteria->add(TagPeer::NAME, '%'.$q.'%', Criteria::LIKE);
    $criteria->addAscendingOrderByColumn(TagPeer::NAME);
    $criteria->setLimit($limit);

      $tags = array();
      foreach (TagPeer::doSelect($criteria) as $tag) {
        $tags[] = $tag->getName();
      } 

    return $tags;
  }
}

Do not forget to run symfony cc to clear the cache after that.

Create a controller method to send the result as JSON

We have the model, we need the controller. Create a new module called tag by running symfony generate:module yourapp tag and add the following method to the tagActions class:

/**
   * Displays a JSON encoded tags array
   *
   * @param sfWebRequest $request
   * @return string
   */
  public function executeSelect(sfWebRequest $request)
  {
    $this->getResponse()->setContentType('application/json');
    $tags = MyTagPeer::retrieveForSelect($request->getParameter('tag'));

    return $this->renderText(json_encode($tags));
  }

Open your routing.yml file and add the following line to be able to access this action:

tag_select:
  url:          /select-tag
  param:     { module: tag, action: select }

Modify your form to add the new tags suggestion widget

Open the form class you want to add this widget and add the following line to the end of the configure method:

$this->widgetSchema['tags'] = new sfWidgetFormJqueryTagSuggestion(array('url' => $this->getOption('url'), 'separator' => ', '));

We use the comma as separator instead of the space by default because this is the separator used by sfPropelActAsTaggableBehaviorPlugin.

Next, modify your call to the form in your actions to pass the AJAX URL as form option:

$this->form = new ArticleForm($article,
  array('url' => $this->generateUrl('article_select_tag'))
);

It’s done!

Twisted Python Twitter library with OAuth support

I have just pushed OAuth support in  my Twitty Twister branch on GitHub. This library created by dustin allows to access the Twitter API  using Twisted for Python: a high performance networking engine. It is to my knowledge the first Twitter library written in Python that supports authentication via OAuth. My version of Twitty Twister is backward compatible, allows to choose between standard or OAuth authentication and even allows to change the user’s avatar via OAuth.

The library does not currently support tokens exchanges (the login flow). So, to use this library and the associated examples you need to  register your application on Twitter and get users access tokens using something like Django Twitter Auth for Django.

The 4 first parameters of the examples commands (files ending with -oauth.py in the example/ directory) are always the application’s key, the application’s secret, the user’s key and the user’s secret. See the OAuth Twitter  FAQ for futher information.

Have fun!

Patch to use sfXssSafePlugin with symfony 1.2

HTML Purifier is a awesome PHP filter library designed to secure and add standard compliance to HTML. In websites including user generated content, this library allow to have mutlimedia pages including image, text formating and YouTube videos in a secure and SEO proof way thanks to rich text editors like Tiny MCE or FCK Editor and HTML purifier.

A plugin called sfXssSafePlugin is designed to integrate this library as an escapement strategy in symfony. If you have tried it with symfony 1.2 you can see this message:

HTML Purifier autoloader registrar is not compatible
with non-static object methods due to PHP Bug #44144;
Please do not use HTMLPurifier.autoload.php (or any
file that includes this file); instead, place the code:
spl_autoload_register(array(’HTMLPurifier_Bootstrap’, ‘autoload’))
after your own autoloaders.

There are also some strict standards and constants compatibility problems. I’ve just wrote a patch to get this plugin working with symfony 1.2.

  1. Install sfXssSafePlugin like described in its README file
  2. Download my patch in the plugin’s folder
  3. Go into the plugin’s folder and run patch lib/helper/XssSafeHelper.php < XssSafeHelper.php.patch
  4. Edit your application configuration file (ie: apps/frontend/config/frontendConfiguration.class.php) and add the following code into the configure() method:
    require_once(sfConfig::get('sf_plugins_dir').'/sfXssSafePlugin/lib/vendor/htmlpurifier/HTMLPurifier/Bootstrap.php');
    spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'));

It’s done ! I’ve submitted this patch to the plugin’s author. I hope it will be upstream soon :)

Add reCAPTCHA widgets to Symfony forms

I’ve wrote a new Symfony plugin to add reCAPTCHA widgets and validation to Symfony new forms. reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows.

To install: checkout it from http://selfpublish.googlecode.com/svn/trunk/plugins/sfAnotherReCaptchaPlugin/ and put it in your Symfony plugins directory.

Next, get a reCAPTCHA key and put the following lines in your app.yml:

recaptcha:
  public_key:      <your public reCAPTCHA key>
  private_key:     <your private reCAPTCHA key>

Clear the cache with the symfony cc and check that the plugin activated in projectConfiguration.class.php.
You are now able to add reCAPTCHA widgets and validators.

See the plugin’s README file or this register form with reCAPTCHA enabled to learn how to use it.

This plugin is distributed under the MIT license and is based on Arthur Koziel work.

Tweet13 sur Presse-Citron

Ok ça date un peu, comme vous avez pu le constater je n’ai pas eu l’occasion de bloguer beaucoup ces temps ci.

Mon dernier jouet pour Twitter, Tweet13, à fait l’objet d’une revue par Eric Dupin sur son blog Presse-Citron. Merci à lui !

Pour rappel Tweet13 est une petite application web qui permet de chiffrer les messages Twitter à l’aide de ROT13 avant des les envoyer.

En parlant d’applications Twitter, je vous en ai concocter une nouvelle sur le thème de la musique qui devrait être disponible sous peu :)

Joyeuses fêtes à tous.

I need a webdesigner!

Hello Folk!

As a creative web application and software maker I’ve an always increasing need of graphics elements and templates  for my projects.

I’m looking for a partnership with a webdesigner. I do the code, you do the design, we share the success (if any) :P

If you are interested to work with me contact me via the dedicated page of this blog :)

Jouons un peu avec Tweet13

Voici Tweet13, le dernier petit gadget Twitter que je viens de programmer.

Comme son nom l’indique, Tweet13 chiffre vos updates Twitter avec ROT13 et ajoute optionellement un lien pour déchiffrer le message.

Quel intérêt de chiffrer un message si tout le monde peut le lire ?
Révéler la fin des films que vous avez vu, donner la réponse à de petits quizz que vous avez créés ou encore parler plus crument que d’habitude sans choquer vos followers sensibles :)

Tweet13 à été développé avec Django, JQuery et l’API Twitter.

Voir Tweet13.

Build your own website thumbnail generator with Django

On many website you can see a awesome link preview effect using a thumbnail of the page. There is some web services such as Websnapr or Thumbalizr providing an API to make your own webpages screenshots but it can be annoying to rely on third party projects: free accounts can only display a small among of screenshots and, cannot customize the size of the image, you cannot render Flash animations or Javascript…

Webkit Logo

We will build a website thumbnail generator using CutyCapt, a Webkit based free software designed to make screenshots of web pages, and Django, the powerful Python web framework.

The first step is to download and install CutyCapt. On a Debian-based system (such as Ubuntu) just type the following commands:

sudo apt-get install subversion libqt4-webkit libqt4-dev g++
svn co https://cutycapt.svn.sourceforge.net/svnroot/cutycapt
cd cutycapt/CutyCapt
qmake
make
./CutyCapt --url=http://lapin-blanc.net --out=example.png

Try to open the example.png (i.e: eog example.png), if the install is OK you must see a screenshot of this blog.

I assume your Django installation is working fine. Start a new project if needed (django-admin.py startproject mysite) and create an application called webthumb

with python manage.py startapp in your project.

Django Reinhardt

Edit your urls.py file to add a new pattern to the tuple urlpatterns. It will match screenshots requests and call the thumb view:

(r'^thumb/(?P.*)', 'mysite.webthumb.views.thumb'),

Now create a view called thumb in webthumb/view.py with this code:

import os
import subprocess
import md5
from django.http import HttpResponse

CUTYCAPT = '/home/keyes/cutycapt/CutyCapt/CutyCapt'
THUMBS_DIR  = '/home/keyes/Documents/Projets/kakofony/thumbs/'

def thumb(request, url):
    hash = md5.new(url).hexdigest()
    path = THUMBS_DIR + hash + '.png'
    print path

    if not os.path.isfile(path):
        try:
            subprocess.check_call([CUTYCAPT,\
                '--url=' + url,\
                '--min-width=200',\
                '--out=' + path])
        except subprocess.CalledProcessError:
            return django.http.HttpResponseServerError

    img = open(path, 'rb').read()
    return django.http.HttpResponse(img, mimetype='image/png')

Adapt the variables CUTYCAPT and THUMBS_DIR with your settings. Of course the directory pointed by THUMBS_DIR must be writeable (chmod 777).

You can now embed website thumbnails in your websites just with this HTML markup <img src="http://localhost/thumb/http://lapin-blanc.net" alt="Lapin Blanc" />.

Enjoy !

The last update of Aptana block Django development server

The last update of Aptana Studio come with a new built-in Jetty-based HTTP server running on port 8000… the same as Django development server. There is no good way to disable the preview server feature of the popular editor, but our favorite web framework can be launched on another port. Just type python manage.py runserver 8080 instead of python manage.py and access to your work on http://localhost:8080.

Django logo

Next Page →