<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0">

    <channel>

        <title>Blog</title>
        <link>http://www.coresoftwaregroup.com/blog</link>
        <description>Let's try this again.  A whole bunch of years ago, I tried doing some blogging, and it didn't go so hot.  Now, Core Software Group is doing a lot of exciting work with Plone, Django, Pyramid, and other Python based tools, and we are documenting various tips and tricks that we run into as we build custom solutions for our customers.</description>

        <generator>basesyndication</generator>
        <!-- TODO
        <lastBuildDate>Mon, 30 Sep 2002 11:00:00 GMT</lastBuildDate>
        <copyright>Copyright 1997-2002 Dave Winer</copyright>
        <docs>http://backend.userland.com/rss</docs>
        <category domain="Syndic8">1765</category>
        <managingEditor>dave@userland.com</managingEditor>
        <webMaster>dave@userland.com</webMaster>
        -->

        <!-- TODO: Should there be an individual image associatable with each
        Weblog object?  I think so... -->
        <image>
            <title>Blog</title>
            <url>http://www.coresoftwaregroup.com/logo.png</url>
            <link>http://www.coresoftwaregroup.com/blog</link>
        </image>

        
            <item>
                <title>Automated Amazon EBS Volume Snapshots with Boto</title>
                <guid>http://www.coresoftwaregroup.com/blog/automated-amazon-ebs-volume-snapshots-with-boto</guid>
                <link>http://www.coresoftwaregroup.com/blog/automated-amazon-ebs-volume-snapshots-with-boto</link>
                <description>&lt;p&gt;Recently, we were asked by a client to setup regular EBS volume snapshots for their production EC2 instances. After a little research, &lt;a class="external-link" href="authors/michaelc"&gt;Mike&lt;/a&gt; came across a fairly simple tool called aws-snapshot-tool: &lt;a class="external-link" href="https://github.com/evannuil/aws-snapshot-tool" target="_blank" title="aws-snapshot-tool"&gt;https://github.com/evannuil/aws-snapshot-tool&lt;/a&gt;.  This tool runs as a cron job and automatically creates daily, weekly, and monthly snapshots, and automatically rotates out the oldest snapshots for each time period.&lt;/p&gt;
