31 Jul 2015
This is an overview of getting Plone 4 (4.3.6 at the time of writing) up and running in 5 minutes or less on Cloud9 IDE. The aim of this is to make it easy, especially for students, to try out Plone, and more importantly Plone development for zero dollars. My previously recommended cloud based options (Nitrous and Codio) no longer offer a viable free tier. Step 0 - Get a Cloud9 IDE account You
31 Jul 2015 12:33pm GMT
28 Jul 2015
October 12 and 13: free training from experienced Plone trainers. Whether you're new to Plone or an advanced developer, we have a class for you!
28 Jul 2015 7:15pm GMT
I am going to do a daily blog everyday for 100 days. Today, I participated in a AMA with Seth G...
28 Jul 2015 4:39am GMT
27 Jul 2015
The Plone Conference organizers are pleased to announce that submissions are now being accepted from the community for talks at the 2015 Plone Conference in Bucharest.
27 Jul 2015 1:55pm GMT
The following text is in German, since we're announcing a regional user group meeting in Düsseldorf, Germany.
Das nächste Python Meeting Düsseldorf findet an folgendem Termin statt:
Bereits angemeldete Vorträge
"Eine Einführung in das Routing von Pyramid"
"Python Idioms - Tipps und Anleitungen für besseren Python Code"
"Bericht von der EuroPython 2015"
Weitere Vorträge können gerne noch angemeldet werden. Bei Interesse, bitte unter email@example.com melden.
Startzeit und Ort
Wir treffen uns um 18:00 Uhr im Bürgerhaus in den Düsseldorfer Arcaden.
Das Bürgerhaus teilt sich den Eingang mit dem Schwimmbad und befindet sich an der Seite der Tiefgarageneinfahrt der Düsseldorfer Arcaden.
Über dem Eingang steht ein großes "Schwimm'in Bilk" Logo. Hinter der Tür direkt links zu den zwei Aufzügen, dann in den 2. Stock hochfahren. Der Eingang zum Raum 1 liegt direkt links, wenn man aus dem Aufzug kommt.
>>> Eingang in Google Street View
Das Python Meeting Düsseldorf ist eine regelmäßige Veranstaltung in Düsseldorf, die sich an Python Begeisterte aus der Region wendet.
Einen guten Überblick über die Vorträge bietet unser PyDDF YouTube-Kanal, auf dem wir Videos der Vorträge nach den Meetings veröffentlichen.
Das Python Meeting Düsseldorf nutzt eine Mischung aus Open Space und Lightning Talks, wobei die Gewitter bei uns auch schon mal 20 Minuten dauern können :-)
Lightning Talks können vorher angemeldet werden, oder auch spontan während des Treffens eingebracht werden. Ein Beamer mit XGA Auflösung steht zur Verfügung. Folien bitte als PDF auf USB Stick mitbringen.
Lightning Talk Anmeldung bitte formlos per EMail an firstname.lastname@example.org
Das Python Meeting Düsseldorf wird von Python Nutzern für Python Nutzer veranstaltet.
Da Tagungsraum, Beamer, Internet und Getränke Kosten produzieren, bitten wir die Teilnehmer um einen Beitrag in Höhe von EUR 10,00 inkl. 19% Mwst. Schüler und Studenten zahlen EUR 5,00 inkl. 19% Mwst.
Wir möchten alle Teilnehmer bitten, den Betrag in bar mitzubringen.
Da wir nur für ca. 20 Personen Sitzplätze haben, möchten wir bitten, sich per EMail anzumelden. Damit wird keine Verpflichtung eingegangen. Es erleichtert uns allerdings die Planung.
Meeting Anmeldung bitte formlos per EMail an email@example.com
Weitere Informationen finden Sie auf der Webseite des Meetings:
Viel Spaß !
Marc-Andre Lemburg, eGenix.com
27 Jul 2015 8:00am GMT
22 Jul 2015
NOTE: Please be aware that this document and instructions are old. Social media have updated the way you added media feeds to your website. The content below this is here only for reference. Please don't use it as is. Unless you have to don't do anything in the ZMI. New documentation for adding feeds is being written.
There are three wayds to add social networking sharing actions to your document actions.
This method uses each online service provider's individual script.
- In the ZMI, Click on portal_actions, then document_actions.
- Add a CMF Action from the drop-down menu
- Fill in these values for Facebook:
- id: facebook
- Title: Share on Facebook
- Description: Share the URL of the current page (or event) on Facebook
- i18n Domain: plone
- icon: string:$portal_url/facebook_icon.gif
- Condition: leave blank - it will show under all conditions
- Permissions: view
- Visible: checked
note. If after trying the above method the results show the text but not the images you'll need to modify portal_view_customizations/zope.interface-plone.abovecontenttitle.documentactions. Use this how to "How to change document actions from text to icons"
This method uses the addthis.com service to share using many different online services.
In ZMI, go to portal_view_customizations and customize plone.abovecontenttitle.documentactions.
Within the <ul> block but after the <tal:actions> block, add the following:
The complete viewlet template should look like this:
This results in the following:
If you put the mouse over the "share this" document action, this is what you get:
You can change the script src to choose which sharing services you want to make available, the order they appear in, and so on. For more information, see addthis.com.
This method uses the product collective.plonebookmarklets from http://plone.org/products/plonebookmarklets.
WARNING: Nathan had the following to say about this product:
To install this, you have to add "collective.plonebookmarklets" to your buildout.cfg in both the eggs and zcml sections, rerun bin/buildout, then restart your Zope.
The resulting document action looks like this:
22 Jul 2015 8:32pm GMT
Since Plone 5 was pre-released, we decided to provide internet users with the ability to test its capabilities. Plone 5 comes with a lot of enhancements, greater flexibility and control.
You can "touch and feel" new features by going to http://plone5demo.quintagroup.com/.
Demo website has account that gives users rights and permissions of site administrator. This user role provides access to all Plone features, such as adding content, publishing content, managing site users and groups, configuring site settings, etc.
Plone 5 Demo site contains several illustrative presentations of popular add-ons, including themes, custom forms (collective.easyform package allows creation of forms through the web), and embed service (collective.embedly package allows to embed video, images and other rich media files to Plone simply by providing their URL).
Plone 5 features
Plone 5 became faster. Now it uses Chameleon template rendering engine that reduces rendering time by 30%. New features and functionality you can experience with Plone 5 and on our demo website are listed below.
The new default theme is called Barceloneta. It is responsive out of the box and compiled with LESS. Diazo theming is enabled by default, so this theme can be edited through the web. Plone 5 uses HTML5 and allows choosing front-end framework, like Bootstrap.
The content management toolbar was redesigned and now users can manage content using pull-out panel. It can be expanded from one icon to full toolbar and repositioned. It is separated from content for easier styling, so users can always see a correct view of the pages.
TinyMCE became more accessible and mobile friendly. Drag&drop uploads and content reordering are now also available.
Dexterity content types are now used in Plone out of the box. Products.Archetypes, Products.ATContentTypes, archetypes.schemaextender are available as add-ons, mainly for older content. For instance, content migrations can be customized with a help of schema extender.
Multilingual functionality is now shipped with Plone by default, so you can always translate your content and keep translations in order.
Plone was always known as the open source CMS with the strongest security available. Plone 5 can boast automated Cross Site Request Forgery (CSRF) and click-jacking protection. Security levels can be customized based on the needs of particular website.
Experiment on our Plone 5 Demo Site
Use our demo site for experimentation. Although this Plone version is a pre-release, experienced developers can implement Plone 5 based solutions. Contact us if you are interested in Plone development.
22 Jul 2015 11:35am GMT
Fast-forward to summer 2015: we've already done a Mercury "technology preview" release and are now in feature freeze, preparing for the 1.0 release, codename Venus, this summer.
As you can see in the video, for all of us it's very important to be part of the open source community that is Plone.
At the same time, we use a different process: design driven, which impacts our code structure and the way integrators can leverage the Plone Intranet platform.
Sharing and re-use
All of our code is open source and available on Github. In terms of re-use we have a mixed strategy:
First of all it's important to realize we're doing a design-driven product, not a framework. We have a vision and many components are closely integrated in the user experience (UX). From a UX perspective, all of Plone Intranet is an integrated experience. Sure you can customize that but you have to customize holistically. You cannot rip out a single feature and expect the UX for that to stand on it's own.
In the backend the situation is completely different. All the constituent packages are separate even if they live in one repo and one egg. You can install ploneintranet.microblog without installing the whole ploneintranet stack: i.e. the whole ploneintranet source needs to be there (at the python level) but you can load only the ploneintranet.microblog ZCML and GS and you'll be fine. All our packages have their own test suites which are run independently. Of course you need activitystream views to display the microblog - and that's frontend UX and one of the most complex and integrated parts of our stack, with AJAX injections, mentions, tagging, content mirroring and file preview generation.
Another example is search: a completely re-usable backend but you'd have to provide your own frontend. Our backend is pluggable - we currently support both ZCatalog and Solr engines and expect to also support Elastic Search in the future. We have documented our reasons for not reusing collective.solr.
Design and user experience are key
We don't believe that loosely coupled components with independent developer-generated frontends create a compelling user experience. Instead of working from the backend towards the frontend, we work the other way around and focus on creating a fully integrated, beautiful user experience.
The downside of that is that it becomes more difficult to reuse components independently. That's a painful choice because obviously it reduces open source sharing opportunities. We do open source for a reason, and you can see much evidence that we care about that in the level of our documentation, in our code quality, and in the careful way we've maintained independent backend packages, including listing component package dependencies, providing full browser layer isolation and most recently providing clean uninstallers for all our packages.
Plone Intranet is a huge investment, and we're donating all our code to the Plone community. We hope to establish a strong intranet sub-community while at the same time strengthening the vibrancy of the Plone community as a whole.
22 Jul 2015 9:00am GMT
20 Jul 2015
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
- advantages of the public website decoupled (frontend) from the private content administration area (backend) pattern - a true story http://davidemoro.blogspot.com/2015/07/kotti-cms-successful-story-part-1.html
- decoupled public website reference (technical reference, links, screenshots, case study) http://davidemoro.blogspot.com/2015/07/kotti-cms-frontend-decoupled-backend-part-2.html
20 Jul 2015 8:35am GMT
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.
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.
The installation folder is a "one command install" meta package:
- 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.
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.
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).
kotti_multilingual is your friend.
|Goto frontend link, translation management and link to the technical documentation online based on Sphinx|
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.
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|
|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).
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):
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?).
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:
All the software is tested. Very happy with the py.test framework.
Other third party Kotti plugins
I've used the following third party plugins that can be used on a standard Kotti environment:
- kotti_calendar for events (very good solution!)
- kotti_newsitem for news
- kotti_navigation, add a configurable navigation on our backend
- kotti_link, link types
See also the full list of available plugins:
Photoes and credits
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:
- Simona Strepparola, Head of Communication
- Gabriele Bedani, Microsoft Sysadmin
- all the MIP staff
- 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
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
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:
- kotti_backend (https://github.com/Kotti/kotti_backend). Already published on PyPI, ready to be used. Turns Kotti CMS into a private content administration area
- kotti_frontend (https://github.com/Kotti/kotti_frontend). Public website solution completely decoupled by the Kotti backend with modern frontend tools (I want to obtain something like http://davidemoro.blogspot.it/2014/09/plone-angularjs-yeoman-starter.html or http://davidemoro.blogspot.it/2014/09/pyramid-starter-seed-yeomam-part-1.html). Optional support for blank sheet themes if you need more flexibility. It is just an incomplete but quite promising prototype, it is still under development.
- a new pyramid tween implementing the editor toolbar available on the public website (TODO)
- a meta-package "one command" installer based (a modified version of https://github.com/davidemoro/kotti_project). Still in TODO
- installable themes and themes generation (scaffolding)
- a Kotti distribution that provides all the most useful third party plugins, just if you need a CMS. Now you have to install all external components manually.
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
- 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.
20 Jul 2015 7:43am GMT
19 Jul 2015
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.
Part 2 is out! See:
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
- elasticsearch integration
- nested urls (folders hierarchy)
... 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:
- 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:
- association_proxy (used in Kotti tags). See http://docs.sqlalchemy.org/en/latest/orm/extensions/associationproxy.html
- other techniques used by kotti_multilingual used for independent fields. See https://github.com/Kotti/kotti_multilingual/blob/master/kotti_multilingual/sqla.py
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.
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
- 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.
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)
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.
- 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)
- 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)
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).
Published part 2! See:
19 Jul 2015 8:59pm GMT
17 Jul 2015
Andreas Jung: XML-based Publishing with Plone, Exist-DB and XML-Director - onkopedia.com case study published
17 Jul 2015 12:38pm GMT
16 Jul 2015
I attended the Nonprofit Technology Conference last March and was inspired to submit a session proposal for next year's conference. So much of our work here at Jazkarta helps non-profit organizations do their jobs better - through their websites and back office systems - that I feel we have lots of useful information to share. So I proposed to tell the story of the major website redesign project that Jazkarta and Percolator Consulting did with The Mountaineers. The story would cover the full project life cycle, from strategy definition through support and ongoing changes. It would be told from 3 perspectives: the team responsible for the front end CMS, Plone (that's us), the team responsible for the back end CRM, Salesforce (that's Percolator), and the team responsible for defining, funding, managing, and coordinating this massive project (that's The Mountaineers). And it would give us the opportunity to highlight the practices that made this project so successful. Things like:
- How we defined requirements, content types, and data model
- The importance of user experience (UX) design
- The agile process we used to manage implementation
- Coordinating a large number of volunteers testing the new site
- Planning and executing a complex launch process involving front end and back end data migrations
The session is called Anatomy of a Major Website Project and if you think this would be a good addition to next year's NTC and to share with the non-profit community more broadly, please head over to the 16NTC site and upvote it!
16 Jul 2015 2:41pm GMT
14 Jul 2015
A content-driven website can look like an intimidating pile of information to the average visitor. You want to help your visitors find what's important to them. How can you ensure that the right content is easy to find?
The first approach most websites take is to offer a "search" bar.
This can be a good approach for research reports and other types of text-heavy content, but it doesn't always work well. The trouble is that full-text search is a hard problem - Google for example spends millions on its search software and millions more tuning the results. Even if you have a great text search, your user still needs to know something about what they are looking for in order to find it. Text search depends on your visitors entering the right words into that little box.
Another approach to helping visitors is to use the way your site is organized, the "information architecture" to guide people to the right materials.
This can be quite effective, if your site has materials that fall into clear categories, like types of content, or subject, publication date, or author. But it suffers from a few drawbacks.
First, you can only expose so many layers of architecture before it overwhelms the user with too many choices. If what they seek is nested too far down, or located in too big a pile, they might miss it. Second, it depends on an agreement in terms between the label you make for an option, and the word the user has in mind. This agreement is fragile, and dependent again on visitors knowing something about your material. Finally, architecture is forever. If you're lucky, you might get to re-organize once every few years. You'd better make the right choices the first time.
Department stores have solved this problem in an interesting way. You walk into the store, head to the women's section, find the slacks, look for a color you like, then try them on. Bam! You've got what you're looking for and you are on your way to the checkout stand.
E-commerce sites have adopted this approach as well. It's familiar and comfortable for visitors.
But it's not just for e-commerce. Imagine you run a non-profit like The Mountaineers that offers courses in outdoorsmanship. Perhaps I come to visit your site. I would like to take a class, learn something new. I've never been climbing before, but it looks fun. I am an absolute beginner, never climbed a mountain in my life. Oh, and I know I've got some time off later this summer! Cool, in three clicks I've narrowed the selection of hundreds of courses offered by your organization down to just a few! I can read about each, find the one that fits me best, and head to registration. We call this "faceted search".
So how can you get such a wonderful feature for your website? You'll need to start with a content management system of some kind. This is where you'll create, store, manage and display the "products" your visitors are looking for. We think the open source Plone CMS is the best choice for large sites with lots of editors and rich content.
You'll need a robust search engine. This is where the information about your "products" is stored. A good engine will produce lists of facet values for you, give you counts of matching items, and allow for lightning-fast lookups. We work mostly with Solr and elasticsearch, two products built on the open source Lucene search engine. But Plone also has a fine index for faceted search built in if your needs are straightforward.
Your CMS should allow you to edit "metadata" or information about your content. Here is where you can determine what facets, or aspects of this information you want to use. With a powerful CMS like Plone, you can customize the metadata to suit your needs.
Or, you can work with an external service to capture metadata. Perhaps your offerings are stored in Salesforce. We can index information from Salesforce into a search engine like Solr or elasticsearch, and use your CMS to display the search interface and results.
Finally, you'll need a plugin for your CMS that supports faceted search. Plone has a great one thanks to the folks at the European Environment Agency: eea.facetednavigation. It lets you easily experiment with different facets, optimizing your search based on analytics about your traffic. This means you can shape the search according to real visitor needs, frequently and with little or no developer time required.
With a solid faceted search experience, you can ensure that your visitors will find those "hidden treasures" they seek. Contact Jazkarta to discuss whether this feature would be a good addition to your website.
14 Jul 2015 7:26pm GMT
What has changed in version 1.3.3?
The documentation has been cleaned and updated!
Plone 5 compatibility
plone.api is now compatible with Plone 5. This includes registry based mail settings.
Note: The Plone 5 test setup uses plone.app.contenttypes instead of Archetypes.
Find content objects
plone.api.content.find wraps the portal_catalog tool. It packs a bit of convenience that cleans up your code quite a bit.
The 'context' argument is used to construct the 'path' query:
The interfaces' __identifier__ is automatically used for the 'object_provides' argument.
plone.api.portal.send_email no longer raises ValueError('MailHost is not configured.') when Products.PrintingMailHost is installed and active.
Support Zope users in env.adopt_user.
plone.api.env.adopt_user(username='zope_admin') now works as expected.
get_registry_record lists a subset of registry keys on error.
plone.api.portal.get_registry_record no longer lists all registry keys. It now lists only keys that contain the passed in record name, instead of all 1500+ keys.
Revoking user roles
Fixed revoke_roles method: now if is't called with obj parameter, it doesn't set inherited roles locally.
plone.api.content.get_view no longer swallows exception. This means that get_view no longer raises InvalidParameterError when there's an error in the view's __init__.
Deleting multiple objects at once
plone.api.content.delete now accepts a list of objects.
Products.Archetypes is optional
plone.api now can be used without Products.Archetypes.
Default value for plone.api.content.get_state
plone.api.content.get_state now allows for an optional default value. This is used when no workflow is defined for the object.
state = get_state(obj=context, default=None)
if state is None:
# Do something
state = get_state(obj=context)
# Do something
A big thank you to cekk, jensens and pbauer for making this release possible!
14 Jul 2015 12:51pm GMT