Skip to content. | Skip to navigation

Personal tools
Log in
Sections
You are here: Home

Latest Plone Posts

Pyramid starter seed template powered by Yeoman (part 1)

By davide moro (noreply@blogger.com) from Planet Plone. Published on Oct 19, 2014.

Book of the month I'm reading this summer: Pylons/Pyramid (http://docs.pylonsproject.org/en/latest).


Pyramid (http://www.pylonsproject.org) is a minimal Python-based web development framework that let you "start small and finish big".

It stole a lot of (good) ideas and concepts from other mature Python web frameworks and it is build with the pluggable and extensible concepts in mind. Read: no need to fork applications.

Furthermore Pyramid is database and template engine agnostic: you are free.

From the very beginning Pyramid allows you to become productive quickly. So why not start with something of useful?

Pyramid + Yeoman

The goal of this experiment is integrate yeoman with Pyramid (or other frameworks like NodeJs/Express with AngularJS or Plone as already did), preserving the yeoman's workflow.

UPDATE 20140926: here you can see a Plone + AngularJS + Yeoman article (collective.angularstarter)

In this article I'll talk about what are the benefits you get integrating your Pyramid app with Yeoman, in future posts I'll discuss how they work under the hood with additional technical details omitted here (each used component deserves an entire blog post).

Yeoman
You might wonder why? Because of the importance of tooling. Since it is very important build an effective developer tooling ecosystem, I want to integrate the simple starter demo app with commonly used tools to help you stay productive. So this simple application prototype it is just an experiment that should help you to integrate with modern web development tools provided by the yeoman workflow stack (http://yeoman.io).

Choosing the right tools is very important for the best develop experience and I cannot work anymore without Yeoman, especially when coding with Javascript.

Grunt
Yeoman it is internally based on three important components (nodejs powered):
  • yo, scaffolding tool like pcreate, paster or zopeskel. It is widely adopted by a large and trasversal community
  • grunt, system used for build, preview and test your software. Gulp is another popular option
  • bower, used for dependency management, so that you no longer have to manually download and manage your scripts
Bower

So with the yeoman's tools you can just code, avoid annoying repetitive tasks and don't worry about:
  • javascript testing setup
  • javascript code linting
  • javascript/css minification and merging
  • image minification
  • html minification
  • switch to CDN versions of you vendor plugins in production mode
  • auto-reload browser
  • much much more
So let's see together what happened to our pyramid starter demo template created with pcreate -t starter integrated with a yeoman's generator-webapp project.

The result will be a Pyramid starter seed project integrated with modern non Python-based web development tools.

Goals

Management of third party assets

You no longer have to manually download and manage your scripts with the Bower package manager.

From http://bower.io:
"""Bower works by fetching and installing packages from all over, taking care of hunting, finding, downloading, and saving the stuff you’re looking for."""
So just type something like: bower install angular-translate --save and you'll get the rigth resource with pinning support.

Tasks automation

Automation, automation, automation.

From http://gruntjs.com:
"""Why use a task runner? In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it, a task runner can do most of that mundane work for you—and your team—with basically zero effort."""
Examples:
  • grunt serve
  • grunt test
  • grunt build
  • grunt YOUR TASK 
  • etc

Jslint

No more deploy Javascript code with bad indentation, syntax errors or bad code practices.

All syntax errors or bad practise will be found.

Image minification

The build process will detect and minify automatically all your asset images.

Uncss task

Modern (and heavy) UI frameworks like Twitter Bootstrap provide an excellent solution for prototyping your initial project, but most of the times you are using a very minimal subset of their functionalities.

https://twitter.com/davidemoroThis inspiring Addy Osmani's blog post helps you to remove unused css in your pages with a grunt task named grunt-uncss (https://github.com/addyosmani/grunt-uncss):
The original not-minified bootstrap.css weights in at 120 kB before removing unused rule.

Css concat and minification

You can split your css code into different files and then the build process will concat and minify them creating a unique app.css file. This way you write modular and better readable css files, reducing the number of browser requests.

The theme.css file is quite small but in real projects you can save more. In this case:
The configured build pipeline is concat, uncss and cssmin. 122.85 kB (original bootstrap.css) -> 4.64 kB (uncss) -> 3.45 kB (minification)

Automatic CDN-ification

It is handy using unminified versions of third party javascript libraries during development and switch to CDN versions in production mode with well known benefits for your website.

Don't worry: the cdnify task will take care about this boring issue. Automatically.

You save a boring manual and error-prone configuration.

Composable bootstrap.js version

The Pyramid starter project is based on Twitter Bootstrap.

Twitter Bootstrap
Depending on your project you can load the whole Twitter Bootstrap Javascript code at once or including individual plugins.

As you can see the Javascript component of Twitter Bootstrap is very modular: http://getbootstrap.com/javascript. So if you don't use a particular feature, just don't include it.

This way in development mode you will have all individual plugins splitted in different files, in production it will served a unique concatenated and minified Javascript file built automatically.

So if you just need alert.js and dropdown.js you can get a 2.79 kB plugins.js:

The concatenation of alert.js and dropdown.js produces a 7.06 kB, that weight in at 2.79 kB after minification instead of the 8.9 kB (gzipped) bootstrap-min.js corresponding to not gzipped 27.2 kB.

Html (template) minification

Since the ZPT/Chameleon templating language is an extension of HTML with xml syntax,

Brower are able to display unrendered ZPT/Chameleon templates
theorically it can play well with html minificators.

I know, template minification can lead to potential unexpected problems due to minification issues on template files... but this is my personal playground, so let me play please!

So... why not switch to a pre-compiled minified template of your ZPT/Chameleon files when you are in "production mode"?

Obviously during development you will use the original template files.

The interesting side of this approach is that there is no overhead at response time, since the minification task runs just one time before deploying your application. It might be an option if you want just your html minified and you cannot feasibly add to your site or project additional optimization tools at web server level.

Anyway I have tried this mad experiment and... if you don't use too aggressive minification params, it seems to work fine with good results. Try it at your own risk or just disable it. Here you can the effects on the generated index.html used in production:
Template minified (7.62 kB -> 4.16 kB)

Result: a lighter Pyramid

Same results but a lighter Pyramid app:

Let's see how it behave the standard Pyramid starter project:
Standard Pyramid starter project (production.ini)
And the Pyramid starter seed:
Pyramid starter seed (production.ini)
As you can see the seed version is ~38 Kb smaller and more performant.

Useful links

That's all?

No, you can do more, for example:
  • reduce the  number or requests (for example you can merge vendor.css and app.css)
  • create and keep updated css sprites with grunt (https://github.com/Ensighten/grunt-spritesmith)
  • manage and upload all your assets to professional services like Amazon AWS (for example you can serve up all your images, styles and scripts from a S3 bucket + CloudFront). This way Pyramid will be able to handle more requests. Pyramid let you put static media on a separate webserver during production with static_url() in conjunction with add_static_view(), without having to change your templates code
  • generate static gzipped assets with Grunt and let your webserver serve them
  • install and configure dedicated performance modules at webserver level (Apache's mod_pagespeed)
Let me know what you think about that, please. Hope soon I will manage to write the second part of this blog post explaining how I did it. In the mean time you can:

Links

    How to change versions of Plone in your Vagrant install

    By nguyen from Planet Plone. Published on Oct 16, 2014.

    downgrading from Plone 5.0a2 to 4.3.3

    Tracking down pesky buildout version pins or requirements

    By nguyen from Planet Plone. Published on Oct 16, 2014.

    Thank you to cdw9, ableeb, and SteveM on #plone IRC!

    Porting tests to plone.app.testing for Plone 5

    By Tom from Planet Plone. Published on Oct 15, 2014.

    A major version of a piece of software always means to leave behind some burdon. Plone ships with two testing framworks since Plone 4. Now it is time to get rid of one of them: PloneTestCase. With the newer plone.app.testing framework it is possible to specify layers to encapsulate testing scenarios and dependencies. I don't want to compete the excelent plone.app.testing documentation here but provide some tipps for porting your addons from PloneTestCase to plone.app.testing.

    First: Look at some examples! Most of the Plone core packages are already ported to plone.app.testing. If you have a lot of packages with one namespace and a similar setup it probably makes sense to start with a ZopeSkel or mr.bob template for your testing base class.

    Second: Use a Testing base class! Define one or two base classes for all your testing needs in one product. This makes migrations a lot easier. With the help of the PloneTestCase class of plone.app.testing.bbb half the work is done. All you need is a layer which installs your addon and does the other things (create content, etc.) you need for testing.

    Third: Doctests Porting doctests is a little bit more tricky. The way doctests are run changed a little bit with plone.app.testing. You no longer pass a testing class to the test but add a layer. This can be easily done with the layered helper function found in plone.testing. You just pass in the layer you defined for your unittests and you can access it in your doctests. Because there is no test class there is no self.<whatever-method> supported in doctests. Greping 'self' in all doctests and replacing it with layer specific code is usually the way to go.

    >>> self.setRoles(['Manager])
    

    would turn into

    >>> from plone.app.testing import TEST_USER_ID, setRoles
    >>> setRoles(layer['portal'], TEST_USER_ID, ['Manager'])
    

    And you don't need to use any Zope based variant of doctest. Just use plain python doctest and suite.

    Forth: Functionaltests Basically all tests inherited from plone.app.testing.bbb.PloneTestCase are functional tests and support the publish method to publish an object in a testing environment. Sometimes I found kind of unpredictable behaviour using this method. Usually it can be avoided using zope.testbrowser (see next point). You need to use it if you are testing alternate publishing methods (like WebDAV or VirtualHostMonster) which rarly be the case.

    One thing I could track down is a cookie reset if diazo is turned on. This is because of a subrequest which is issued during traversal. You can disable diazo during testing:

    >>> response = self.publish(docpath, basic_auth, env={'diazo.off': "1"})
    

    To debug functional testing you need the following patch in your (failing) test.

    def raising(self, info):
        import traceback
        traceback.print_tb(info[2])
        print info[1]
    
    from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
    SiteErrorLog.raising = raising
    

    Fifth: Testbrowser Using zope.testbrowser is supported with plone.app.testing too. There are two main differences: a browser instance is initiated with the application: like this:

    >>> browser = Browser(self.layer['app'])   # in functional test cases
    

    or

    >>> browser = Browser(layer['app'])    # in doctests
    

    You need to commit changes before! you initiate the browser.

    >>> from transaction import commit
    >>> commit()
    

    Sixth: plone.protect

    If you are using a view, which uses CSRF protection via plone.protect you may want to disable this feature in tests temporarily. You can call your view by injecting a CSRF token into the request like this:

    >>> from plone.protect import createToken
    >>> request.form['_authenticator'] = createToken()
    

    The original idea I found in this blog.

    Seventh: Functional doctests In functional doctest sometimes a http function is found. This is the doctest analog of the functional test publish method. Currently it fails with plone.app.testing. I am investigating this and keep you posted, if I found something ...

    And now happy porting to plone.app.testing of your addons. BTW the porting of some products is left for core Plone. If you want to give it a try ... go ahead. :)

    See you on the Plone Conference in Bristol, Tom

    1.9.0 release brings new features and documentation to collective.recipe.plonesite

    By Clayton Parker from Planet Plone. Published on Oct 15, 2014.

    plone.pngThe 1.9.0 release of collective.recipe.plonesite is now available on PyPi. This release brings several new features and some improvements to the documentation.

    The biggest new feature is the integration with collective.upgrade. This allows for the plonesite recipe to automatically upgrade the Plone portal and run any upgrade steps for installed packages in the site. Credit goes to Ross Patterson for adding this feature.

    A couple more features were also added to the latest release. Fabio Rauber contributed a feature that provides the ability to have the plonesite recipe automatically add mount points. See the documentation for an example of how this works. The last new feature is the ability to run the plonesite part using sudo. This allows the plonesite part to be run when the Zope instance and ZEO server are run under different UIDs. Toni Mueller provided this new option.

    Lastly, the documentation was cleaned up in the source and for the end user. The documentation on PyPi is now grouped by option type so that it is easier to find what you are looking for. The docs were also cleaned up in source control so that it is easier to contribute.

    Results of the Plone Developer Survey

    From Planet Plone. Published on Oct 14, 2014.

    Announcing the Anniversary Sprint 2015

    By Rob Gietema from Planet Plone. Published on Oct 14, 2014.

    Four Digits will be 10 years old on the 23rd of June 2015, so what better way to celebrate then a Plone Sprint! So after the succes of the Living Statues Sprint 2010, 2011, the Plone Conf 2012 and Arnhem Sprint 2013 Four Digits will be hosting another sprint in 2015! The sprint will be from Monday to Friday and will finish with a big party on Friday evening.

    Announcing the Anniversary Sprint 2015 in Arnhem, June 22-26

    From Planet Plone. Published on Oct 14, 2014.

    Four Digits will be 10 years old on the 23rd of June 2015, so what better way to celebrate then a Plone Sprint! So after the succes of the Living Statues Sprint 2010, 2011, the Plone Conf 2012 and Arnhem Sprint 2013 Four Digits will be hosting another sprint in 2015! The sprint will be from Monday to Friday and will finish with a big party on Friday evening.

    Learning Plone as a SysAdmin

    By Rob McBroom from Planet Plone. Published on Oct 14, 2014.

    Plone Code BadgeI recently started learning to develop for the Python-based CMS, Plone. This is my perspective on learning to be a Plone developer with years of experience as a SysAdmin and Python developer.

    More Powerful Than I Thought

    Getting to know Plone, I can really see its appeal for someone who needs a CMS. It can handle anything you want it to. I've been really impressed with the granularity of:

    • Access control
    • Where portlets can be located
    • What types of content can exist in a container
    • How you can override styles and templates at any layer

    It's impressive to me that you can even create your own content types. Plone is packed with features for large organizations and let's you customize it to your requirements.

    There's no Free Lunch

    The flip side of the ability to do whatever you want is that it has a steep learning curve. Figuring out where parts of Plone start and end can be difficult:

    • Where does buildout end and Plone begin?
    • What is a part of GenericSetup vs. Plone?
    • When do you need to use Templer?

    This is further complicated by the fact that almost everything has an "old way" and a "new way".

    Make sure you understand vanilla Plone before you dive into anything custom on an existing site. There are also many versions of Plone in the wild that are still supported from 2 to 4.3, and 5 is just around the corner. Make sure to learn on the version your organization is already using or plans to use.

    How I would learn Plone

    If you need to learn how to develop for Plone, I recommend to start you:

    Learn Buildout First

    With Plone you don't install packages like you traditionally would with `pip install`. You list all the packages in a file that Buildout uses to install everything at once and track their location. You should also understand the difference between a Unified Installer buildout or a manual buildout.

    ZODB and Plone

    Get to know the commands and sequence required to start the ZODB and Plone and shut them down. Then you can get familiar with the command scripts that helps take care of this for you.

    Learn How to Get Into the Debugger

    Next I would get familiar with the Plone debugger which will let you inspect and interact with live objects.
    http://docs.plone.org/develop/plone/getstarted/debug_mode.html


    Explore the Admin Interface

    Once you are comfortable with getting Plone installed, running, and debugged, you can start getting familiar with the user's admin interface inside Plone. Take a look around and get familiar with creating content like blog posts as well as changing system settings.

    Understand the Zope Management Interface (ZMI)

    Once you've played with settings and content in Plone, you can hop over into the ZMI and see how the changes you made in the Plone interface modifies and creates data in Zope.
    http://docs.zope.org/zope2/zope2book/UsingZope.html

    At this point you should be familiar enough with Plone to start looking at how to build the site you want. Then things get real interesting depending on where you go with this powerful CMS.

    Did you enjoy this post? I'll continue to blog on my perspective of Plone and how to modify and manage it.

    How to hide the title and/or description on a Plone 4 page

    By nguyen from Planet Plone. Published on Oct 10, 2014.

    Based on information at http://plone.org/documentation/kb/how-to-write-templates-for-plone-4

    Create the view template

    If you want to hide the title and description on a Plone page, you can create a new template that does that.

    • Go to the ZMI -> portal_skins
    • Use the Find tab to look for an object with the ID "document_view". Click on it, then click on the Customize button.  
    • In the breadcrumbs, click on the "custom" link to take you up one level.
    • Check the box next to the document_view object, then click the Rename button at the bottom of the page.  Give it a new name (e.g. document_no_title_or_description_view) then click the OK button.
    • Click on the document_no_title_or_description_view object again to edit it, and replace its contents with the code below.

     

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
          xmlns:tal="http://xml.zope.org/namespaces/tal"
          xmlns:metal="http://xml.zope.org/namespaces/metal"
          xmlns:i18n="http://xml.zope.org/namespaces/i18n"
          lang="en"
          metal:use-macro="context/main_template/macros/master"
          i18n:domain="plone">
    <body>
    
    <metal:content-title fill-slot="content-title">
        <metal:content-title define-macro="content-title">
         </metal:content-title>
    </metal:content-title>
    
    <metal:content-description fill-slot="content-description">
        <metal:content-description define-macro="content-description">
         </metal:content-description>
    </metal:content-description>
    
    <metal:content-core fill-slot="content-core">
        <metal:content-core define-macro="content-core">
            <metal:field use-macro="python:context.widget('text', mode='view')">
                Body text
            </metal:field>
        </metal:content-core>
    </metal:content-core>
    
    </body>
    </html>

    The difference between the above and the default view template is that both the content-title and the content-description macros no longer do anything.

    Next, you have to enable this new customized view template for pages ("Documents").

    Add the new view template to the page/Document type

    • Go to ZMI -> portal_types -> Document
    • Add one more line to the "Available View Methods" field, containing document_no_title_or_description_view, and press the Save Changes button.

     

    Using the new view template

    • Go to the page on which you wanted to hide the title and description.  
    • The Display drop down menu should now include a new choice "document_no_title_or_description_view".  Select it, and the page should now no longer show its title nor its description.

     

    A different approach to mobile theming.

    By admin from Planet Plone. Published on Oct 10, 2014.

    Mobile theming with zettwerk.mobiletheming and medialog.simpleslier

    How to export and import Plone users

    By nguyen from Planet Plone. Published on Oct 09, 2014.

    using bin/instance debug

    Plone Foundation Welcomes New Members

    From Planet Plone. Published on Oct 09, 2014.

    Johannes Raggam, Leonardo J. Caballero G. and Maarten Kling are the Foundation's newest members.

    Zidanca Sprint Report: JS/LESS Integration

    From Planet Plone. Published on Oct 09, 2014.

    After recovering from a hard week of work, thinking and writing/re-writing code, we accomplished an important goal at the Zidanca Sprint—a replacement for Resource Registry adapted to modern front-end development and friendly mockup widgets.

    September Newsletter

    From Planet Plone. Published on Oct 09, 2014.

    Coming to you via email hopefully soon! In the meantime, make arrangements to attend Plone Conference 2014 and/or one of the other upcoming events and check out what we did in September.