&lt;p&gt;The tool, written in Python, takes advantage of an excellent module called boto (&lt;a class="external-link" href="https://github.com/boto/boto" target="_blank" title="boto at github"&gt;https://github.com/boto/boto&lt;/a&gt;, &lt;a class="external-link" href="http://docs.pythonboto.org/en/latest/" target="_blank" title="boto docs"&gt;http://docs.pythonboto.org/en/latest/&lt;/a&gt;).  Boto is a Python package that provides an interface to Amazon Web Services (AWS) allowing you to easily maintain and manage various aspects of your AWS environment with very little coding.&lt;/p&gt;
&lt;h3&gt;Install Notes&lt;/h3&gt;
&lt;p&gt;The &lt;a class="external-link" href="https://github.com/evannuil/aws-snapshot-tool" target="_blank" title="aws-snapshot-tool"&gt;aws-snapshot-tool github page&lt;/a&gt; has simple instructions to get started, but here are a couple points of interest:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;install and setup boto&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="color: #757575;"&gt;&lt;span style="line-height: 18.203125px;"&gt;pip install boto&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #757575;"&gt;&lt;span style="line-height: 18.203125px;"&gt;Setup a .boto config file to store your AWS access key (See: &lt;a class="external-link" href="https://code.google.com/p/boto/wiki/BotoConfig" target="_blank" title="Setup boto config file"&gt;https://code.google.com/p/boto/wiki/BotoConfig&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Setup your Identity and Access Management (IAM) access&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you access AWS through their API, you are utilizing the web service functions to which your account has been given access.  The aws-snapshot-tool includes a sample IAM configuration, that shows which actions need to be setup:&lt;/p&gt;
&lt;pre&gt;"Action": [
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:DeleteSnapshot",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSnapshots",
        "ec2:DescribeTags",
        "ec2:DescribeVolumeAttribute",
        "ec2:DescribeVolumeStatus",
        "ec2:DescribeVolumes"
      ],
&lt;/pre&gt;
&lt;h3&gt;Configuration (including rotation)&lt;/h3&gt;
&lt;p&gt;&lt;span style="line-height: 1.5em;"&gt;Configuration is very easy.  The script uses a config.py file that looks like:&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;config = {
    'ec2_region_name': 'us-east-1',
    'ec2_region_endpoint': 'ec2.us-east-1.amazonaws.com',
    'tag_name': 'tag:MakeSnapshot',
    'tag_value':    'True',
    'keep_day': 5,
    'keep_week': 5,
    'keep_month': 11,
    'log_file': '/tmp/makesnapshots.log',
}
&lt;/pre&gt;
&lt;p&gt;There are three important pieces being defined here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The region where your EBS volumes are defined&lt;/li&gt;
&lt;li&gt;The tag name put on each volume in order to enable snapshots&lt;/li&gt;
&lt;li&gt;&lt;span style="line-height: 1.5em;"&gt;The definition for how long to keep snapshots: 5 days, 5 weeks, and 13 months&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Tag Your Volumes&lt;/h3&gt;
&lt;p&gt;Well, it couldn't be any easier.  Simply add a Tag of 'MakeSnapshot', with a value of 'True', (as defined in the above config file) to any volume you want picked up by this script.  The script loops through all volumes in the entire defined ec2_region_name field, looks for that tag, and handles the snapshot and rotation of snapshots automatically.&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Volume Snapshot Tag" class="image-inline" src="../MakeSnaphot.png/image_preview" /&gt;&lt;/p&gt;
&lt;h3&gt;Cron Setup &amp;amp; Output&lt;/h3&gt;
&lt;p&gt;We chose to run our script on another EC2 instance, but this could run anywhere.   We setup the following cron jobs to run:&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;$ crontab -l&lt;/p&gt;&lt;p&gt;# mon-fri 30 3 * * 1-5 /home/zope/aws-snapshot-tool/makesnapshots.py day&lt;/p&gt;&lt;p&gt;# every sat 30 3 * * 6 /home/zope/aws-snapshot-tool/makesnapshots.py week&lt;/p&gt;&lt;p&gt;# first sun 30 3 1-7 * 0 /home/zope/aws-snapshot-tool/makesnapshots.py month&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;Each snapshot is created with a description that begins like 'day_snapshot...', 'week_snapshot...', or 'month_snapshot...', like in the following scree&lt;span style="line-height: 1.5em;"&gt;nshots:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height: 1.5em;"&gt; &lt;/span&gt;&lt;img alt="AWS Snapshots - Day" class="image-inline" src="../day.png/image_preview" style="line-height: 1.5em;" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height: 1.5em;"&gt; &lt;/span&gt;&lt;img alt="AWS Snapshots - Week" class="image-inline" src="../week.png/image_preview" style="line-height: 1.5em;" /&gt;&lt;/p&gt;
&lt;h3&gt;Gotchas?&lt;/h3&gt;
&lt;p&gt;At the moment, I can only think of 3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="line-height: 1.5em;"&gt;The config.py script points to a region.  If we decide to start using other regions for our servers, we will need to accomodate that.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="line-height: 1.5em;"&gt;The cost of storage.  Is cheap.  However, once this has run for a year, we will have 23 snapshots per volume saved in our account.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="line-height: 1.5em;"&gt;These are real time snapshots.  It is each server administrator's responsibility to insure the volume being backed up is in the proper state.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>boto</category>
                
                
                    <category>python</category>
                
                
                    <category>Amazon</category>
                
                
                    <category>EC2</category>
                
                
                    <category>EBS</category>
                

                <pubDate>Thu, 02 May 2013 09:40:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>A Landscape of Python Web Development</title>
                <guid>http://www.coresoftwaregroup.com/blog/a-landscape-of-python-web-development</guid>
                <link>http://www.coresoftwaregroup.com/blog/a-landscape-of-python-web-development</link>
                <description>&lt;p&gt;In preparation for our kickoff meeting of the new &lt;a class="external-link" href="http://www.meetup.com/Python-Web-Development" target="_blank" title="Python Web Development Meetup"&gt;Python Web Development meetup&lt;/a&gt;, I started putting together what I called "A Landscape of Python Web Development".  It started with a few of the obvious tools and products that we use at Core Software Group, like Zope/Plone, Django, and boto and suds.&lt;/p&gt;
&lt;p&gt;From there, it started becoming obvious that I needed to break down the ever-growing list into mutliple categories.&lt;/p&gt;
&lt;p&gt;My list of products played out like this:&lt;/p&gt;
&lt;h3&gt;The Categories&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Frameworks&lt;/li&gt;
&lt;li&gt;CMS&lt;/li&gt;
&lt;li&gt;Deployment/Hosting&lt;/li&gt;
&lt;li&gt;Page Templates/Forms&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Tools/Other&lt;/li&gt;
&lt;li&gt;Static Site Generators&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Frameworks&lt;/h3&gt;
&lt;p&gt;This list of frameworks includes some old timers, and some newer, 'lightweight' frameworks.  The last one listed, itty, was mentioned in one of &lt;a class="external-link" href="http://pyvideo.org/speaker/138/raymond-hettinger" target="_blank" title="pycon videos"&gt;Raymond Hettinger's pycon videos&lt;/a&gt;, and seemed an interesting, super small framework to check out.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zope&lt;/li&gt;
&lt;li&gt;Pyramid&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;Flask&lt;/li&gt;
&lt;li&gt;Bottle&lt;/li&gt;
&lt;li&gt;CherryPy&lt;/li&gt;
&lt;li&gt;web2py&lt;/li&gt;
&lt;li&gt;itty&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CMS&lt;/h3&gt;
&lt;p&gt;I'm sure I missed some, but these seemed to be the key players that we have come across, and the interwebs seemed to point to.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Plone&lt;/li&gt;
&lt;li&gt;Kotti&lt;/li&gt;
&lt;li&gt;Django CMS&lt;/li&gt;
&lt;li&gt;Mezzanine&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Deployment/Hosting&lt;/h3&gt;
&lt;p&gt;The first three are cloud platforms, and the last three are samples of python tools related to deployment.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="line-height: 1.5em;"&gt;Heroku&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Google App Engine&lt;/li&gt;
&lt;li&gt;Elastic Beanstalk&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;boto for EC2&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;fabric&lt;/li&gt;
&lt;li&gt;buildout&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Page Templates/Forms&lt;/h3&gt;
&lt;p&gt;This list was a late addition, but is now pretty obvious.  You can't do web development without page templates and forms.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zope Page Templates (ZPT)&lt;/li&gt;
&lt;li&gt;Django Templates&lt;/li&gt;
&lt;li&gt;jinja2&lt;/li&gt;
&lt;li&gt;chameleon&lt;/li&gt;
&lt;li&gt;deform&lt;/li&gt;
&lt;li&gt;z3c.form&lt;/li&gt;
&lt;li&gt;WTForms&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Databases&lt;/h3&gt;
&lt;p&gt;While the following are not directly related to web development, they certainly come into play when building applications that require a backend database.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sqlalchemy&lt;/li&gt;
&lt;li&gt;psycopg2&lt;/li&gt;
&lt;li&gt;pymongo&lt;/li&gt;
&lt;li&gt;MySQL-python&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;Ok, I have to admit that I'm incredibly weak when it comes to writing tests.  But I needed a list of some of the tools out there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;unittest&lt;/li&gt;
&lt;li&gt;doctest&lt;/li&gt;
&lt;li&gt;coverage&lt;/li&gt;
&lt;li&gt;selenium&lt;/li&gt;
&lt;li&gt;funkload&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Tools/Other&lt;/h3&gt;
&lt;p&gt;Wow. This list could go on and on and on.  I grabbed a few tools that we use, plus a few others I came across over the last month.  Hopefully, we can provide some presentations about some of these in future meetups.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;suds&lt;/li&gt;
&lt;li&gt;requests&lt;/li&gt;
&lt;li&gt;twisted&lt;/li&gt;
&lt;li&gt;mincss&lt;/li&gt;
&lt;li&gt;xml.dom, lxml, etree&lt;/li&gt;
&lt;li&gt;virtualenv&lt;/li&gt;
&lt;li&gt;simplejson&lt;/li&gt;
&lt;li&gt;PIL/Pillow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Static Site Generators&lt;/h3&gt;
&lt;p&gt;This list of static site generators almost has nothing to do with the above items, but I couldn't resist putting the list together.  I'm fascinated by the concept of someone willing to write blog entries as text files, which in turn get deployed as static HTML to some server on the web.  What I really want to know is: "How many folks are actually using these kind of tools for production sites?"&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Klein - &lt;a href="https://github.com/twisted/klein"&gt;https://github.com/twisted/klein&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pelican - &lt;a href="http://blog.notmyidea.org/pelican-a-simple-static-blog-generator-in-python.html"&gt;http://blog.notmyidea.org/pelican-a-simple-static-blog-generator-in-python.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hyde - &lt;a href="http://ringce.com/hyde"&gt;http://ringce.com/hyde&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cactus - &lt;a href="https://github.com/koenbok/Cactus"&gt;https://github.com/koenbok/Cactus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Nikola - &lt;a href="https://github.com/ralsina/nikola"&gt;https://github.com/ralsina/nikola&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Hovercraft/impress.js&lt;/h3&gt;
&lt;p&gt;Finally, while building my presentation, I came across a Python package called &lt;a class="external-link" href="https://pypi.python.org/pypi/hovercraft" target="_blank" title="Hovercraft python package for creating impress.js presentations"&gt;Hovercraft!&lt;/a&gt;, written by Lennart Regebro, for generating &lt;a class="external-link" href="http://bartaz.github.io/impress.js/#/bored" target="_blank" title="impress.js"&gt;impress.js&lt;/a&gt; presentations from a reStructuredText file.  Awesome.  And so easy to use.  You can download my &lt;a class="internal-link" href="../downloads/python-meetup-kickoff-slides/kickoff.rst"&gt;kickoff.rst file&lt;/a&gt; and the &lt;a class="internal-link" href="../downloads/python-meetup-kickoff-slides/KickoffMeetingPresentation.zip"&gt;generated output&lt;/a&gt; for my presentation.&lt;/p&gt;
&lt;p&gt;Our discussion at the &lt;a class="external-link" href="http://www.meetup.com/Python-Web-Development/" target="_blank" title="Python Web Development Meetup"&gt;Python Web Development meetup&lt;/a&gt; was interesting, and it turns out that most of categories really start to look like the definition of a "development stack" which I suppose could be used to define a set of tools that someone might use to get started doing Python based web development.&lt;/p&gt;
&lt;p&gt;I hope you find some value in this list.  If I missed some completely obvious products, please add a comment and let me know.&lt;/p&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>python</category>
                
                
                    <category>community</category>
                
                
                    <category>meetup</category>
                
                
                    <category>frameworks</category>
                
                
                    <category>tools</category>
                

                <pubDate>Wed, 10 Apr 2013 22:55:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>How to enable User Folders in Plone</title>
                <guid>http://www.coresoftwaregroup.com/blog/how-to-enable-user-folders-in-plone</guid>
                <link>http://www.coresoftwaregroup.com/blog/how-to-enable-user-folders-in-plone</link>
                <description>
&lt;p&gt;I needed to enable the User Folders feature of Plone from within my product. My first thought was to use a Generic Setup profile, but the solution was setuphandlers.py.&lt;/p&gt;
&lt;p&gt;I inspected the Enable User Folders button on the Security settings page of Site Setup, and saw the attribute was named enable_user_folders. I tried to find a generic setup profile I could edit.&lt;/p&gt;
&lt;p&gt;The closest I got was adding enable_user_folders to properties.xml. This turned the attribute on in the ZMI, but not in Site Setup and User Folders were not enabled.&lt;/p&gt;
&lt;p&gt;Then I found a reference to&lt;/p&gt;
&lt;pre&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_user_folders&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;in a setuphandlers.py file from the &lt;a href="https://github.com/Rhaptos/Products.RhaptosSite/blob/plone4-migration/Products/RhaptosSite/setuphandlers.py"&gt;Rhaptos git repo.&lt;/a&gt;&lt;/p&gt;
So, I added these lines to setupVarious in my setuphandlers.py.
&lt;pre&gt;from plone.app.controlpanel.security import ISecuritySchema
site = context.getSite()
security = ISecuritySchema(site)
security.enable_user_folders = True&lt;/pre&gt;
&lt;p&gt;Now, when I install my product, User Folders are enabled automatically.&lt;/p&gt;
&lt;p&gt;Note that you need to make sure setupVarious is turned on in configure.zcml.&lt;/p&gt;
&lt;pre&gt;&amp;lt;genericsetup:importStep
    name="your.package"
    title="your.package special import handlers"
    description=""
    handler="your.package.setuphandlers.setupVarious"
    /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Hope this helps someone.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
                <author>Mike Cullerton</author>

                
                    <category>plone 4</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>generic setup</category>
                
                
                    <category>User Folders</category>
                

                <pubDate>Tue, 09 Apr 2013 15:22:57 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>How to open SSH links in iTerm 2</title>
                <guid>http://www.coresoftwaregroup.com/blog/how-to-open-ssh-links-in-iterm-2</guid>
                <link>http://www.coresoftwaregroup.com/blog/how-to-open-ssh-links-in-iterm-2</link>
                <description>
&lt;p&gt;I know some of you have this problem. I've seen a few references to it on the net, but no solutions. iTerm 2 won't open ssh links.&lt;/p&gt;
&lt;p&gt;I have a pyramid application that uses boto to query ec2 instances and then posts information about the instances--including an ssh link, to a web page on my laptop.&lt;/p&gt;
&lt;p&gt;The ssh links open fine in iTerm. I couldn't get them to open in iTerm 2 though. Instead, they just opened new tabs.&lt;/p&gt;
&lt;p&gt;
I really like using iTerm 2, so to 'solve' the problem, I added the actual ssh shell command for each of the instances as text on the page.&lt;/p&gt;
&lt;p&gt;
To open an ssh connection to an instance, I simply copy the ssh command, click the link, paste the ssh command into the new terminal tab, and hit return.&lt;/p&gt;
&lt;p&gt;
Hey, it works.&lt;/p&gt;
&lt;p&gt;
Every once in a while, when it really bothers me, I try to figure out a real solution.&lt;/p&gt;
&lt;p&gt;
Today was one of those days.&lt;/p&gt;
&lt;p&gt;The solution turned out to be pretty simple.&lt;/p&gt;
&lt;p&gt;In the iTerm 2 Preferences, under the Profiles tab, General section, change the Command to Login shell.&lt;/p&gt;
&lt;p&gt;Now, when I click on one of the links, it opens correctly in iTerm 2.&lt;/p&gt;
&lt;p&gt;
I hope it works for you too.&lt;/p&gt;
&lt;p&gt;*Note that you must first have iTerm 2 set up to accept ssh connections. Preferences-&amp;gt;Profiles-&amp;gt;General-&amp;gt;URL Schemes&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
                <author>Mike Cullerton</author>

                
                    <category>pyramid</category>
                
                
                    <category>boto</category>
                
                
                    <category>python</category>
                
                
                    <category>ssh</category>
                
                
                    <category>iTerm 2</category>
                

                <pubDate>Mon, 08 Apr 2013 16:45:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Plone Hello World Tutorial</title>
                <guid>http://www.coresoftwaregroup.com/blog/plone-hello-world-tutorial</guid>
                <link>http://www.coresoftwaregroup.com/blog/plone-hello-world-tutorial</link>
                <description>&lt;p&gt;About a month ago, there was a bit of a ruckus on twitter about the state of Plone and documentation and what not.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;There was a specific request for a Hello World type tutorial introducing Plone development. After talking with Mikko and others on IRC, I put some ideas together and released a first attempt a few days later.&lt;/p&gt;
&lt;p&gt;Over the last few weeks, I've put time into adding more sections, reorganizing the layout, and general cleanup. Tonight, I pushed those changes to the developer manual at &lt;a class="external-link" href="http://collective-docs.readthedocs.org/en/latest/getstarted/helloworld/index.html"&gt;http://collective-docs.readthedocs.org/en/latest/getstarted/helloworld/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;At this point it's starting to take shape. There are holes in it, and things I'd like to clean up, but it's a good start.&lt;/p&gt;
&lt;p&gt;I'd like to get some feedback. What do folks think? What is missing? Are there any errors?  Really, anything helpful is appreciated.&lt;/p&gt;
&lt;p&gt;You can comment here, or reach me @cullerton on twitter.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Mike&lt;/p&gt;</description>
                <author>Mike Cullerton</author>

                
                    <category>documentation</category>
                
                
                    <category>plone 4</category>
                
                
                    <category>community</category>
                
                
                    <category>browser view</category>
                
                
                    <category>tutorial</category>
                
                
                    <category>hello world</category>
                

                <pubDate>Fri, 14 Sep 2012 01:25:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Plone Demonstrations on World Plone Day</title>
                <guid>http://www.coresoftwaregroup.com/blog/plone-demonstrations-on-world-plone-day</guid>
                <link>http://www.coresoftwaregroup.com/blog/plone-demonstrations-on-world-plone-day</link>
                <description>&lt;div id="parent-fieldname-text"&gt;
&lt;p&gt;&lt;img alt="Colorado World Plone Day Logo" class="image-right" src="../fort-collins-world-plone-day-2012/wpd.png/image_thumb" style="cursor: pointer;" /&gt;Core Software Group will be presenting demonstrations of Plone, an open source, python-based CMS, showing the &lt;a href="http://plone.org/products/plone/features/"&gt;latest features from the 4.1 release&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Demonstrations will show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how content managers use the various tools in Plone&lt;/li&gt;
&lt;li&gt;how administrators manage a Plone site&lt;/li&gt;
&lt;li&gt;how developers can extend the CMS through building custom themes or custom products&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For those interested, we can also:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;show a &lt;a href="../what-can-we-do-for-you"&gt;variety of sites&lt;/a&gt; that we have built showing different solutions customers have requested&lt;/li&gt;
&lt;li&gt;show how to quickly install and configure a Plone site&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The presentations will last from approximately 12:00pm - 2:00pm.&lt;/p&gt;
&lt;p&gt;For more information and to RSVP, &lt;a class="internal-link" href="../fort-collins-world-plone-day-2012"&gt;visit the event page&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>plone 4</category>
                
                
                    <category>presentation</category>
                
                
                    <category>community</category>
                
                
                    <category>worldploneday</category>
                

                <pubDate>Wed, 18 Apr 2012 10:55:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Fix for 404 Not Found Error for @@manage-portlets</title>
                <guid>http://www.coresoftwaregroup.com/blog/fix-for-404-not-found-error-for-manage-portlets</guid>
                <link>http://www.coresoftwaregroup.com/blog/fix-for-404-not-found-error-for-manage-portlets</link>
                <description>&lt;p&gt;This one took a while to track down, so I thought I would write down our solution.  It turned out to be easy.  We simply added an interface to our custom content type's class as follows:&lt;/p&gt;
&lt;p&gt;First import the necesary modules:&lt;/p&gt;
&lt;pre&gt;from zope.interface import implements
from plone.portlets.interfaces import ILocalPortletAssignable&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Then we added an implements line to our class:&lt;/p&gt;
&lt;pre&gt;class SiteFolderCT(BaseFolder):
    """An Archetype for an SiteFolder application"""
    implements(ILocalPortletAssignable)
    &amp;lt;the rest of the class code...&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I hope this helps out others.&lt;/p&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>upgrade</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>migration</category>
                
                
                    <category>portlets</category>
                

                <pubDate>Thu, 01 Sep 2011 12:35:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Adding a Zope 3 permission to Plone</title>
                <guid>http://www.coresoftwaregroup.com/blog/adding-a-zope-3-permission-to-plone</guid>
                <link>http://www.coresoftwaregroup.com/blog/adding-a-zope-3-permission-to-plone</link>
                <description>
&lt;h2&gt;Quick Overview&lt;/h2&gt;
&lt;p&gt;We recently migrated a Plone 2.1 site to Plone 3.3. While moving a skins file to a browser view, we needed a new  permission to protect the browser view. Browser views need a named Zope 3 style permission, so the old Zope 2 style permission wouldn't work. It ended up taking 3 steps; declare the permission in zcml, assign the permission to a role in rolemap.xml, and use the permission to protect your view.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Step-by-step&lt;/h2&gt;
&lt;h3&gt;Step 1: Declare the permission in ZCML&lt;/h3&gt;
&lt;p&gt;Most people declare the permissions in permissions.zcml and include that file in configure.zcml. But you can declare the permission in configure.zcml and just include permissions.zcml. Note that id is the zope 3 style identifier, and title is the zope 2 style identifier. The title shows up on the security tab in the ZMI.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src/your.product/your/product/browser/permissions.zcml:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;    &amp;lt;permission 
       id="myproduct.myNewPermission"
       title="MyProduct: My New Permission"
       /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step 2: Assign the permission to a role&lt;/h3&gt;
&lt;p&gt;Assign the permission to a role in rolemap.xml. Here, I assign my new permission to the manager role.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src/your.product/your/product/profiles/default/rolemap.xml:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;    &amp;lt;permission name="MyProduct: My New Permission"&amp;gt;
       &amp;lt;role name="Manager" /&amp;gt;
    &amp;lt;/permission&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step 3: Protect your view with the new permission&lt;/h3&gt;
&lt;p&gt;In configure.zcml protect your view with the new permission. Here, I'm protecting the class MyClass in the file common.py.  We chose to put the permissions from Step 1 into permissions.zcml, so we include it here. Note that the permission must be the same as the id in Step 1.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src/your.product/your/product/browser/configure.zcml:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;include file="permissions.zcml" /&amp;gt;
&amp;lt;browser:page
    for="Products.CMFPlone.interfaces.IPloneSiteRoot"
    name="myName"
    class=".common.MyClass"
    permission="myproduct.myNewPermission"
    /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As usual, the community developer manual at http://plonemanual.twinapex.fi/ was very helpful.&lt;/p&gt;
</description>
                <author>Mike Cullerton</author>

                
                    <category>zope 3 permission</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>migration</category>
                
                
                    <category>zcml</category>
                

                <pubDate>Mon, 13 Sep 2010 16:15:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Injecting Plone variables into javascript</title>
                <guid>http://www.coresoftwaregroup.com/blog/injecting-plone-variables-into-javascript</guid>
                <link>http://www.coresoftwaregroup.com/blog/injecting-plone-variables-into-javascript</link>
                <description>
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step 1: Create a class to output the javascript&lt;/h3&gt;
&lt;p&gt;I created a file in src/my.product/my/product/browser called 
CommonUtils.py and added a class GlobalJS with a __call__ method that 
returns a string containing the javascript. __call__ sets the 
content-type, creates the string containing the variable, and returns 
the string.&lt;/p&gt;
&lt;pre&gt;class GlobalJS(BrowserView):
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; def __call__(self,REQUEST,RESPONSE):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RESPONSE.setHeader('Content-Type', 'application/javascript')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; js_string = "var portal_url = '%s';" % (self.context.portal_url())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return js_string&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step 2: Create a browser view pointing to the class&lt;/h3&gt;
&lt;p&gt;In src/my.product/my/product/browser/configure.zcml, I added a 
browser view pointing to GlobalJS, gave it a name, and added a 
permission. Note that the name of the file containing GlobalJS is 
CommonUtils.py&lt;/p&gt;
&lt;pre&gt;&amp;lt;browser:view 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for="*"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="global_js.js" 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class=".CommonUtils.GlobalJS"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; permission="zope2.View"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step 3: Register the view in javascript registry&lt;/h3&gt;
&lt;p&gt;Here, I register the browser view in 
src/my.product/my/product/profiles/default/jsregistry.xml. I needed 
access to portal_url before jquery was loaded, so I added the 
insert-before property. Note that the id is the same as the name 
registered in the browser view.&lt;/p&gt;
&lt;pre&gt;&amp;lt;javascript 
&amp;nbsp;&amp;nbsp;&amp;nbsp; id="global_js.js"
&amp;nbsp;&amp;nbsp;&amp;nbsp; cacheable="True" compression="safe" cookable="True"
&amp;nbsp;&amp;nbsp;&amp;nbsp; enabled="True" expression=""&amp;nbsp; inline="True" insert-before="jquery.js"/&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, global_js.js is loaded on every page and I have access to 
portal_url from within javascript.&lt;/p&gt;
&lt;p&gt;Hope this helps someone.&lt;/p&gt;
</description>
                <author>Mike Cullerton</author>

                
                    <category>jsregistry</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>generic setup</category>
                
                
                    <category>browser view</category>
                

                <pubDate>Tue, 22 Jun 2010 09:00:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Colorado World Plone Day - 2010</title>
                <guid>http://www.coresoftwaregroup.com/blog/colorado-world-plone-day-2010</guid>
                <link>http://www.coresoftwaregroup.com/blog/colorado-world-plone-day-2010</link>
                <description>&lt;p&gt;This year's Colorado World Plone Day event will be held at the National Renewable Energy Laboratory's (NREL) Visitors Center in beautiful Golden, Colorado, and will be presented as part of NREL's Power Lunch series.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Colorado World Plone Day Logo" class="image-left" src="../colorado-world-plone-day-2010/wpd.png" /&gt;Presenters will talk about various features of Plone, demo websites using Plone, and field any questions people may have.&lt;/p&gt;
&lt;p&gt;So far, this year's presenters are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kurt Bendl - Contractor at NREL&lt;/li&gt;
&lt;li&gt; Dan Timmons - CU, Boulder&lt;/li&gt;
&lt;li&gt;Chris Crownhart - Core Software Group&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;p&gt;The presentations will last from approximately 12:00pm - 12:45pm, followed by a 15 minute question/answer period.&lt;/p&gt;
&lt;p&gt;For those of you who need to get back to work, we will break shortly.  For those of you who wish to stick around to see some developer oriented presentations, and/or to discuss Plone's features in more depth, we will have the room for a couple more hours.&lt;/p&gt;
&lt;p&gt;Direction to the NREL Visitors Center can be found at: &lt;a class="external-link" href="http://www.nrel.gov/visitors_center/contact_visit.html"&gt;http://www.nrel.gov/visitors_center/contact_visit.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Power Lunch series is a brown bag style presentation series, so please bring a sandwich and come hang out with us for an hour.&lt;/p&gt;
&lt;p&gt;For more information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;See: &lt;a class="external-link" href="../colorado-world-plone-day-2010/colorado-world-plone-day"&gt;http://www.coresoftwaregroup.com/colorado-world-plone-day-2010&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Contact Chris Crownhart at 303/809-1001&lt;/li&gt;
&lt;/ul&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>Meeting</category>
                
                
                    <category>Social Event</category>
                
                
                    <category>community</category>
                
                
                    <category>worldploneday</category>
                
                
                    <category>presentation</category>
                

                <pubDate>Mon, 19 Apr 2010 13:20:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Overriding the Title tag in Plone 3</title>
                <guid>http://www.coresoftwaregroup.com/blog/overriding-the-title-tag-in-plone-3</guid>
                <link>http://www.coresoftwaregroup.com/blog/overriding-the-title-tag-in-plone-3</link>
                <description>&lt;h2&gt;Quick Overview&lt;/h2&gt;
&lt;p&gt;You need to override the &lt;b&gt;plone.htmlhead.title&lt;/b&gt; viewlet and &lt;b&gt;create a class&lt;/b&gt; to render your title. The default version of the viewlet is defined in [eggs]/plone/app/layout/&lt;b&gt;configure.zcml&lt;/b&gt;, and the class is defined in &lt;b&gt;common.py&lt;/b&gt;. You'll need a few more things from common.py too. Override the viewlet in your own [theme]/browser/configure.zcml file, and add the location of your new class.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;I needed to override a viewlet, but didn't know which one. A quick grep found a reference to the plone.htmlhead viewlet manager, and then one to the plone.htmlhead.title viewlet. Viewlets are found in the plone/app/layout/viewlets/configure.zcml file within the eggs area of your buildout. Here is the specific code in configure.zcml.&lt;/p&gt;
&lt;pre&gt;...&lt;br /&gt;    &amp;lt;browser:viewlet&lt;br /&gt;       name="plone.htmlhead.title"&lt;br /&gt;       manager=".interfaces.IHtmlHead"&lt;br /&gt;       class=".common.TitleViewlet"&lt;br /&gt;       permission="zope2.View"&lt;br /&gt;       /&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the plone.htmlhead.title viewlet references a class called .common.TitleViewlet. This means a file--in the same directory as configure.zcml, named common.py contains a class named TitleViewlet. Here is the TitleViewlet code from common.py.&lt;/p&gt;
&lt;pre&gt;class TitleViewlet(ViewletBase):&lt;br /&gt; &lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; def index(self):&lt;br /&gt;     portal_title = safe_unicode(self.portal_title())&lt;br /&gt;     page_title = safe_unicode(self.page_title())&lt;br /&gt;     if page_title == portal_title:&lt;br /&gt;         return u"&amp;lt;title&amp;gt;%s&amp;lt;/title&amp;gt;" % (escape(portal_title))&lt;br /&gt;     else:&lt;br /&gt;         return u"&amp;lt;title&amp;gt;%s &amp;amp;mdash; %s&amp;lt;/title&amp;gt;" % (&lt;br /&gt;                  escape(safe_unicode(page_title)),&lt;br /&gt;                  escape(safe_unicode(portal_title)))&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;In the index method at the bottom, Plone sets the value of the &amp;lt;title&amp;gt; tag.&lt;/p&gt;
&lt;p&gt;If the page title and the portal title are the same, the portal title is used. If not, both are used, with page title on the left and portal title on the right.&lt;/p&gt;
&lt;p&gt;We needed to switch it, so that portal title was on the left, and page title was on the right.&lt;/p&gt;
&lt;h2&gt;What we did&lt;/h2&gt;
&lt;p&gt;To override the title viewlet, I created an entry in my theme's browser/configure.zcml file.&lt;/p&gt;
&lt;pre&gt;&amp;lt;!-- Our custom title viewlet --&amp;gt; &lt;br /&gt; &amp;lt;browser:viewlet&lt;br /&gt; name="plone.htmlhead.title"&lt;br /&gt; manager="plone.app.layout.viewlets.interfaces.IHtmlHead"&lt;br /&gt; class=".myTitleViewlet.TitleViewlet" &lt;br /&gt; layer=".interfaces.IThemeSpecific"&lt;br /&gt; permission="zope2.View" &lt;br /&gt; /&amp;gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Notice that there is a new layer statement, and that the manager line includes the complete path to IHtmlHead. The class statement now points to our new class containing code to override the title.&lt;/p&gt;
&lt;p&gt;Here is the code from myTitleViewlet.py.&lt;/p&gt;
&lt;pre&gt;from zope.interface import implements&lt;br /&gt;from zope.component import getMultiAdapter&lt;br /&gt;from zope.viewlet.interfaces import IViewlet&lt;br /&gt;from zope.deprecation.deprecation import deprecate&lt;br /&gt;&lt;br /&gt;from Products.CMFPlone.utils import safe_unicode&lt;br /&gt;from Products.Five.browser import BrowserView&lt;br /&gt;from cgi import escape&lt;br /&gt;&lt;br /&gt;from plone.app.layout.viewlets.common import ViewletBase&lt;br /&gt;&lt;br /&gt;class TitleViewlet(ViewletBase):&lt;br /&gt;&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; def index(self):&lt;br /&gt; portal_title = safe_unicode(self.portal_title())&lt;br /&gt; page_title = safe_unicode(self.page_title())&lt;br /&gt; if page_title == portal_title:&lt;br /&gt; return u"&amp;lt;title&amp;gt;%s&amp;lt;/title&amp;gt;" % (escape(portal_title))&lt;br /&gt; else:&lt;br /&gt; return u"&amp;lt;title&amp;gt;%s | %s&amp;lt;/title&amp;gt;" % (&lt;br /&gt; escape(safe_unicode(portal_title)),&lt;br /&gt; escape(safe_unicode(page_title)))&lt;/pre&gt;
&lt;p&gt;I needed some of the imports from the top of common.py, and added one of my own for ViewletBase. The only code that really changed is the else clause, where the order of portal_title and page_title are switched, and the em dash is replaced by a pipe (|).&lt;/p&gt;
&lt;p&gt;A great reference for overriding the &amp;lt;title&amp;gt; tag is &lt;a href="http://plone.org/documentation/manual/theme-reference/elements/hiddenelements/plone.htmlhead.title"&gt;HTML Head Title&lt;/a&gt; page which is part of the &lt;a href="http://plone.org/documentation/manual/theme-reference"&gt;Plone Theme Reference&lt;/a&gt;.&lt;/p&gt;</description>
                <author>Mike Cullerton</author>

                
                    <category>plone 3</category>
                
                
                    <category>TitleViewlet</category>
                
                
                    <category>plone.app.layout</category>
                
                
                    <category>viewlet</category>
                

                <pubDate>Tue, 26 Jan 2010 12:20:00 -0700</pubDate>

                
            </item>
        
        
            <item>
                <title>Installing plone 3 using paster</title>
                <guid>http://www.coresoftwaregroup.com/blog/installing-plone-3-using-paster</guid>
                <link>http://www.coresoftwaregroup.com/blog/installing-plone-3-using-paster</link>
                <description>&lt;p&gt;We build most of our sites using paster (versus using the Unified Installer). Here are some simple notes we had for doing that (&lt;a href="http://plone.org/documentation/how-to/use-paster" target="_blank"&gt;more information on using paster with plone can be found in the Plone documentation&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This how-to assumes you have ZopeSkel installed.&lt;/i&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a directory to house the plone installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;mkdir /path/to/plone/install/directory&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt; Use paster to install buildout files.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;paster create -t plone3_buildout /path/to/plone/install/directory&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Change your working directory to the new zope install.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;cd /path/to/zope/install/directory&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Bootstrap the system.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;python bootstrap.py&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Run buildout.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;./bin/buildout&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;That's it.  Now, just start zope/plone.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;./bin/instance start&lt;br /&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Or run in it the foreground (and in debug mode).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;./bin/instance fg&lt;/pre&gt;</description>
                <author>Mike Cullerton</author>

                
                    <category>ZopeSkel</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>paster</category>
                

                <pubDate>Thu, 10 Sep 2009 17:30:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Migrating portal_status_message to addPortalMessage for Plone 3</title>
                <guid>http://www.coresoftwaregroup.com/blog/migrating-portal_status_message-to-cookies-for-plone-3</guid>
                <link>http://www.coresoftwaregroup.com/blog/migrating-portal_status_message-to-cookies-for-plone-3</link>
                <description>&lt;p&gt;This is a pretty simple change, but I could not find much documentation on it around the web.  We had quite a few controller python scripts that had code in them setting a portal_status_message.  The code looked like:&lt;/p&gt;
&lt;pre&gt;return state.set(portal_status_message='Your comment has been sent to the web support team.')&lt;/pre&gt;
&lt;p&gt;This old code is completely ignored now, so you have to convert these to the new format.&lt;/p&gt;
&lt;p&gt;In Plone 3, portal_status_message is now handled using a cookie, and there are special classes and methods for adding your messages to the cookie.&lt;/p&gt;
&lt;p&gt;Now, to set a status message, do the following:&lt;/p&gt;
&lt;pre&gt;from Products.CMFPlone import PloneMessageFactory as _&lt;br /&gt;context.plone_utils.addPortalMessage(_(u'Your comment has been sent to the web support team.'))&lt;/pre&gt;
&lt;p&gt;Additionally, you can pass flags to the method to indicate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; 'info'&lt;/li&gt;
&lt;li&gt;'warning'&lt;/li&gt;
&lt;li&gt;'error' &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;like:&lt;/p&gt;
&lt;pre&gt;context.plone_utils.addPortalMessage(_(u'Your comment has been sent to the web support team.'), 'info')&lt;/pre&gt;
&lt;p&gt;For more information about the classes, interfaces, and methods, see this PLIP: &lt;a href="http://plone.org/products/plone/roadmap/111" target="_blank"&gt;http://plone.org/products/plone/roadmap/111&lt;/a&gt;&lt;/p&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>python scripts</category>
                
                
                    <category>plone 3</category>
                
                
                    <category>migration</category>
                

                <pubDate>Fri, 28 Aug 2009 09:30:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Simple way to add lightbox/thickbox support to Plone 3 site</title>
                <guid>http://www.coresoftwaregroup.com/blog/simple-way-to-add-lightbox-thickbox-support-to-plone-3-site</guid>
                <link>http://www.coresoftwaregroup.com/blog/simple-way-to-add-lightbox-thickbox-support-to-plone-3-site</link>
                <description>&lt;p&gt;On the old Core Software Group site, I downloaded thickbox and manually added the css and js files to the portal_css and portal_js registries.  It worked, but was kind of kludgy.&lt;/p&gt;
&lt;p&gt;Thanks to Steve McMahon's &lt;a href="http://pypi.python.org/pypi/Products.pipbox" target="_blank"&gt;Products.pipbox&lt;/a&gt;, it's clean and easy, and gives you a massive amount of flexibility and control.  Here's all I did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Added Products.pipbox to my eggs section of my buildout.cfg, then ran bin/buildout&lt;/li&gt;
&lt;li&gt;Installed pipbox via quickinstaller&lt;/li&gt;
&lt;li&gt;pipbox adds a property sheet to portal_properties, which for now, you have to edit via the ZMI&lt;/li&gt;
&lt;li&gt;I added the following to /portal_properties/pipbox_properties -&amp;gt; selector specs:&lt;/li&gt;
&lt;ul&gt;
&lt;p class="callout"&gt;{type:'overlay',subtype:'image',selector:'img.image-right,img.image-left,img.image-inline',  urlmatch:'/image_.+$',urlreplace:''}&lt;/p&gt;
&lt;/ul&gt;
&lt;li&gt;That's it.  Now our &lt;a href="../what-can-we-do-for-you/portfolio"&gt;portfolio page&lt;/a&gt; uses the lightbox popups to display screenshots of Plone sites we have built.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next up:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Figure out how to control the position of the popup box.&lt;/li&gt;
&lt;li&gt;Figure out how to take advantage of AJAX form support in pipbox.&lt;/li&gt;
&lt;li&gt;Figure out how to implement AJAX tabs using pipbox.&lt;/li&gt;
&lt;/ol&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>plone 3</category>
                
                
                    <category>pipbox</category>
                
                
                    <category>thickbox</category>
                
                
                    <category>lightbox</category>
                

                <pubDate>Wed, 26 Aug 2009 12:15:00 -0600</pubDate>

                
            </item>
        
        
            <item>
                <title>Welcome to our new blog</title>
                <guid>http://www.coresoftwaregroup.com/blog/welcome-to-our-new-blog</guid>
                <link>http://www.coresoftwaregroup.com/blog/welcome-to-our-new-blog</link>
                <description>&lt;p&gt;We at Core Software Group have been working with Zope for almost 10 years now, and with Plone for nearly 7 years!  Man, that is awesome!  I have always believed that Plone is the killer app for Zope, and have thoroughly enjoyed providing Plone consulting services.&lt;/p&gt;
&lt;p&gt;During our journey down the Plone road, we have learned a ton, and it is my hope that we can share what we have learned in the past, and what we will learn in the future, on this blog, so other folks can benefit.&lt;/p&gt;
&lt;p&gt;We have worked on Zope-only applications, built CMF-only applications, supported a variety of Plone versions, and most recently have been migrating old Plone sites to the newer Plone 3 platform.&lt;/p&gt;
&lt;p&gt;There are an enormous amount of resources on the web for helping developers with Plone, but it always seems like the one thing you are working on does not have much documentation.  Additionally, there are just some things that require the "secret decoder ring"!&lt;/p&gt;
&lt;p&gt;When we come across oddities that require you to pat your head and rub your belly at the same time to get Plone to work just right, we will tag them with "secret decoder ring".&lt;/p&gt;
&lt;p&gt;I hope that we can provide useful information to other developers.  If you like what we've done, or have questions about what we can do, please feel free to &lt;a href="../contact-us"&gt;contact us&lt;/a&gt;.&lt;/p&gt;</description>
                <author>Chris Crownhart</author>

                
                    <category>secret decoder ring</category>
                
                
                    <category>plone 3</category>
                

                <pubDate>Sat, 15 Aug 2009 12:45:00 -0600</pubDate>

                
            </item>
        

    </channel>
</rss>


