Showing posts with label kotti. Show all posts
Showing posts with label kotti. Show all posts

2015-08-24

Introducing substancek. A Kotti project

Let me introduce substancek, a Kotti (http://kotti.pylonsproject.org) project.

What it is substancek?

substancek is:
  • Kotti (web application framework) + decoupled admin interface
It is only an additional layer upon the following opinionated stack:
with the following motto:
"""(even) better development experience and complete frontend freedom"""
and introduces (or better promotes) the concept of private admin area (backend) decoupled from the public side (frontend) of your web applications built with Kotti.

In other words it is a set of technologies addressed under the substancek brand that let you extend Kotti in order to use it just as a private backend administration area for your application data.

So you are still using plain Kotti with an additional package (at least kotti_backend depending on what you need).

If you want to know more I've discussed here benefits and why frontend decoupled from the backend pattern. See http://davidemoro.blogspot.it/2015/07/kotti-cms-successful-story-part-1.html

substancek name

Tribute to:
  • substanced (http://www.substanced.net). Carefully designed, well documented Python web development framework based on Pyramid/ZODB. It shares the concept of management views decoupled from the retail views for each published resource
  • kotti (http://kotti.pylonsproject.org). The Kotti framework

When substancek is for you

Any project of any size (from micro to XXL) involving content management that needs:
  • RDBMS. Kotti is an opinionated framework opposed to plain Pyramid. The persistence layer is managed by SQLAlchemy (http://www.sqlalchemy.org)
  • user friendly and production ready admin/editing interface for content producers so they can immediately start adding content to your web application with copy/cut & paste, clean urls, etc
  • rapid development. Pyramid and Kotti are easy to learn and let you become productive quickly and speed up your development. Even more with the decoupled admin interface.
  • stability. Pyramid and Kotti exist since many years and they are solid rock solutions production ready
  • frontend freedom. The admin interface comes for free while it is completely up to you add what your application needs (retail views). Since they are completely two different applications there are no css/js conflicts and you can integrate your preferred frontend tool chain without get influenced by how the admin interface is built.
  • flexibility. Pyramid won't hold you back when your application is small and won't get in your way when your application becomes large.
    Even if you start small, using Pyramid you anticipate what customers will need later avoiding expensive rewrites and this can make the difference. In other words this also means successful projects in the long term. Same for Kotti. See What makes Pyramid unique.
So if you project needs (or in future iterations) one or more:
  • complex security policies
  • workflows
  • hierarchical data support
  • or even intranet/extranet like collaboration areas
you might consider even more substancek (kotti_backend + Kotti + Pyramid + SQLAlchemy).

For example:
  • very small applications. For example a just one view public json endpoint for published news-like resources consumed by a third party app with an admin interface for editing contents
  • heavy Javascript based applications with modern frontend tools (eg: SPA + REST) with a decoupled admin interface
  • content management solutions
    • blog
    • ecommerce
    • intranets
    • large CMS-ish applications
Note well: if you don't need workflows don't be scared because there is no overkill. You can use a one state workflow or no workflow at all for example. No hierarchical data? Use not nestable resources and so on. If it comes out later that you need them it will be quite easy converting your code.

Alternatives

You can use plain Kotti, without the substancek's kotti_backend setup. Or if you prefer noSQL try the excellent substanced (substanced + Pyramid + ZODB). Both solutions are lightweight, tested, well documented and easy to learn. Alternatively if you need really a minimal and unopinionated solution you might use plain Pyramid.

Do you need something more? You might consider to use Plone (https://plone.org) as a framework.

Anyway the good news is that Python is plenty of good options.

substancek architecture details

As already told you the private admin area (backend) and the rest of the application (frontend) are two complete different applications with different settings, different views and shared authentication.

Assuming you are going to use PasteDeploy to run your application, let's consider the following configuration files setup:
  • backend-dev.ini, configures the private admin interface based on Kotti thanks to the kotti_backend plugin
  • frontend-dev.ini, configures your application you are developing (a full CMS frontend implementation or a microapp with just one retail view).
  • development.ini (optional), mount the backend-dev.ini and frontend-dev.ini applications in the same process (/admin for the private admin interface and / for your application). Alternatively you can run the frontend and backend using two processes waiting for requests on different ports and play with rewrite rules.

backend-dev.ini

[app:kotti]
use = egg:kotti

...
pyramid.includes =
    pyramid_debugtoolbar
    pyramid_tm
    kotti_backend.views.override_root_view


kotti.configurators = kotti_tinymce.kotti_configure
    kotti_backend.kotti_configure

kotti.use_workflow = kotti_backend:workflows/simple_backend.zcml

kotti_backend.goto_frontend = 1 
This is a normal Kotti setup with:
  • enabled the (optional) root view override for our admin interface. In other words the default root view will be @@contents instead of the standard Kotti's hello page (see pyramid.includes)
  • added kotti_backend to kotti.configurators
  • override the Kotti's default workflow with the one provided by kotti_backend (kotti.use_workflow). Playing with the additional pview permission you can decide your resources visibility on the frontend. See the workflow definition here https://github.com/Kotti/kotti_backend/blob/master/kotti_backend/workflows/simple_backend.zcml
  • enable a "Goto frontend" link (kotti_backend.goto_frontend) for easy switching from admin interface and frontend 
See more options on the kotti_backend's README file:

frontend-dev.ini

[app:main]
use = egg:Kotti
...

kotti.use_workflow = kotti_backend:workflows/simple_backend.zcml

kotti.configurators =
    your_package.kotti_configure

kotti.base_includes =
    kotti
    kotti.views
On the frontend configuration file we share the same workflow in use on the admin interface (kotti.use_workflow).

One of the most important configuration is the kotti.base_includes override: here we decide what will be loaded on our application. We omit all the Kotti views loaded by default in the standard setup and we load what we want to include where:
  • kotti, loads the kotti "core"
  • kotti.views (optional), load some view discriminators and utils defined by Kotti if you need them
  • your_plugin.your_includes, load your includes registering the views needed by your application
The kotti.configurators typically auto includes your package and tell what should be included in your application (pyramid.includes). See the Kotti documentation for more info.

In other words:
"what is not loaded, it doesn't exist"
so the final result is that there is nothing exposed on the frontend except what you decide to load and extreme control. You can register just only one view application or configure a complex setup for a CMS-like application: it's up to you registering only the views your application needs and no more. This way you can use completely different frontend frameworks, different versions of Javascript libraries, you have no css/js conflicts and no need to hide unneeded things and you decide which resources will be published on the frontend.

See also another advance usage pattern "Using Kotti as a library" http://kotti.readthedocs.org/en/latest/developing/advanced/as-a-library.html

development.ini

# See http://pythonpaste.org/deploy/#paste-composite-factory
[composite:main]
use = egg:Paste#urlmap
/ = config:frontend-dev.ini
/admin = config:backend-dev.ini

[server:main]
use = egg:waitress#main
host = 127.0.0.1
port = 5000
The (optional) development.ini shows how to configure a composite application with different mount points. You can change /admin with /cms or /whateveryouwant depending on your needs.

Examples

You can checkout the https://github.com/substancek/substancek_cms_theme package if you want to see in action a (quite complex) example.

I'm going to provide more and simpler examples (eg: a pretend micro application), see the roadmap.

What are the substancek related packages

Here you can see the whole substancek ecosystem:
  • kotti_backend, generic package that turns Kotti to a private admin area. This is the keystone for every substancek like project
  • CMS-like applications
    • substancek_cms (roadmap), a Kotti CMS distribution with an alternative frontend theme based on SASS, html/templates minification and assets optimization based on Yeoman tools. It will be based on the kotti_project experiment available here https://github.com/davidemoro/kotti_project
    • substancek_cms_theme, an example public side CMS implementation based on Kotti built with SASS and html/templates minification
    • kotti_actions, link actions backend implementation for header, footer and main navigation links
    • kotti_boxes, portlets and box backend implementation
    • kotti_es, elastic search support (to be refactored)
  • common utilities
    • pyramid_html_minifier, generic Pyramid package that introduces Chameleon templates minification with no overhead. Required by substancek_cms_theme.
    • build_commands, generic Python package that defines a set of initialization commands on install (eg: python setup.py npm/bower/gulp) for frontend stuff. Required by substancek_cms_theme.

Who's using substancek technologies

MIP - graduate school of business

The MIP (Politecnico di Milano graduate school of business - www.mip.polimi.it/en) uses substancek technology inside for the private admin interface. This approach is so flexible that let you use Kotti as a private admin content management area and even implement your public views using other frameworks or non Python languages (for example PHP+Symfony2).

See:

substancek_cms_theme

This is a work in progress opinionated CMS frontend implementation that reuses existing Kotti templates and logics.

The look and feel is the same you get with a standard Kotti installation but it shows how to integrate and distribute a Python package integrated with a Yeoman setup (http://yeoman.io) that provides:
  • production vs development setup. In production mode will be used assets and templates from the dist
  • Chameleon templates minification with no overhead thanks to pyramid_html_minifier when you are in "production" mode
  • SASS
  • image/assets optimization
  • build commands for npm/bower/gulp initialization thanks to the generic package build_commands
Once installed you'll see the admin interface visiting http://localhost:5000/cms.
See the code here: https://github.com/substancek/substancek_cms_theme

Next steps

If you want to contribute there is a lot to do:
  • contributions to the Kotti core (for example @@contents pagination, REST, etc and new ideas)
  • creation of the substancek_cms package that puts together the substancek_cms_theme default theme plus the most useful third party Kotti plugins like news, events, etc with decoupled admin interface and Vagrant/Ansible automated setup based on kotti_project for easy installation/evaluation
  • creation of simple pretend packages, add more examples (microapp, blog)
  • a toolbar available on the frontend just of editor users for improved usability (the same shown in the MIP case history) implemented with a Pyramid tween
  • more work on substancek_cms_theme, implement advanced features shown in the MIP case history like link managers and portlets and refactor the Yeoman folder removing what is not strictly needed
  • scaffolding, help people create new projects with decoupled admin interface using Kotti as a framework
  • substancek dedicated github page
Contributions, feedback or pings like "hey, I'm going to use Pyramid/Kotti for the my next project" will be very appreciated!

Documentation

All Kotti posts published by @davidemoro

Twitter links

2015-07-18

Kotti CMS - frontend decoupled from backend. How we did it (part 2)


In the previous article http://davidemoro.blogspot.it/2015/07/kotti-cms-successful-story-part-1.html we have seen that:
  • decoupled public website from the private content management is cool
  • Python and Pyramid is cool
  • don't use PHP please :)
No we will see:
  • how to build a pure Python Kotti based setup with a private content management area decoupled from the public website (with tips, links, technical details and screenshots)
Here you can see some screenshots, implementation details and links.

Project setup

The installation folder is a package that contains all the application-specific settings, database configuration, which packages your project will need and where they lives.

From https://pypi.python.org/pypi/mr.developer.
The installation folder is a "one command install" meta package:
  • replicable
  • under version control + git flow
  • documented + change list for each plugin and the project itself
  • with a tag based deploy
  • based on Python pip/requirements.txt
  • batteries included
  • exceptions logging on file (with logrotate) enabled by default
  • automated deploy
so let the computer works for us and have fun.
See:

Populators

Populators are functions with no arguments that get called on system startup, they may then make automatic changes to the database like content initialization.

Populators are very important because when you install the project folder during development or on the very first production instance you'll find all the most important contents and sections by default. Things will be created automatically if the database is empty, so you don't obtain a blank site on the very first install.

Populators are also good for improving the first impact of the end users (I mean editors) with the platform because they see all the main sections already there.

See:

Private backend area

Turning Kotti CMS into a private content administration is quite easy:
Later I've created a generic package that does all the things for you (kotti_backend):
so things are even easier now (install kotti_backend, done).

Multilingual

kotti_multilingual is your friend.

Goto frontend link, translation management and link to the technical documentation online based on Sphinx
See:

Elastic search

kotti_es provides ElasticSearch integration for fulltext search. This plugin needs more love and and a complete refactor (it was built in a hurry and I'm not yet satisfied) but it proved there are no known issue after months of intensive usage.
Probably things will change, hope other guys with the same needs will contribute.

See:

Main navigation and header/footer links

You can use the kotti_actions plugin if you want to implement footer, header links or even nested main navigation menus. Obviously kotti_actions is ment to be used with a decoupled frontend.

As you can see a custom colour can be assigned to courses, navigation links, sections and every kind of object thanks to the json annotations column provided by default by Kotti. So you can add arbitrary fields.

How the multilevel menu looks like on the public website
See:

Portlets

The main layout based on box managers for portlets
The kotti_boxes is your friend. This plugin is ment to be used with a decoupled frontend. And it was quite quick implementing portlets because we didn't need to customize the private backend area.

You can define different page layouts for each resource type (home page, news, courses, etc) and show boxes in well defined areas (box managers), for example LeftBoxManager, AboveFooterBoxManager and so on.

So box and box managers are just non publishable contents and you can:
Banner portlets with links
  • copy/paste them
  • assign workflow with different security policies to box and box managers
  • assign different views
  • share edit permission to certain box or box managers to particular users or groups
  • prevent certain type of boxes to be included in some areas (for example: banner box image only addable to the left box manager).
See:

Editor toolbar

As you can see if you are logged in the frontend will show an editor toolbar with:
  • link to the backend version of the page
  • object information (state, type of object, etc)
Info and links to the backend, edit and folder contents

or see exactly the website as an anonymous user (very common customer request):

Anonymous view
You can also add more features, for example direct edit links for images or portlets or live edit features.

Talking about a pure Python solution, you might implement this feature with a Pyramid Tween (I hope I'll have enough spare time to do that. Anyone would want to contribute? We are very welcome, contact me!):

Course types (custom content types)

The course view with portlets and collapsable paragraphs
They are a sort of rich documents with an image attachment column and integrated with an external ecommerce site. When you add a course type there is an event that initializes automatically subobjects and the main image attachement by default, so less work for editors.

In addition all image content types and image attachments are addable or editable just by allowed users thank to custom roles and global or local permission sharing.

Collapsable paragraphs are implemented with custom content types not directly reachable on the frontend.

There are a lot of fields on this content type, so they are grouped together using fieldsets.
Editors can also create a base private course model and then copy and paste it when new courses should be added.

Sometimes you want to prevent the addability on the site root for particular object types, this way things will remain always tidy (why you should add a course on the very root of the site?).

See:

Windows and MySQL issues and tips

Kotti can be installed on Windows but I strongly suggest to adopt a Unix-like server with Postgresql instead of MySQLas storage layer: 

Tests

All the software is tested. Very happy with the py.test framework.

See:

Other third party Kotti plugins

I've used the following third party plugins that can be used on a standard Kotti environment:
See also the full list of available plugins:

Photoes and credits

http://www.mip.polimi.it/enAll the screenshots shown in this article are taken from the "MIP Politecnico di Milano's graduate school of business" website:
So the MIP's website backend is powered by Pylons/Pyramid and Kotti CMS, I'll write a non-technical case study soon. In the mean time many thanks to:
  • MIP
    • Simona Strepparola, Head of Communication
    • Gabriele Bedani, Microsoft Sysadmin
    • all the MIP staff
  • Truelab 
    • Riccardo Bonini, project manager
    • Ruben Barilani, web developer
    • Caio Ceccon, web developer (Faculty and Staff implementation). Python developer that joined us for only 5 days but enough to become good friends! He never touched a Pyramid/Pylons or Kotti application but he was able to be productive in a couple of days, this proves the Pyramid/Pylons developer friendliness
    • Davide Moro, it's me
    • Andrea Sironi, creative director

Results

You can consider Kotti as a very good, secure, flexible, battle tested and easy to approach solution for important customers.

All Kotti posts published by @davidemoro

Next steps

Reading this article you should find all the bricks you need if you want to implement a public website decoupled from its backend with Kotti.

Now I'm assembling the above bricks in order to provide an "easy to install" solution with the same pattern I've described here. This is my roadmap:
It can be considered a good starting point for:
  • CMS-ish application
  • a generic framework for building generic web apps or single page web applications (remember, Kotti is not only a CMS, it could be considered as a framework)
So stay tuned and if you like this work please consider to contribute with
  • code
  • testing
  • issue reporting
  • Github stars
  • spreading the word 
or why not sponsorships!

And if you want to know more about Kotti and you are attending +EuroPython Conference 2015 in Bilbao don't miss the Andreas Kaiser's talk "Standing on the Shoulders of Giants: The Kotti Web Application Framework". I'll join the sprint (remotely) at the end of EuroPython so see you on IRC (http://webchat.freenode.net/?channels=kotti). If you want to stay tuned follow https://twitter.com/KottiCMS.

2015-07-16

Kotti CMS - a successful story (part 1)

Yet another Kotti CMS (http://kotti.pylonsproject.org) article.

We'll see in this blog post:
  • advantages of the public website decoupled (frontend) from the private content administration area (backend) pattern
Furthermore in this article you might find traces of:
  • PHP vs Python comparison
  • Symfony2 vs Pylons/Pyramid
  • Plone vs Kotti
  • Python evangelism
But before starting let's explain what is the background of this true story and how Kotti CMS helped a lot.

Update 20150718

Part 2 is out! See:

The challenge

That were the requirements for an important project I joined last January:
  • build a new CMS from scratch (yeah, I know, it doesn't make sense reinventing the wheel: see How to choose your CMS)
  • based on PHP/Symfony
  • with only two (2) developers
  • end user friendly
  • through the web customization for visual sections by editors/administrators (home page text introduction, main navigation, header and footer links, boxes, etc).
  • with an external ecommerce integration
  • custom logics and behaviours
  • custom security based on roles, workflow, permission sharing
  • configurable portlets system (manageable columns)
  • custom navigation link managers
  • multilingual
  • elasticsearch integration
  • nested urls (folders hierarchy)
  • stable
... with a not postponable 3 months deadline!

Obviously there was a previous huge problem at commercial/estimation level and Peppa Pig would have said the famous "THIS IS IMPOSSIBLE!" because build a new CMS is an incredibly enormous task... but let's see why we are still alive and how it was possible to meet these impossible requirements with hard work, a bit of (italian) inventiveness and the Python/Pyramid based Kotti CMS.

1 - Does anyone already found a solution to a similar problem?

Not listed here:
but I think the chucknorrisfacts guys should update their site. Obviously Chuck Norris can solve this problem, he can also prevent it with a roundhouse kick.

2 - Switch technology to Plone attempt

Now I'm serious :)

The first thought was: try to change the technology stack switching to Plone (http://plone.org) but the Windows/PHP/Symfony/MySQL stack was not an option, so no Plone for this project.

3 - Have a look at existing PHP-based CMS solutions

Second step, check if there is a decent CMS solution built with PHP with this requirements:
  • secure
  • easy to extend and maintain
  • with a good and modern codebase
  • with an intuitive backend interface for editors
and we were not able to find any existing solution matching our requirements criteria.
In addition introducing a new framework usually means more time and a lot of pain if you have to customize almost everything if the framework it is not built with flexibility in mind.

4 - try out Sonata + Symfony2 from scratch

We tried to setup a Symfony2 project powered by Sonata and we had a look at to existing early stage "CMS"s Sonata based but it was clear that it wasn't the right tool for building a real content hierarchy aware CMS usable by end users. Trust me, CMS is another sort of thing: you cannot call CMS the ugly version of the Django admin or something that is not suitable for end users. Anyway, Sonata is a quite good solution if you are going to write a data administration area for your custom Symfony2 application. See http://symfony.com/doc/1.0/cmf/cookbook/creating_cms_using_cmf_and_sonata.html and http://demo.sonata-project.org/.

5 - The solution

It was clear that it was impossible for us building a heavy customized CMS with almost "enterprise" requirements based on PHP for our team composition, experience, tight deadlines, etc.

So the solution was: why not adopting a good CMS based on a relational database storage powered by Python (there are very good options) and use it as a content administration backend area with a decoupled frontend built with Symfony2/PHP?

We had a look to Django and Pyramid CMS solutions and Kotti seemed the best option:
  • very good code base (and its core it is damn small)
  • powered by Pylons/Pyramid (quite small, flexible, easy to extend and approachable Python web framework with url traversing capabilities for free)
  • clean user interface
  • powered by SQLAlchemy
  • very very flexible if you need to turn the whole system inside out
  • many good concepts available in Kotti or Pyramid/Pylons are largely inspired by the Zope/Plone world (two decades of successful web applications and content management experience there)
  • it is not only a CMS but a web development framework
This way we were able to be extremely efficient and take advantage of our expertise from the very first day:
  • 1 PHP developer on the PHP-Symfony frontend side
  • 1 Python developer on the Python Kotti CMS backend
As we will see that was our "winning" solution but I don't consider it optimal: this pattern itself is clean, powerful and I think I'll adopt the same technique in the next future in pure Python. Effectively there were some (well known) problems with our setup:
  • PHP is not Python
  • Symfony2 is not Pylons/Pyramid (security, routing, traversal, view declarations with discriminators)
  • Kotti is not Plone (very good solution but it is still quite minimal), so I had to implement the missing parts we need. The good news is that Kotti and Pyramid you are very productive
  • but... Pylons/Pyramid is Pylons/Pyramid! Very happy and damn productive, I really enjoyed programming with this framework. Very impressed.

PHP is not Python

Concepts like decorators not available as PHP builtin: cool things like decorators are only comments that are "compiled" later. And it is more hard implementing new "decorators" and test them compared to Python.

It seems that you cannot set to a class an instance of another class (our Kotti's type_info for example).

Doctrine or Propel works fine if you are adopting the Docrine or Propel pattern. If you need something of different, no way. We wrote a custom abstraction on the top of the pattern used by Kotti and SQLAlchemy for types inheritance with joined tables (!!). Last but not least, SQLAlchemy provides things like:
and it feels quite magic because with PHP solutions the same patterns are not replicable so easily.

Bit operations math for cookies shared auth among Symfony2 frontend and Kotti CMS backend.

Generally it was a bit frustrating having to write a lot of code what you get for free with Python with just 2 lines of code.

Symfony2 is not Pylons/Pyramid

What is Symfony2: it is one of the better frameworks available in the PHP world, probably the most promising. It is not a monolithic framework, you can also use standalone symfony components as well in your non-Symfony PHP projects (many famous existing PHP projects are switching to Symfony). Symfony2 plays well with other existing components like ORMs and it tries to bring innovation to PHP.
It promotes best development practise, testing, modularity, extensibility. It has its own dependency injection system and it let you write templates with a quite good template system named Twig.

Anyway, quite good ideas with concepts stolen from other non-PHP framework, in particular dependency injection plus a configuration hooks if you want to replace existing components without having to modify an existing application (but no component adapter patterns). So with Symfony you can write good code, despite PHP.

Yeah, Symfony2 is quite good and it tries to bring innovation to the PHP world: very good. But if you feel innovative and you like so much innovation why not switching to other technologies that were already more innovative 20 years ago?! And now things are even better. Programming languages like Python and web frameworks like Pylons/Pyramid are on another planet: they really seem built by aliens compared to other PHP frameworks.

For example with Python you have:
  • package managers like pip that exists since many years
  • ORM with extreme flexibility (SQLAlchemy is on another planet too). Doctrine or Propel works fine just if you follow the Doctrine/Propel way, if you need alternative patterns they might not follow your needs with a lot of pain
  • less security vulnerabilities (see https://plone.org/products/plone/security/overview)
  • easy security setup for your applications
  • component adapter patterns
  • easy debugging (PDB)
  • routes and above all concepts like traversal (see  http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/muchadoabouttraversal.html)
  • clean syntax and builtin concepts like decorators and context managers
  • no random byte code cache corruption
  • more productivity
Installation, setup, deploys and installation management seems more simpler too with Python in my opinion. If you setup your projects with pip you can deploy your applications with a couple of commands:
$ git fetch
$ git checkout tags/0.1.5
$ pip install -r requirements.txt
$ restart your application
or if you have complex requirements you can have a look at buildout.
See:
So it is no more time "with PHP you just copy and paste the code" if you are doing things seriously as you can see: http://symfony.com/doc/current/cookbook/deployment/tools.html
Probably complex is the wrong word, it would be better verbose. For verbose I mean: composer install with a lot of options and dump-autoload, clear the Symfony2 prod cache avoiding cache corruption issues and install assets, cache warmup, be sure there are right permissions for writeable directories, etc.
So the "just copy and paste the code" myth (#1) with PHP is not true anymore and I don't like it.

And the very first PHP initial setup on your computer is not so easy. I think for a newbie it is much more easy a different one or two commands approach: install requirements and launch one command.
If you have to start with a PHP/Symfony2 setup just for developing is quite a long and error prone task. That's why my very first experiment with PHP-Symfony2 was: adopt Vagrant/Ansible for environment setup and provisioning. If you need a Vagrant/Ansible example you can have a look at here: https://github.com/davidemoro/symfony-vagrant-ansible.

Another false myth (#2): the most used technology it is better than others: no.

Yet another false myth (#3): the most used technology is more secure: no, absolutely not. See again https://plone.org/products/plone/security/overview.

Let me show other things you can do better with Python:
  • "byte code cache" corruption issues
  • missing traversal concept
  • views registration and override
  • debugging
  • security configuration
The idea of a byte code cache (http://symfony.com/doc/current/book/performance.html) is to remove the need to constantly recompile the PHP source code for improved performance. There shouldn't be any downside but we experienced random problems with cache corruption (not funny when it happens in production).

Symfony2: traversal... what?! You need to implement it, while in Pylons/Pyramid comes for free. See http://docs.pylonsproject.org/projects/pyramid//en/latest/narr/muchadoabouttraversal.html

Add or customize views. Just one example: register or override the default view of a Document only if its parent is a Course if damn easy with Pylons/Pyramid (just register a new view with a discriminator, one line). With other frameworks you'll need to write a lot of not generic code. See http://docs.pylonsproject.org/projects/pyramid//en/latest/narr/viewconfig.html

Debugging is a pain with PHP. Debugging things with PHP and/or Symfony is a bit frustrating if you had previous experience with the Python debugger (pdb) or with the pyramid debug toolbar and its interactive through the web exception shell. If something goes wrong you can see what's the problem interactively or why a variable is "None" without leaving the browser. See:
I didn't liked at all the security configuration of the Symfony2 framework with its "firewall" concept: the official doc itself admits it might be confusing and tough to set up just "because security is complex!" (see https://symfony.com/doc/current/book/security.html). Things can be complex but if your API lead people to be confused, probably you have a bad design problem.
Anyway it is more easy working with Pylons/Pyramid if you are going to write applications with complex security requirements (even workflow-based security thanks to the third party repoze.workflow). See http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html

I hope you don't consider the above personal thoughts as not constructive rants: Symfony2 is a good and promising PHP framework and if you are interested in building web applications with PHP it is definitively a very good choice. I have been working with Symfony for 6 months and this is just my opinion compared to my previous programming experience with Zope, Plone, Grok, BFG, Pylons/Pyramid, Django and a bit of Nodejs/Express (KeystoneJS, SailsJS, etc).

So the previous Symfony2/PHP vs Python/Pyramid/Python comparison boils down to: if you are a curious web developer I think it really worth leaving your "comfort zone" and have a look at something of new. It doesn't matter if you are going to use Python (Django, Pyramid/Pylons, Flask, morepath, etc), Ruby, NodeJS or whatever else: you'll learn a lot of useful new things for sure and innovate your work!

Kotti CMS is not Plone

Kotti is very lightweight framework and its core is damn small because:
  • a lot of things are demanded to the SQLAlchemy layer for storage, queries, indexing, etc.
  • simpler stack compared to Plone/Zope/CMF/Archetypes/Dexterity/etc (just Kotti, Pylons/Pyramid, SQLAlchemy + a list of well known and widely adopted third party libraries. So if you spend time learning Pylons/Pyramid, you can easily switch to other frameworks). For example if you have to write event handlers with Kotti you'll notice that things are more simpler (no event handlers hell or having to manage duplicated events)
  • tries to keeps things simple
  • new programmers with no Pylons/Pyramid background are productive after a couple of days
and probably in next releases its core will shrink again.

It is very easy to start with: just a couple of days and you will be ok because it is very lightweight.

So programmers with no Pylons/Pyramid nor SQLAlchemy knowledge (or even not Python developers) will be productive very soon with Kotti. Obviously if you have a previous SQLAlchemy, Plone, Pylons/Pyramid or any other Python frameworks background it is better but it is not required at all.

I think Kotti is very good if you have to write a custom relational database based application with CMS-ish features without having to remove all the things provided by Plone that you don't need at all: with Kotti or Pylons/Pyramid you only pay for what you eat. But Kotti is not only good for CMS-ish applications: it a framework that does very well as a backend for heavy Javascript single page web applications.

Obviously Kotti is not Plone:
  • community (the Plone's community is much more large)
  • Plone has a lot of third party plugins
  • no auto generated add/edit forms (not a problem because it is very simple to create or customize forms thanks to Colander/Deform. So no z3c.form there!)
  • no portlets (topic covered in next blog post)
  • no link actions (eg: portal_actions, topic covered in next blog post)
  • missing permalinks and not breakable links
  • no collections
  • no PloneFormGen-like plugins (but we used a very good form builder solution available online as a service with integrated CRM)
  • etc
but if you need a feature not provided by Kotti or other third party plugins don't worry because you will be productive very soon, even more if you adopt a frontend decoupled from the backend pattern.

Why frontend decoupled from the backend pattern

A couple of definitions about my frontend and backend concepts:
  • frontend. It is our public website, where anonymous users browse the contents of the website. In our case it is built with PHP/Symfony2 but obviously you can also do all things with Python alone (pure Python is the best option)
  • backend. It is our private content management area, built with Kotti CMS, Pylons/Pyramid and Python
This pattern is so flexible that let you implement the public area with a completely different technology. This way you can choose the best solution for the content management private area (for example: Python) and keep control of the frontend with your in-house developers (for example: PHP).
If you adopt a separation among frontend and backend your work will be even more agile:
  • you can start with a "blank sheet" theme (topic covered in next articles)
  • you don't waste time removing or hiding features or unneeded views, just implement what you need. Probably guys with experience with big fat frameworks understand what I mean.
  • no CSS or Javascript conflicts with the backend. You won't be influenced at all how to integrate your usual frontend toolchain with a framework with its own tools or opinions because they are two completely different applications. So there is absolute frontend freedom, just choose the development stack you prefer
  • you can develop new complex features like portlets (box shown in views) without having to touch at all the backend interface because the backend is just a (raw) backend area! They are just another type of content (not publishable on the frontend but rendered in views). So you can adopt workflows on portlets, you can copy/cut and paste them, use different views on portlets, assign custom views, create custom addability rules based on portlet types, etc. This way you can develop complex features like portlets in a fraction of time!
  • since the frontend and the backend are served on the same domain, there is shared authentication so you can implement toolbar, live edit or view site as anonymous for editors
  • less SEO headaches for non-publishable objects (portlets, tabs, collapsable sections, etc), you can store in the administration area objects that won't be published by the frontend at all. It is very handy implement these things like regular contents because you inherit workflows, same navigation/editing interface, etc. For example you can manage collapsable paragraphs as regular content type objects on the backend (yoursite.com/cms/document/paragraph1) but they will be rendered on the document view yoursite.com/document (if you try to access yoursite.com/document/paragraph1 from the frontend you'll get a 404 NotFound). Since they are not published on the public website you don't have to protect urls, no need to redirect to the main parent content, etc: all these things requires a lot of extra work if you want to take care of this kind of details
  • if you use the same technology for the public website and the private area, you can reuse code already defined on the backend (for example you can reuse the breadcrumbs callable view with a completely template)
And more:
  • faster. You can build the frontend with less security checks (just expose public data with less complexity due to assertion about local roles, groups, etc)
  • more secure. You'll keep the administration area (backend) completely private and the frontend in our case built with PHP with a low privilege database user (readonly)
  • you can rebuild the frontend without having to touch the administration area (backend)
  • frontend easy replaceable
  • different fulltext search policy for frontend vs frontend. On the backend there is the standard search results (you search for a text contained on a collapsable document and you'll land on that collapsable document on the backend, just what you expect from the editor perspective). If you search the same word on the public website you'll land on the parent document of the collapsable document (good for visitors) 

Photoes (credits)

A-team photoes from http://iqtell.com/2014/05/10-reasons-why-the-a-team-is-better-than-your-team/

All Kotti posts published by @davidemoro

End of part 1

In this article we have seen that:
  • decoupled is cool!
  • Python is cool!
Instead in next blog posts I'll talk about:
  • how to build a pure Python Kotti based setup case study with a private content management area decoupled from the public website (with tips, links and screenshots, etc).

Update 20150718

Published part 2! See:

2015-05-29

Kotti CMS - how to add new roles

Kotti CMS has an intuitive user and permissions management that scales to fit the requirements of larger organizations.

This blog post is a small recipe: how to add a new role in user management views and sharing views for local roles management.

It is quite easy, it requires few lines of code you can add to your __init__.py module:
from kotti.security import (
    Principal,
    ROLES,
    SHARING_ROLES,
    set_roles,
    set_sharing_roles,
    set_user_management_roles,
    )
from kotti_yourpackage import _


def add_role(role_id, role_title):
    """ Add role in share view and user management views """
    UPDATED_ROLES = ROLES.copy()
    UPDATED_ROLES[role_id] = Principal(role_id,
                                       title=role_title)
    UPDATED_SHARING_ROLES = list(SHARING_ROLES)
    UPDATED_SHARING_ROLES.append(role_id)
    set_roles(UPDATED_ROLES)
    set_sharing_roles(UPDATED_SHARING_ROLES)
    set_user_management_roles(UPDATED_SHARING_ROLES + ['role:admin'])


add_role(u'role:customer', _(u'Customer'))

And now, we have a new Customer role ready to be used:

As you can see there is a new (pretend) "Customer" role
You can assign the Customer role as global or local (just on single nodes) to end users or even better group of users.

After that you can work with ACLs or, better, configure what the customer role can do writing a custom workflow (see http://davidemoro.blogspot.com/2015/02/kotti-cms-workflow-reference.html).

All Kotti posts published by @davidemoro:

2015-05-23

Kotti CMS - ElasticSearch integration

Announcing a new Kotti CMS (Python web framework based on Pylons/Pyramid and SQLAlchemy) plugin that provides ElasticSearch integration for fulltext search and indexing:
Development status? It should be considered experimental because this is the very first implementation. So any kind of help will be very appreciated! Beer, testing, pull releases, feedback, improving test coverage and so on.

Acknowledgements

kotti_es is based on a pyramid_es fork (https://github.com/truelab/pyramid_es/tree/feature-wrapper, there is a PR in progress). The pyramid_es author is Scott Torborg (https://github.com/storborg).

Configuration

The configuration is very simple.

Just enable the kotti_es plugin just add the kotti_es plugin, choose the index name and elastic search server addresses.

From the kotti_es README file:
kotti.configurators =
    kotti_es.kotti_configure

elastic.index = your_project
elastic.servers = localhost:9200
elastic.ensure_index_on_start = 1
kotti_es.blacklist =
    Image
    ...

kotti.search_content = kotti_es.util.es_search_content

Index already existing contents

With kotti_es you can reindex all your already existing contents without any change to the original Kotti code base with just one command:
$ reindex_es -c app.ini
So kotti_es plays well with models defined by third party plugins that are not ElasticSearch aware. You can install kotti_es on an already existing Kotti instance.

Custom behaviours

If you want you can override/extend the default indexing policy just registering your custom adapter. See the kotti_es tests for more info.

So no need to change existing models, no need to inherit from mixin classes and so on.

Video

kotti_es in action:

Wanna know more about Kotti CMS?

If you want to know more about Kotti CMS have a look at:
All Kotti posts published by @davidemoro:

2015-04-11

kotti_multilingual

kotti_multilingual is a package still in an early stage of development that adds to the Kotti CMS (http://kotti.pylonsproject.org/) multilingual capabilities. It is neither feature complete nor can be considered API stable: so things will change!

You can find various fixes on this fork (a PR is still in the review phase):

How it works

First of all you should add a LanguageRoot folder in your root site. It is like the standard folderish Document, but with an editable Language attribute where you set the language code (eg: en, it, etc).

Once you have created two or more language folders (with >2 languages there is a problem with the translation link actions at this time of writing) you can add your contents and translate them.

The translate menu prompts a translate into italian action from  /en/welcome
If you click on the translate into action, it will create a translated instance in /it/welcome (you can rename it later in /it/benvenuto or whatever you like) and you'll be redirected to a regular edit form prefilled with the english fields values.

Once saved, you can switch to the existing translation and navigate among languages as shown in the following picture:

You can switch to the existing English translation
kotti_multilingual supports the quite advanced concept of language independent fields: a field whose values should be inherited by translations, only editable on the root translation.

You can see for example a select widget in edit mode on the root translation:
And the same field in readonly mode on the translated object:

See the kotti_multilingual.widget.i10n_widget_factory code for more info.

Code examples

And now code examples.

resources.py

You can define language independent fields in your type_info attribute on your resource.
class YourResource(...):

    ... 

    type_info = Document.type_info.copy(
        ...
        language_independent_fields= ['course_sku',],
        )

views/edit.py

The edit form does not require changes, you just need to apply the i10n_widget_factory on your language independent fields (in some particular cases you need a bit more complex setup when you have to deal with not null column, required fields, etc). In these particular cases you'll have to play with get_source (kotti_multilingual.api.source) and put the widget in readonly mode. If you experience problems cloning select widgets you might have to migrate to deferred widgets (that creates a new widget instance each time) and set the widget mode in readonly when needed.

from kotti_multilingual.widget import i10n_widget_factory
...
from kotti_multilingual.api import get_source 
@colander.deferred
def deferred_widget(node, kw):
    request = kw['request']
    context = request.context

    ...

    widget = SelectWidget(values=available_tags, multiple=True)
    if get_source(context) is not None:
        widget.readonly = True
    return widget


class YourResourceSchema(colander.Schema):

    course_sku = colander.SchemaNode(
        colander.String(),
        title=_(u"Course SKU"),
        missing=u"",
        widget=i10n_widget_factory(TextInputWidget),
        )


class YourResourceAddForm(ImageAddForm):
    schema_factory = YourResourceSchema
    ...

    def get_bind_data(self):
        bind_data = super(YourResourceAddForm, self).get_bind_data()
        # we tell to the i10n_widget_factory that this is an addform,
        # so our widgets will be shown as usual in edit mode
        bind_data['addform'] = True
        return bind_data

Final thoughts

Yes, it is a very very young package but very promising!
It is not complete and probably it never will be complete because SQLAlchemy is huge and I think it is not possible to cover all the possible SQLAlchemy combinations.

For example this fork includes support for the SQLAlchemy's association_proxy feature and language independent fields (in this case the copy_properties_blacklist attribute on your resource is your friend).

This is open source, dude: if you need something that is not yet covered, just fork kotti_multilingual, implement the missing parts and share with others!

Update 20150427

Merged and released new version of kotti_multilingual on PyPI https://pypi.python.org/pypi/kotti_multilingual/0.2a3.
Development happens on https://github.com/Kotti/kotti_multilingual now.

All Kotti posts published by @davidemoro:

2015-04-01

How to choose your CMS

This article is dedicated to non Python folks searching for a good CMS because I've seen too many times people taking bad decisions.

If you are searching for a CMS solution or are you writing a custom web application with content management features inside, you should consider also one of the existing solutions built with Python before choosing your platform. Even if your core business is based on different technologies or other programming languages like Java or PHP.

I'm not telling that you have to choose Python solutions, I'm just suggesting you to start with a 360 degrees serious software selection before choosing.

Obviously the final choice depends on what you have to do: a lot of times a Wordpress site with a few dollars theme and a couple of third party plugins is good enough.

But if you are plan to build something more complex that involves:
  • top level security solutions 
  • complex security requirements 
  • extensibility without having to fork the existent code
  • heavy, but still maintainable, customizations in core logics
  • you are not going to build a website, but something of more complex like an intranet
  • you are going to build something that can evolve for covering future changes without requiring a complete rewrite
you should evaluate carefully your future platform before deciding.

If you have the above strong requirements, you can have a look at the following projects:
  • Plone (nosql, enterprise level, a lot of plugins)
  • Kotti (traditional database storage, more lightweight, easy to approach)
They are both Python based, quite different solutions but they have common roots and a long CMS tradition. They are open source, secure, with a friendly an skilled community and a clean editing experience compared with other "CMS" solutions (you can't call CMS something that looks like a messy version of an admin interface! Just good for technicians or for small projects, not for content editors).

I'm just suggesting: if you are evaluating CMS frameworks, don't choose a solution because it is built with your preferred programming language or framework but consider also other existing solutions. Don't choose a project because you were able to change the logo and few colours quickly. You should evaluate the main available solutions and after that choose the best fit for you... and be prepared to change technology if needed.

Change attitude also means continuously searching for something of better, find new opportunities, learning something of new, learn new development pratices, get involved in other open source communities: it is definitively a good thing. You are not disrupting your existing knowledge, you are improving your experience and enlarging your knowledge. So don't be scared, choose the best for you and be open minded!

Another hint: don't be tempted to write from scratch a new CMS unless you are know well what you are doing and/or you have a good budget with dozens of experienced developers. Still having the idea of writing your new CMS from scratch?! Have a look at how many contributors and how many years are needed before an open source CMS it is considered stable with a good feature set and then decide. Don't reinvent the wheel!

Or if you don't want to learn another framework or programming language but you found the best fit for you: hire a consultant but always choose the best.


PS: if you like adventure and you chose a RDBMS based solution like Kotti you have another option: you can follow a hybrid approach.

This way you can use Kotti as a private content management area and implement your public website with the technology or frontend tools you like exposing data marked as published on the database. There are a lot of benefits due to backend decoupled from the frontend.

Maybe I'll talk about a similar successful case history built with this technique in an another blog post. Stay tuned with @davidemoro.

Update 20150720 - hybrid approach

2015-03-28

Pyramid exceptions logging

If you want to log exceptions with Pyramid (http://www.pylonsproject.org/) you should start reading carefully the following resources:
and once enabled pyramid_exclog check your tween chain order as explained here http://pyramid-exclog.readthedocs.org/en/latest/#explicit-tween-configuration.

If you get in trouble some some reason, maybe you'll find this article helpful in some way. Depending on how you serve your application, it might happen that your .ini configuration logging settings are not considered at all.

Covered arguments in this post:

How to configure your PasteDeploy .ini file

In the following example I'm using the handlers.RotatingFileHandler (a python logrotate implementation), but feel free to use FileHandler (without handlers.).
You can configure your production.ini like the following one:
...
###
# logging configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###

[loggers]
keys = root, mip_project, exc_logge

[handlers]
keys = console, exc_handle

[formatters]
keys = generic, exc_formatter

[logger_root]
level = WARN
handlers = console

[logger_mip_project]
level = WARN
handlers =
qualname = mip_project

[logger_exc_logger]
level = ERROR
handlers = exc_handler
qualname = exc_logger

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[handler_exc_handler]
class = handlers.RotatingFileHandler
args = ('exception.log', 'a', 10000000, 10)
level = ERROR
formatter = exc_formatter

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

[formatter_exc_formatter]
format = %(asctime)s %(message)s

[uwsgi]
plugin = python
...
master = true
processes = 1
threads = 4
virtualenv = %d/your_python
chdir = %d
home = %d/your_python
In the above example it is important omitting %(here)s/ in the RotatingFileHandler args, otherwise it won't be resolved running your app with uwsgi.

If uwsgi complains about no paste.script.util.logging_config is available

If your logger configuration is not considered by uwsgi and you see a warning more or less like a missing "paste.script.util.logging_config" module, just install PasteScript in your virtualenv:
(your_python) $ pip install PasteScript
And make sure your [uwsgi] section is pointing to your virtualenv (see previous section).

Anyway, once installed PasteScript (I've tested the 1.7.5 version), all went fine:
$ uwsgi --ini-paste-logged production.ini
Unfortunately I wasn't able to get exception logs enabled if I call the above command in a supervisord configuration file. Any suggestions?

See also:

Windows service and  CherryPy

If you want to serve a Pyramid application with CherryPy (or creating a CherryPy based Windows service) with exception logging enabled you'll have to setup logging by hand because CherryPy does not consider your logging configuration.

See also:
You can follow the above guides and add the bold lines in your pyramidsvc.py in order to have exceptions logged:
from cherrypy import wsgiserver
from pyramid.paster import get_app
from pyramid.paster import setup_logging
import os
... 
    def SvcDoRun(self):
 
        path = os.path.dirname(os.path.abspath(__file__))

        os.chdir(path)

        app = get_app(CONFIG_FILE)
        setup_logging(CONFIG_FILE)
        .... 

Links

A very interesting overview on Python logging and syslog:

2015-03-24

Pyramid, MySQL and Windows: the good, the ugly and the bad

Pyramid, MySQL and Windows: the good (Pyramid), the ugly and the bad. This title does not fit perfectly the main characters of this blog post because some of theme are both ugly and bad, but it doesn't matter.

Just in case you are going to set up a Pyramid project based on MySQL and Windows (sometimes you have to)... there are a couple of things useful to know. But let's start with a chronologically order.

Day 0 - morning

You feel like the brave Steeve McQueen:

Evening - day 0

At the end of the day you'll feel also like Steeve McQueen, but a little more proved:


What happened?

Random problems with normal transactions considered too large, thread disconnected, error log entries like:
  • InterfaceError
  • OperationalError
  • MySQL Server has gone away
  • database connection failure
  • TimeoutError: QueuePool limit of size ... overflow ... reached, connection timed out, timeout ...
  • pyramid process hangs
  • etc

The solution


1 - adjust your my.ini options like that:
[mysqld]
max_allowed_packet = 64MB    # adjust this parameter according to your situation
wait_timeout = 28800
interactive_timeout = 2880 
2 - be sure your production.ini file looks like the following one (with Python 2):
sqlalchemy.url = mysql+mysqldb://USER:PASSWORD@127.0.0.1:3306/YOURDB?charset=utf8&use_unicode=0
# For Mysql "MySQL Connection Timeout and SQLAlchemy Connection Pool Recycling" issues see:
# http://docs.sqlalchemy.org/en/latest/core/pooling.html#setting-pool-recycle
# http://douglatornell.ca/blog/2012/01/08/staying-alive/
sqlalchemy.pool_recycle = 3600
3 - you can schedule a restart of your application once a day.

4 - [OPTIONAL, not only Windows related] adjust your SqlAlchemy configuration parameters according to how many threads your server runs. For example (production.ini):
sqlalchemy.pool_size = 20
sqlalchemy.max_overflow = 10
5 - if you are using CherryPy as a Windows service, be sure your  'engine.autoreload.on' option is set to False.


6 - [UPDATE20150401] check your sql-mode if you want to prevent not handled ProxyError exceptions due to input longer than the max size provided on the field model. See https://github.com/Kotti/Kotti/issues/404


 Results


No more exceptions or odd behaviours!

Links