<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
         xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://www.martinaspeli.net/blog-posts/RSS">
  <title>Martin Aspeli</title>
  <link>http://www.martinaspeli.net</link>
  
  <description>
    
       A blog and personal website
       
  </description>
  
  
  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2009-01-07T00:59:00Z</syn:updateBase>
        
  
  <image rdf:resource="http://www.martinaspeli.net/logo.gif"/>

  <items>
    <rdf:Seq>
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/a-little-documentation-goes-a-long-way"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/being-small-and-beautiful"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/the-dog-ate-my-contributor-agreement"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/dvcs-baby-steps"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/im-a-cutting-edge-technologist-but-please-dont-make-me-learn-anything-new"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/of-babies-and-bathwater-or-why-i-love-the-zope-component-architecture"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/using-hudson-ci-for-plone-projects"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/using-grok-techniques-in-plone"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/the-naming-of-things-package-names-and-namespaces"/>
        
        
            <rdf:li rdf:resource="http://www.martinaspeli.net/articles/dexterity-1.0a2-released"/>
        
    </rdf:Seq>
  </items>

</channel>

    <item rdf:about="http://www.martinaspeli.net/articles/a-little-documentation-goes-a-long-way">        <title>A little documentation goes a long way</title>        <link>http://www.martinaspeli.net/articles/a-little-documentation-goes-a-long-way</link>        <description>The most important change in my working practices in recent months, making your life a little better</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>The most important change in my working practices in recent months, making your life a little better</p>
<p>Over the past couple of years, we've seen a dramatic shift in the way Plone software (and Zope software, and, really, Python software in general) is packaged. Our code is now broken into dozens of packages, pulled in via a complex set of dependencies, and managed via powerful tools like Buildout.</p>
<p>However, the part of this whole story that excites me the most is the humble README.txt, combined with the practice of turning it into the "long description" in setup.py that appears on <a class="external-link" href="http://pypi.python.org/pypi">PyPI</a>.</p>
<p>I didn't always appreciate this quite so much, but that little bit of documentation is the minimum you <em>must</em>&nbsp;do if you release something. It is not a substitute for more narrative documentation, which helps people learn and understand how the pieces fit together. However, the package README is the first line of defence for reference documentation. Once people have an idea about how your software fits together, they will find the package and expect to be told enough about to use it without having to resort to code archeology.</p>
<p>Let's look at some examples. First, there's the narrative "how does it all fit together" type documentation. This needs to be kept separate, and must be discoverable independently of code structure. A good example of mine is the <a class="external-link" href="http://plone.org/products/dexterity/documentation">Dexterity manuals</a>.</p>
<p>Next, a bad example: The README for <a class="external-link" href="http://pypi.python.org/pypi/plone.theme">plone.theme</a>. Ironically, I was trying to remember how to hook a browser layer up to a CMF theme (the <em>raison d'etre</em> of plone.theme<em>)</em> and&nbsp;got rather annoyed by the total lack of information in that README. I then realised who wrote the package. D'oh.</p>
<p>A better example is <a class="external-link" href="http://pypi.python.org/pypi/collective.beaker">collective.beaker</a>, a package for using the Beaker session and caching management framework in Zope 2. Notice how you both find out what the package is for, and how it is used. There are installation instructions, too, and hints on things like testing, where this package has some unusual implications.</p>
<p>More recently, I've started doing this very seriously, for example in the as-yet unreleased update to <a class="external-link" href="http://dev.plone.org/plone/browser/plone.app.registry/trunk/README.txt">plone.app.registry</a> and the new-and-exciting <a class="external-link" href="http://dev.plone.org/plone/browser/plone.app.caching/trunk/README.txt">plone.app.caching</a>. My coding cycle is now to do the interfaces module first, then code and tests in tandem, and then documentation. I normally start writing the README while waiting for test runs to complete. This cycle is then repeated, so that I update and revise the README as I refactor code. Finally, I read the rendered README through once as a sanity check before doing a release to PyPI.</p>
<p>Importantly, the documentation for the packages above has helped make them substantially better. By trying to explain how they worked, I found troubling inconsistencies and omissions that I'd failed to spot in my unit tests or interfaces.</p>
<p>Put differently, if something cannot be documented properly, it's crap. Find out for yourself before you foist it on everyone else, as Chris McDonough would no doubt <a class="external-link" href="http://plope.com/Members/chrism/succeeding_poorly">agree with</a>.</p>
<p>I'll leave you with some practical advice:</p>
<ul><li>Have a README.txt in your package and make sure it's being included as the long_description in setup.py. The standard ZopeSkel templates takes care of this for you.</li><li>Make sure your README makes sense to someone other than yourself. Start by explaining what the package is for and why it exists. Mention briefly how to install it. Then explain the main use cases and how they are achieved. Even a few bullet points will go a long way. If your package is mostly user-facing, explain where people should expect to find its functionality in the UI. You can reference interfaces or code as necessary, but give people a fighting chance to see the big picture first.</li><li>Your README is <em>not</em>&nbsp;a doctest. You can have doctests too, and if you genuinely believe they are useful to someone trying to understand your package, you can append them too to the long_description <em>after</em> the README. They <em>must</em> be separate files. Doctests are often good for low-level documentation (and sometimes more appropriate for really basic packages that have no end-user or integrator relevance). But they are not by themselves sufficient for documentation, and can be hugely off-putting by tricking the reader into thinking they can figure out how to use the package, when in fact it only shows contrived test cases based on unrealistic test setup. (Yes, I haven't always been of this persuasion, but I've seen it go wrong too many times).</li><li>Make sure your README is valid reStructuredText. I dislike reST, but I've grown to tolerate it, and it's what PyPI renders. In TextMate, the reStructuredText bundle helps a lot, as I can now preview the rendered text with Cmd+Alt+Ctrl+P.</li><li>Have a HISTORY.txt in the long_description too (the standard templates again set this up for you), and maintain a change log once you've released the package. I cannot overstate how important it is to have a clear picture of how a package has changed, and in which versions new features or bug fixes were introduced.</li></ul>
<div>Some people are instinctively scared by documentation. Don't be. It doesn't take long. It will likely pay off later when you come back to the code, and it'll certainly help others, who are now less likely to hassle you for basic help. You went through the trouble of writing a package and releasing it. Why do that if no-one can figure out how it works?</div>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2010-02-04T13:43:31Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/being-small-and-beautiful">        <title>Being small and beautiful</title>        <link>http://www.martinaspeli.net/articles/being-small-and-beautiful</link>        <description>Some thoughts on what makes a small (software) business successful</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>Some thoughts on what makes a small (software) business successful</p>
<p>In most countries, small businesses are the backbone of economic growth and employment. This is especially true in technology, where small businesses and startups also often drive innovation and quality improvements in their field.</p>
<p>I've had the opportunity to work for a couple of small (5-20 people) software development companies, as well as for some really big companies. More importantly, I've been in a position to help medium and large clients procure services from smaller vendors, advising on such things as the risk of relying on a smaller partner and the potential benefits of a closer working relationship and specialised expertise.</p>
<p>Sometimes, this type of partnership works very well, but it can also be pretty frustrating for all parties involved: the client, the vendor, and the hapless business consultant in the middle trying to smoothen out the process. That's usually down to details: differences in expectations, poorly written contracts, communication problems, or differences in working styles.</p>
<p>It's not always easy to give feedback individually, but here are some collected thoughts. These are not directed at anyone in particular. In fact, I think I've been lucky with the small businesses I've work with. Still, I'm sure many of us would recognise some of these challenges from projects past.</p>
<h2>Know your size</h2>
<p>I'd bet that most small software businesses work primarily for clients that are larger than themselves, be that in the private or public sector. This has implications for the relationship between client and vendor. In particular, the client is exposed to more risk than you are (or at least they'll think that they are), because if you go belly-up, the client is unlikely to get their money back. This is not a bad thing, so long as both sides are aware of it. If the old adage that "the client is always right" holds true, a corollary may be that "a bigger client is always more important than you are".</p>
<p>Of course, that doesn't mean the client should be given free rein to boss you around. If you are honest about your size, the client needs to respect that. If they start asking for the impossible, such as exclusive access to people who are also needed on other projects, sit them down and talk to them about your business and why things are they way they are. If they can't hold up their end of the bargain, it's time to look for new clients.</p>
<p>The size mis-match sometimes becomes acute when a small business tries to sound bigger than they are. Nothing makes a client think "amateurs" like hollow attempts at grandeur or obfuscation. Personal favourites include:</p>
<ul><li>Every employee has a CxO title. You're the CEO, your wife's the CFO and the guy you just hired is the CTO. A CEO (at least in Europe and Australia) is associated with someone who leads a large team and makes executive decisions. Certainly not someone who does day-to-day grunt work (like programming or, worse yet, support). If, on the other hand, you call yourself "Partner", you're probably on safer ground.</li><li>Some employees have <em>more than one</em>&nbsp;CxO title. We're two people who run a company. You're CEO and CTO, and I'm CFO and COO. Right.</li><li>Obviously vague statements about size, turnover, etc. The worst case scenario here is a one-man company that pretends to have employees. (There's nothing wrong with being a one-man company. It just means that as far as your client is concerned, you're a contractor. That's likely to make your life a lot easier anyway, since the client will probably handle some of the administrative overhead for you.) If you're a bigger company, be honest and unapologetic about your size. The client has made a conscious choice to go with a smaller vendor. They're not going to suddenly run away because you're 8 people instead of 10.</li></ul>
<h2>Be clear about what you do</h2>
<p>Some people never say "no". The problem is if you tell your clients you can do everything, they expect you to be good at everything, too. And one big failure is going to loom larger in clients' memories than ten success stories. Tough luck. If you're not very good at requirements management, or web design, or PostgreSQL, don't tell them you can do it. Find a way to work with others who are good at it instead.</p>
<p>This also has to do with confidence in front of the client. If you can't explain to a client in a few short sentences what you and your company do best, start working on that right now. As in dating, a show of confidence can go along way towards sealing the deal.</p>
<p>The best focus statements I've seen tend to be:</p>
<ul><li>Concise</li><li>Compelling</li><li>Focused on customers' business problems, rather than presumptive technology solutions</li><li>Industry-aware - if you understand a client's industry, you're a lot more likely to speak their language and be able to predict their challenges</li></ul>
<p>Conversely, one of the worst ones I've seen went something like this: "Almost no matter what your problem, we'll find a way to apply Python and Zope to it". I paraphrase. And I forget where I read it. But this implies that you have a mighty hammer, and pity the projects that you may look upon as nails.</p>
<h3>Are you a 'product' business or are you a 'service' business?</h3>
<p>I submit that this is the kind of thing you need to decide up-front, and be brave enough to stick to it. Companies like IBM will sell you products (e.g. software licenses or hardware) as well as services (consulting, development), but they are huge and they keep those parts of their business quite separate. If you're a small company, you can sell products (i.e. deliver physical products or sell licenses), or you can sell services (i.e. work on projects). You can't do both. Or at least you shouldn't.</p>
<p>Selling things and selling services are quite different activities, that place different demands on a business. If you sell software licenses, clients are going to expect salespeople, professional documentation, rapid security updates, license management and bulk licensing deals, solid support, and continuous improvement to the product. Development requires a substantial up-front investment, as well as ongoing investment in maintenance and updates, marketing and so on.</p>
<p>If you are delivering projects, clients expect you to work on their project full time. As soon as you become successful as a consultant or contractor, you're not going to have time to work on your products. Unless you dedicate staff exclusively to supporting and developing your products, you're going to be caught between the rock of your clients and the hard place of your customers. And few small companies have the luxury of ring-fencing people like that.</p>
<p>Fundamentally, this is the distinction between "business-as-usual" work and "project" work. Mixing the two modes of working is hard enough in a big organisation. For a small business, it normally means working for your clients during the day and working on your products at night. That's not sustainable.</p>
<p>The attraction of being a "product company" is that it promises a stable revenue stream and frees you from the pain of project management and complicated clients. However, most companies struggle to reach sufficient sales quickly enough to make back their initial investment and still pay their staff. Project work at least pays straight away.</p>
<p>If you are working with open source, trying to sell licenses can be even more complicated. Using open source technologies is one of the great equalisers for small companies, who can credibly claim that the risk of going with a smaller vendor is counterbalanced by a community of people and companies familiar with the technology. Unfortunately, there won't be a community around your proprietary product, so you end up undoing one of the good arguments for people to buy your services. And that's before you get into the&nbsp;intricacies&nbsp;of copyright and license terms, made even worse if you ever blur the lines and use a customer project to build a product you then intend to sell to others. (Hint: don't do it.)</p>
<h3>Are you a project business or a support business?</h3>
<p>This one's related to the previous point, but it's harder to get away from support. If you build a piece of software for a customer, they are going to want support.</p>
<p>You probably can't get away from doing support, but you should decide whether you are going to make most of your money on project fees, or in support contracts, and configure your business accordingly. Clients understand the distinction, and will want to know: are you in it only for new development (in which case they will want strong assurances about continued support and, possibly, supportability by other vendors), or are you after a long-term contract (in which case they'll expect a discount on your rates up-front in return for a longer term contract).</p>
<p>You also need to make sure you dedicate enough resources to support on an ongoing basis. Your current support clients are liable to be your next project clients. That is, unless you bungle that crucial call that comes in just when your team is trying to finish off a project for another client. It can be difficult to balance "old" (and perhaps boring) support work with "new" project work, so make sure you build that into your plans from the beginning, or you'll end up on the nightshift again.</p>
<h2>BE REALISTIC ABOUT YOUR RATES AND TRANSPARENT ABOUT YOUR PRICING</h2>
<p>Pricing can be really hard. To set your prices, you need to understand something about what your customers expect, and what your competitors are charging, but both your clients and your competitors have an interest in keeping that information from you. You also need to know when to change your prices, and how to build that into your contracts.</p>
<p>There are some useful rules of thumb, though. First of all, you can charge less as a small company than can a big company. This has little to do with the quality of your work or the depth of your expertise. However, there is an inherent risk premium for the client associated with going with a smaller vendor. If you screw something up, chances are it will sting the client more than it will sting you. At least instinctively, most clients believe that bigger companies are less likely to screw up, and better able to back-fill in case of resource unavailability or skill shortages. To a certain extent, this is true. A big vendor working with a big client has more to lose, and will invest in keeping a relationship going. They will also hopefully have more checks and balances internally, and often more experience on which those checks and balances rest.</p>
<p>Cost is often a reason put forward by those in the client's procurement process wanting to go with a smaller vendor. If your costs come in as high as or higher than a "big" name, those champions will have a harder time explaining why your tender should win.</p>
<p>In a very unscientific estimate, I'd suggest that the best place to be is in the upper third of the price range for your local market. If you're the most expensive vendor, you better be damned good, because as soon as the client has to cut cost, they'll start at the top of the rates card and work their way down. If you're the cheapest bidder, they may question your seriousness. Cost can be a signal of quality, but don't confuse cause and effect: you can't charge more in order to appear like a gold-plated option. You'll be extremely closely scrutinised if you make that claim, and if your claim doesn't hold up, you'll be dropped like a stone.</p>
<p>You also need to be transparent about your pricing. Pricing can be very psychological. Many clients will be unhappy about paying a high day rate for a small vendor, even if the total cost is dwarfed by other projects. It simply feels wrong for the five-person company to charge more than IBM or SAP do for their top consultants. This can quickly turn into a charge that you are out of touch with your market.</p>
<p>You should have a rate card. For standardised services, like support, you can put this on your website. For projects, keep it confidential, but share it with your clients. Your rate card needs to set out a day or hourly rate for each type of resource you have, e.g. senior developer vs. junior developer. Clients also like discounts, so feel free to show them a rate card and then outline a price based on a discount.</p>
<p>No matter what you do, though, for the love all that is good and holy, produce a simple price table that makes it abundantly clear what the client has to pay, and when they have to pay it. If the client has to think (or bring out a spreadsheet) to figure out the total cost, you've lost. If it's not clear what's to be paid up front, and whether there is an annual cost involved for support, you've lost. For example, if you itemise "development" and "annual support", is support included in year 0? Is it payable from when the project begins or ends? What if there are multiple releases? "Creative", unclear pricing is probably the number one way to look unprofessional. You should have a single pricing model and stick to it, not leave it up to each tender to come up with some way of making money.</p>
<p>Finally, a word about pricing in its wider context: you need to measure your recovery. How many hours do your staff work? How many hours do you pay them for? How many hours' worth do you invoice the client for? And how many hours' worth do you actually get paid, on time?</p>
<p>If you don't have these or similar numbers readily to hand, you're not running your business properly. A lot of small companies fail to invoice regularly, or send invoices that contain errors. This is unforgivable and wreaks all sorts of havoc. If you've ever seen anyone try to bend their SAP finance system to accommodate a vendor that does unusual things, you'll know what I mean.</p>
<p>Ask yourself this: could you lower your prices and still make the same money if you actually managed to recover fees for all the hours you spent on a project? If the answer is yes, you should try to do that, because your customers will feel like you're a more predictable partner, you will appear more professional, your staff will feel like their work counts for more, and you are more likely to win work since you now have a cost advantage. Driving this type of efficiency in your own business is hugely important, and requires constant attention and measurement. And proper internal systems for things like time writing and invoicing. Don't skimp on these. And please don't try to build your own, unless you happen to also sell those types of solutions to clients.</p>
<h2>Know your customers</h2>
<p>Just as important as knowing yourself, is knowing your customers. This is where industry specialisation can help, although I think that often happens more by accident and word-of-mouth marketing than by design. Ideally, you want to walk into the first meeting with a new or prospective client armed with a solid understanding of who they are, and what they do. Do some research:</p>
<ul><li>What kind of business are they?</li><li>What are the biggest challenges facing them right now?</li><li>Why are they doing this project?</li><li>Where do you think this project fits into the overall picture?</li><li>Who are the key stakeholders for your project? Who are your champions and who are your detractors?</li><li>Who else are going to be involved from the client's side? How can you get to know them?</li></ul>
<p>I've seen many a small business win out over a bigger rival because the client says, "they know us best". A close partnership and good personal relationships are your biggest assets when you're small, especially in the private sector.</p>
<h2>GET GOOD AT WRITING TENDERS</h2>
<p>Everybody hates writing tenders. They take way too much time, involve a lot of tedious questions, and the outcome is by no means certain. And without fail, they end up keeping you up into the wee hours the night before submission. However, your tender response is the first impression you leave with a new client. Some obvious things that help are:</p>
<ul><li>At the end of each project, spend a few hours writing up a credential that you can re-use. This should be half a page, and answer four questions:</li>
<ul><li>Who is the client? You need to check that you can use their name. If you can't, generalise, e.g. "A major retail bank".</li><li>What problem were they facing? Make sure you don't make your client look bad here.&nbsp;</li><li>What did your company do?</li><li>What were the outcomes? Try to quantify if you can, e.g. "10% cost saving".</li></ul>
<li>Re-use sections such as "who we are" and "what we do". Find a structure that works and stick to it.</li><li>Write proper English (or whichever language you work in). Some clients will not even read a tender submitted that is full of grammatical errors, and even those who do read it will not be impressed by the time they score your submission.</li><li>Get someone else to proof read. Ask them to try to cut the word count down by 20%. Many people will waffle endlessly trying to sound "businesslike". Don't fall for it. Clients like short sentences and straightforward language just as much as you do.</li><li>Answer the tender. A lot of client just won't read a nonconformant response. If you really want to suggest a better way, some clients will thank you, but play it safe, and submit two tenders (or an appendix) - one that conforms, and one that doesn't.</li></ul>
<h2>Standardise your processes</h2>
<p>The tender might get you in the door, but you've got to work hard to stay there. In general, I've found that there are two types of clients: those that have a project management office and expects you to work within their process, and those that expect you to get on with the job yourself. In either case, you'll get the blame if something goes wrong.</p>
<p>If the client has a process, learn it. You should ask for proper training, and figure out where to get support if you have questions. The last thing you want is to be remiss in some project management deliverable. The kind of people who call you up on such things are unlikely to be impressed by your programming skills.</p>
<p>If the client doesn't have a process, you need one. My advice would be to pick one that already exists and is well known, rather than trying to invent your own. Get your people certified in it if you can. Scrum is a personal favourite, but the most important thing is to have a process and sticking to it. It's important that your process includes a means of managing requirements throughout the lifecycle of a project, and gives lots of opportunities for interaction with and feedback from the client.</p>
<h2>Keep your communication professional</h2>
<p>Every time you communicate with your client - by email, letter, phone or in person - you are either building on or taking away from their impression of you. That goes for every member of your team. If you slide into jargon, come across as flippant (rule of thumb: no humour in emails), or simply give the impression that you are out of touch, you're in trouble.</p>
<p>Also be aware that email is the most dangerous form of communication. A lot of problems in my career could've been avoided had I spoken to someone on the phone or in person, rather than by email. One of the biggest lessons I've learned is that open source developers have an entirely different way of reading and writing emails than clients.&nbsp;A lot of people don't take well to long emails. Some people don't feel it's obligatory to respond to emails, but will normally answer the phone and return messages. Businesspeople often don't understand inline quoting, either.</p>
<p>Finally, be professional at every turn. For example:</p>
<ul><li>Come to meetings with professional-looking business cards.</li><li>Use an email signature that includes your company name and phone number.</li><li>Record a professional voice-mail greeting.</li><li>Get someone with design experience to create presentation and document templates and use them, every time.</li><li>Produce formal documents on company letterhead.</li><li>Show an interest in your client's problems and listen more than you talk. When you do talk, speak with confidence. Point to your experience and aim to illustrate how you can solve their business problems, rather than highlight how good you are in your field of speciality.</li><li>Dress like your client. If they wear a suit and tie, so do you. If they're more casual, lose the tie and maybe the jacket. If they're media types, dust off the mail bag and grow that goatee.</li></ul>
<p>These are little things, but they can make a big difference in how you are perceived.</p>
<h2>WORK ON-SITE</h2>
<p>One of the great things about my current job is that we almost always insist on working on-site. The one project where we didn't spend much time on-site was also one of the hardest, and that was not an accident. Working on-site lets the client see the work you do. It allows you to meet people spontaneously or as needed to clarify requirements or other aspects of the project. It allows you to socialise and form relationships beyond the purely functional.</p>
<p>Working on-site can be difficult if you're doing development. Things like corporate firewalls often get in the way. And of course, not all clients are just down the road. Try to do it at least part-time anyway, especially in the early phases of the project.</p>
<h2>Don't be your own lawyer</h2>
<p>Hire a lawyer. Make sure you understand every contract you sign. Make sure any contract you ask the client to sign has been drafted by a lawyer and doesn't contain anything "weird". Weird contracts are a great way to mire a project in delays, and can come back to bite you in ways you'd rather not know about.</p>
<h2>Conclusion</h2>
<p>I hope this list has been useful. I'm sure you could add many more. Feel free to use the comments to share your own experiences, or tell me that I'm wrong.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-12-26T14:45:12Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/the-dog-ate-my-contributor-agreement">        <title>The dog ate my contributor agreement</title>        <link>http://www.martinaspeli.net/articles/the-dog-ate-my-contributor-agreement</link>        <description>Top five excuses for not contributing to open source, and why you need to get over it.</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>Top five excuses for not contributing to open source, and why you need to get over it.</p>
<p>Plone is true "community-driven" open source project. No-one is paid specifically to work on Plone, and yet it gets developed. The Plone Foundation protects Plone's intellectual property and handles other issues (like commissioning marketing materials and managing domain names), but takes a completely hands-off approach to development. And yet Plone development continues apace. No one company has a monopoly on development, and yet many small companies and individuals manage to self-organise into building the content management system you know and love (or <a title="Oh, how we love to hate Plone" class="internal-link" href="oh-how-we-love-to-hate-plone">love to hate</a>).</p>
<p>How does this happen? How does the content management system, which you are implementing for your business or selling to your clients or using on a day-to-day basis, come to be?</p>
<h2>Contributors, that's how.</h2>
<p>That's right, open source software is built by contributors. People who write code and documentation, who test and report bugs, who evangelise and organise conferences and other events.</p>
<p>But who are these mythical contributors? By and large, they're people like you and me. They have needs to solve. They have projects to deliver. They have customers with requirements. And they have found out that by contributing to the project, they gain something.</p>
<p>There are several reasons why people contribute to open source (some of them outlined in my <a title="Plone: A model of a mature open source project" class="internal-link" href="../publications/Plone%20-%20A%20Model%20of%20a%20Mature%20Open%20Source%20Project.pdf">Master's thesis</a>), but here are some of the most important ones in the context of Plone:</p>
<ul><li>You are using Plone and you find a bug. You report that bug. (This is already a form of contribution.) Your problem is solved if and when someone finds the time to fix the bug. If you're lucky, you may know someone who can fix it for you quicker, or you may pay someone to fix it if it's urgent.</li><li>You are using Plone and you find a bug. Instead of (or in addition to) reporting the issue, you submit a patch (in the issue tracker) or commit a fix. You gain almost immediately, because your problem is resolved. Other people gain too, because they get your fix in the next release.</li><li>You are using Plone and you need a new feature. You write it, either as a change to the core of Plone, or as an add-on product. You release that so that others can benefit. You gain, because other people may help you maintain the software, by fixing bugs or contributing improvements.</li><li>You are using Plone and you need a favour. Others have benefited from your contributions previously, and all are all too happy to help answer your intricate questions or debug a problem. You gain, because you can call in your favours when you need them the most.</li><li>You are using Plone and you want to get better at it. You make a contribution. In the process, you ask for some advice (or receive some unsolicited). You learn and become a better Plone developer in the process.</li><li>You are using Plone and you contribute a high-profile add-on product. People realise you're good. Your services come in demand. Publishers want you to write books. You find that you can make good money as a Plone consultant. You gain because your marketing budget is naught.</li><li>You are using Plone and it is an important part of your business. You contribute new features and participate in the community processes (like the Framework Team), as well as in the general discourse on the mailing lists and chat rooms. You gain because your voice is heard and you are given the chance to influence the direction in which Plone is heading.</li><li>You are using Plone and you go to a conference. You meet lots of people there, who you come to call your friends. You gain because you make new friends. Bonus if you didn't have any to begin with.</li><li>You are using Plone, and you've previously fixed bugs and helped others. You go to a conference and meet the people who've benefitted from your work. You are filled with a sense of great accomplishment and pride as they thank you sincerely. They buy you a beer. You get drunk, and decide to hit on the hot blonde who happens to be in the bar and loves your Star Trek t-shirt. You gain because... oh, nevermind.</li></ul>
<p>Contributions don't necessarily come in the form of code either. Some of the more valuable things you can do are:</p>
<ul><li>Answer questions on the mailing lists.</li><li>Test new releases and report bugs.</li><li>Help translate Plone to your native language.</li><li>Help organise the bug tracker, combining duplicates and filtering out invalid bugs.</li><li>Write documentation, whether for end users or developers.</li><li>Organise a sprint, symposium or conference.</li><li>Sponsor important work.</li></ul>
<h2>Contribute, moi?</h2>
<p>Everyone, without exception, has the capacity to contribute. And yet, many are apprehensive. Let's count down the most common excuses.</p>
<h3>1. I have no time</h3>
<p>Guess what, no-one else has any time either. Not one single person is paid specifically to work on Plone. Do you really think that you are so much more busy than everyone else?</p>
<p>This is of course a very valid excuse. Plone shouldn't come at the expense of your personal life or client deliverables. But this is not a zero-sum game. Time spent contributing has benefits. The smart Plone companies have realised that they owe their business in part to the community of contributors, and need be a part of that to stay relevant, to improve their standing in the market, and simply to have a platform to build on in the future.</p>
<p>Find out how you can contribute, and take it seriously. Many Plone companies have vowed to spend 5-10% of their time on community contributions. One way to do that is to send people to conferences and sprints where they can connect with others and work on Plone core.</p>
<p>Furthermore, the best Plone companies will find ways to improve Plone in the course of their customers projects, for example by writing re-usable components instead of "point solutions" where possible. Customers benefit here too, because they end up with more maintainable software that is understood by a larger community of vendors. The solution that is cheapest in the short term is rarely the cheapest over the total lifecycle of a project, and vendor lock-in (even to a vendor as nice as you and your company) is a risk not to be taken lightly. It's pretty likely that your customers chose open source and Plone at least in part for these reasons, so don't be afraid to make the case that contributing to the community makes sense for them as well as for you.</p>
<h3>2. I am not good enough</h3>
<p>Trust me, if you know where to look, you'll find code in Plone written by programmers way less skilled or experienced than you.</p>
<p>This is probably the most common excuse, but it doesn't hold water. Everyone can contribute, and writing code is far from the only thing that is valuable. You are never going to get better unless you try. Perhaps you shouldn't try to perform major refactoring or change any fundamental behaviour the first time around, but bugs are fair game, and Plone has a well-established process for reviewing proposals for new features.</p>
<p>More importantly, you'll find that if you <em>try</em> to contribute, you will get a lot of help and kudos. Existing contributors are much more likely to help those who try to help themselves than those who throw up their hands and say they can't or won't (but still complain about bugs going unfixed). Ask in the IRC chatroom or the on the mailing lists. Make it clear that you're trying to do your bit. I for one will help you if I can. And before you know it, you'll be the one helping others get their contributions in. We all started somewhere.</p>
<p>Plone in particular has a low barrier for contributions. There are people who read the checkin mailing lists and will email you if you did anything wrong. In the words of Plone's co-founder Alexander Limi: It's better to ask for forgiveness than permission.</p>
<h3>3. I need a fix RIGHT NOW</h3>
<p>We have a tool for you: it's called Subversion.</p>
<p>Some people seem to think that getting a fix into Plone will take longer than doing it themselves, e.g. with a monkey patch in a separate product. This is entirely counterproductive. First of all, by keeping the fix out of its proper location, you create an additional maintenance burden. Secondly, you're likely to find yourself fixing the same thing again on your next project, especially if Plone has moved on and your patch is no longer 100% valid. Thirdly, fixing a problem with an override is almost almost more complex than fixing the original code. Finally, you are keeping others from benefitting from your changes, so you get none of the network effect benefits.</p>
<p>Fixing something properly is easy. Modern Plone projects are managed with Buildout, which in turn manages a set of Python eggs that make up the Plone distribution. All you have to do is check out a "develop egg" from Subversion for the package you need to fix. If you use the <a class="external-link" href="http://pypi.python.org/pypi/mr.developer">mr.developer</a> extension, it's even easier, you can just add the svn path and run "<em>bin/develop co plone.whatever</em>". You make your fix there, and then commit (try to make sure the tests pass; you may also be asked to merge your fix to trunk if you're on a maintenance branch, but that is easy in almost all cases). Until there's a release, you'll need to keep running that egg from Subversion, but this is little different from running your own, unreleased/untested code.</p>
<p>Now, some people are nervous about running Plone packages form subversion. Luckily, the actively maintained Plone versions see a release every 2-4 weeks if there are changes to release. And since Plone is now just a set of eggs, you don't need to wait for a full Plone release. Ask the maintainer of the package you had to fix for a new release, and you can start using it right away with a single line in your [versions] block in your buildout.</p>
<p>In an case, the burden of fixing something "out of context" and managing that fix "forever" in a separate place is always going to be higher than doing it properly. You're also much more likely to get feedback and help from others if you contribute, so you'll know much sooner whether your fix is "right".</p>
<h3>4. I don't want to (or my boss won't let me) sign the contributor agreement</h3>
<p>This one falls into three categories: Some people hate paperwork and can't be bothered to sign a legal document; some people are uncomfortable with the terms of the agreement; and some people work in organisations who are too paranoid to have their employees sign an open source contributor agreement.</p>
<p>There's little excuse for the first category: Plone's contributor agreement is a two page form written in pretty clear language. I think it took me five minutes to read it, sign it, and send it off.</p>
<p>If you are in control of your business, you also have little to worry about. So many other businesses have signed up that you are unlikely to have a unique problem. The contributor agreement is there <em>solely</em> to protect you and others like you. It is not a legal document designed to take away your rights. Anyone who's been involved in an open source project where&nbsp;intellectual&nbsp;property issues became a real, rather than a hypothetical, issue knows that this is a murky world that can lead to a lot of confusion. You should be thankful that people have invested a lot of time and pro-bono work in helping the Plone Foundation set up a constructive agreement.</p>
<p>If you are being told you can't sign, at least try to make the case. Ask others how they've overcome such obstacles. Most companies have ways and means if you only try.</p>
<p>Finally, although Plone's contributor agreement covers the bulk of code in the Plone release, it is not necessary to sign one to commit code to the Collective subversion repository, or to contribute in other ways.</p>
<h3>5. Someone else will fix it for me</h3>
<p>In economics, this is known as the "free rider" problem. If we all had to pay the police directly for fighting crime, chances are an insufficient number of people would pay, since crimes prevented in your neighbourhood benefit you equally whether you paid the policemen who prevented them yourself, or only your neighbours did.</p>
<p>Some projects have attempted to address this in the same way that governments do when they tax citizens and use the revenue to fund public services (and duck houses): one company or organisation tightly controls development and charges some or all users of the software a fee to use the software or become certified solution providers. Some of that revenue is then ploughed into development.</p>
<p>Plone doesn't follow this model, and never will. You should be thankful. You have an opportunity to participate in a truly democratic process, to be part of a mature, open and friendly community, to have your voice heard and directly influence the future of the platform. You can bet your business on a technology, safe in the knowledge that many others have before you, and no-one can decide they want to squeeze you out of the market by denying your rights to the software. This is true open source. It's pretty amazing. You owe it to yourself to be part of it.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-12-12T14:47:28Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/dvcs-baby-steps">        <title>DVCS baby steps</title>        <link>http://www.martinaspeli.net/articles/dvcs-baby-steps</link>        <description>Thoughts on Git and Mercurial</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>Thoughts on Git and Mercurial</p>
<p>Over the past few days, I've <a title="I'm a cutting edge technologist, but please don't make me learn anything new" class="internal-link" href="im-a-cutting-edge-technologist-but-please-dont-make-me-learn-anything-new">finally</a>&nbsp;taken the time to learn a bit more about Distributed Version Control Systems (DVCSs). In particular, I've read both&nbsp;<a class="external-link" href="http://hgbook.red-bean.com/">The Mercurial Book</a>&nbsp;and <a class="external-link" href="http://progit.org/">Pro Git</a>, as well as a few blogs and tutorials.</p>
<p>Most of the time, I work with Subversion, both in development projects at work, and when I contribute on Plone. Subversion is a VCS, but not a DVCS. There is a single, centralised repository, from which everyone checks out a local working copy of a given project. Subversion tracks any number of files, co-ordinating updates by multiple authors, and allows you to roll back to previous versions should you need to. It deals with merges, branches and conflicts, too, although not in quite as sophisticated a way as a DVCS.</p>
<p>DVCSs are different. Typically, there is no central repository. Everyone has a full copy of the repository, including the full revision history. Most commands are local, and changes need to be explicitly pushed to a remote server. Branches are a lot cheaper, and merges are easier. A DVCS supports a number of workflows (which can be mixed on an ad-hoc basis). You can have a single maintainer of the canonical version of a given project "pulling" from others' published repositories, or a model whereby people submit patches exclusively by email. There doesn't even need to be a canonical version at all, just a number of people with their own sandboxes, sharing code in a completely decentralised manner.</p>
<p>Mercurial and Git are both very powerful systems. Of the two, I prefer Mercurial, mainly because it seems a little easier to work with. Git is probably a bit more powerful (I like the "stash" feature in particular), but whilst the basic commands are relatively straightforward, I found myself worried that I'd need to read the documentation many more times before it became comfortable. Some features, like submodules, seem downright confusing, and there are some niggling inconsistencies in the way the command line interface works. Of course, it helps me that the Mercurial commands closely mimic those of Subversion.</p>
<p>But would I switch to them wholesale? Perhaps, but not yet. The DVCS model, and the enhanced support for branching and merging, is certainly attractive. However, I worry that the fundamental DVCS concepts are just a little too complicated. I normally have to teach version control basics (with Subversion) to the people who join my project teams. It's not always easy for people to grasp, and harder still to get into good working habits. Subversion at least simplifies the process, in that it can be explained by the analogy of a filesystem with history. There is very little "magic" going on. For example, a "tag" is just a copy of the code in the "/tags" directory, nothing more, nothing less. You can understand how you'd do it all manually if you had to.</p>
<p>By contrast, I think it would be difficult to explain a DVCS without reference to the underlying data model. Both of the books I read made heavy use of diagrams and examples to illustrate even pretty basic concepts, and felt it necessary to explain the repository data structures in some detail. You need to build a mental model that includes a commit history with branches and merges. You need to understand concepts like "heads", "tips" and "parents". The history is not even static - it can be changed, for example by "rebasing". If you don't have a degree in computer science or at least a good understanding of with such concepts as abstract data structures (e.g. linked lists) and pointers, as well as familiarity with the UNIX tool chain for managing diffs and patches, I think you're going to struggle to pick up a DVCS in an hour or two (the time I normally have to get people started). And if you don't understand the DVCS you're using well enough, I fear that the experience could become very frustrating. I don't get the feeling that either system is particularly conducive to trial-and-error. As soon as people start asking, "what the heck happened to my file?", I think you've lost.</p>
<p>This is a classic "power vs. simplicity" tradeoff. The very concepts of decentralised version control, branching, and merging are complex. There are a lot of edge cases. There are a lot of real-world use cases that require sophisticated solutions, especially when you start getting into projects that have a large number of contributors or a high volume of contributions.</p>
<p>The good news is that even if you're working with a project that uses Subversion for its repository, you can use both Git (via git-svn) and Mercurial (via hg-subversion) as a "super-client" for Subversion. You can have local commits and use the various DVCS tools, and then "push" your changes up to the Subversion server, which won't know the difference between this and any other client. I intend to start trying that out with Mercurial and hg-subversion shortly.</p>
<p>The next time I start a new/non-Plone project, I may also try to use Mercurial (or Git) only. And if I do, I'll almost certainly use <a class="external-link" href="http://bitbucket.org">BitBucket</a> to do it. BitBucket (and its Git equivalent, <a class="external-link" href="http://github.com">GitHub</a>) is a free (up to a point, but you can buy plans with more data allowance) service that enables anyone to set up Mercurial repositories for any number of projects.</p>
<p>The interesting thing, though, is that BitBucket and GitHib are a little bit like Facebook for programmers. Whereas traditional "project hosting" services such as <a class="external-link" href="http://code.google.com">Google Code</a> (which supports both Mercurial and Subversion) is centred around the <em>project</em>, BitBucket and GitHub are centred around the <em>people</em>. That is, they both host repositories on URLs like http://&lt;service&gt;/&lt;person&gt;/&lt;project&gt;. There is no single location for a given project. Instead, you are encouraged to create your own fork of someone else's repository (there's even a button on the web GUI) if you want to work on that project, and then either request access to push your work back yourself, or ask the maintainer to pull it into their working copy.</p>
<p>I don't think this is the correct model for all projects. I suspect it is best suited for small, ad-hoc projects, personal projects, or projects that are not yet off the ground. In fact, I think this model could be actively damaging for a large, co-ordinated project such as Plone. Of course, you don't have to use this completely decentralised model, so that is not an argument against Git or Mercurial in itself.</p>
<p>I would say, though, to those working on Plone projects: please continue to use the shared infrastructure we already have, until such time that we are all ready to move to something different, together. Although it is not quite the same, working with a Subversion repository via Mercurial or Git is pretty powerful and gives you most of the benefits of having a fully DVCS-managed environment. By putting things in the places where other people are most likely to find them, and allowing those not ready to make the switch to work with the tool chain with which they are already familiar, you will encourage contributions and aid the cohesiveness of the community. When it comes to "core" Plone code, there is also a legal aspect to consider, in that the Plone Foundation owns code in the Plone repository, and that this code is protected by the Plone Contributor Agreement. That is an important factor in protecting Plone's intellectual property, and not something to be taken lightly.</p>
<p>Do I think Plone will eventually move to using Mercurial or Git? It seems a bit unlikely, given the amount of code we have in our Subversion repositories. I'm also worried that some of our integrators would find the Mercurial or Git learning curve a little bit too steep. We need to keep the barriers to contribution as low as possible. However, there clearly would be benefits too, so we should have a debate and see what the community wants. It seems a lot of other projects are moving to a DVCS, which is a sign that we should look into it, too. And in the meantime, I would encourage everyone to try out Mercurial or Git, or both.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-12-14T01:45:23Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/im-a-cutting-edge-technologist-but-please-dont-make-me-learn-anything-new">        <title>I'm a cutting edge technologist, but please don't make me learn anything new</title>        <link>http://www.martinaspeli.net/articles/im-a-cutting-edge-technologist-but-please-dont-make-me-learn-anything-new</link>        <description>A paradox exposed</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>A paradox exposed</p>
<p>If you read this blog, you are probably a technologist, and quite possibly a software developer. If so, ask yourself this: When was the last time you learned something truly new? Not just another aspect of what you already know best (say, a Python developer reading up on a module in the standard library he hasn't used before), but something that puts you out of your comfort zone and stretches your ability to learn (like that same developer tackling Erlang).</p>
<p>If the answer is more than a month ago, stop reading and think about your prioritises for a moment. And think about how you came to be a technology professional in the first place.</p>
<p>Technology is all about learning new things. I remember when I first started playing with my mother's IBM 386 PC with MS-DOS 6 (yes, I know I'm young). I was terrified and excited. When I learned about DOS batch files, I thought I could build just about anything. With GOTO. And SHIFT. When I borrowed my friend's father's Visual Basic 6 manuals, I read them cover to cover and tried to build a better text editor. Oh, how I have learned the error of my ways, but that was an exciting time. It was how I got into technology, and became interested in programming. Half a dozen programming languages later, it's still one of my most important hobbies, and the cornerstone of my professional career. If I hadn't had the desire to learn new and unfamiliar things, I would probably have been an accountant. Yipes!</p>
<p>A colleague and friend once told me: if you're in technology, you're an absolute idiot if you're not spending at least 30 minutes every day learning something new. Your knowledge today is most likely obsolete in a few years' time. But more importantly, the aptitude for learning and passion for acquiring new skills is probably your most valuable professional attribute. Without it, you're just someone who learned a trade and now applies it day in, day out. There's nothing wrong with this, but it certainly limits your ability to grow professionally.</p>
<p>I think we all know this. I think we all remember the excitement of learning new things. And yet, programmers can be some of the most stubbornly set-in-their-ways people you'll ever meet. This goes beyond the pointless "religious" debates (vi vs. emacs; object oriented vs. procedural). It even goes beyond programming languages and paradigms. It goes right down to the tools we use to write our software.</p>
<p>I was prompted to write this by a discussion on the Deliverance mailing list about moving the code to <a class="external-link" href="http://github.com">GitHub</a> or <a class="external-link" href="http://bitbucket.org">BitBucket</a>, two "social coding" portals that use Git and Mercurial for version control respectively. The aim was to make it easier for people outside our community to contribute, and to present a bit more an outward face. Some developers also preferred these tools over Subversion, which is what we use now.</p>
<p>In response, one of the contributors basically said he wouldn't be interested in contributing if it moved away from Subversion. I don't know his reasoning, but for a moment I found myself in agreement. In fact, I've berated people who move code away from a Subversion repository to a Git or Mercurial one before (although not only for the reason I'm about to describe - more on that in a future blog post). I'm extremely comfortable with Subversion. It fits my brain and I use it on a daily basis. Having to learn something else sounded onerous. My urge was to resist it, so as to keep the project well within my comfort zone.</p>
<p>But then I thought: how utterly stupid a reason. I learned Subversion at one point too. Why should this be any different? Maybe Git or Mercurial really would be better? I didn't know them well, so I had few factual arguments. My resistance was instinctive: For the love of God, don't make me learn anything new!</p>
<p>The same applies everywhere. People freak out when you present them with a new framework or tool. I've spent weeks - if not months - building frameworks that I believe in, only to have people shoot it down because it's "one more thing to learn". (For sure, an excessive learning curve can be a big problem, but many of these "new" things are in fact about making old things easier for new people to learn). Programmers build up irrational hatreds for all sorts of things: XSLT (XDV, anyone?). XML. Java. In a grown up community like Plone's, we don't see too much of this (though perhaps it is just displaced by apathy), but peruse Slashdot or Reddit one evening, and you will find hordes of kids born ten years after <a class="external-link" href="http://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1260028483&amp;sr=8-1">K&amp;R</a> &nbsp;was written proclaiming the virtues of C and refusing to even look at C++, let alone Java. They learned that from someone.</p>
<p>This problem is of course not unique to software development, but I think it is a little hypocritical at times. We claim to be on the cutting edge of technology, and yet we often engage in great amount of navel-gazing. It leads to NIH (Not Invented Here) Syndrome. Rather than learn about what others have done and build on it, we prefer to build our own, with our own tools, designed in our own way, exactly the way we've always done it.&nbsp;Get off my lawn,&nbsp;you young whippersnappers!</p>
<p>What can be done about this? The advice about taking half an hour of each day to learn something new is a good one. After the Deliverance debate, I decided I was long overdue to learn about DVCS and found the excellent <a class="external-link" href="http://hgbook.red-bean.com/">Mercurial Book</a>, which I read online. I'm now reading <a class="external-link" href="http://progit.org">Pro Git</a> to compare. Learning new things is fun, and makes you a better developer. The ability to draw insights from a number of disparate sources is probably one of the main things your clients pay you for (or your boss values you for), whether you're a consultant, a developer or some other kind of professional. So keep growing your list of sources.</p>
<p>But we must also recognise some of the reasons people become insular. There are so many technologies and tools out there, one can't hope to learn about them all. "Choice overload" instinctively makes people retract to the familiar. Once we got jobs and families, we stopped having time to just surf the internet looking for "cool new things". It can also be hard sometimes to pick out the things truly worth investing time in.</p>
<p>Here, you can help your friends. When you find something worth learning about, Tweet liberally and blog about it. Pick out the best summary you can find, and show it to others. It is much easier to get started when someone gives you a recommendation and helps you filter out the noise. And if you've just built the next great piece of technology, you could do worse than to make it easy and fun to learn.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-12-05T15:53:45Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/of-babies-and-bathwater-or-why-i-love-the-zope-component-architecture">        <title>Of babies and bathwater (or: Why I love the Zope Component Architecture)</title>        <link>http://www.martinaspeli.net/articles/of-babies-and-bathwater-or-why-i-love-the-zope-component-architecture</link>        <description>In defence of one of the great Python frameworks of the past decade.</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>In defence of one of the great Python frameworks of the past decade.</p>
<p>I went on holiday for four days. When I came back and opened Thunderbird, I saw that there were 97 new emails in the zope-dev newsgroup (mailing list). Controversial debate, here we come.</p>
<p>This particular debate was instigated in reaction to an earlier thread by Chris McDonough, who was trying to bring some BFG API improvements back up to zope.component. I always value Chris' opinions on design and development - few people are as committed to software maintenance, programmer friendliness or high-quality documentation as he and his colleagues at Agendaless are. And even though Chris' proposal didn't quite fit in the end, he inadvertently re-kindled a debate about how we can improve the API of the Zope Component Architecture (ZCA), i.e. <a class="external-link" href="http://pypi.python.org/pypi/zope.interface">zope.interface</a> and <a class="external-link" href="http://pypi.python.org/pypi/zope.interface">zope.component</a>.</p>
<p>Recently, there's been a sense of backlash against the ZCA. It's too hard. It's too Zope-specific. It breaks expectations and has a sub-optimal API. This has sometimes spilled over into a generic mistrust of frameworks. Frameworks are too hard. They're too application-specific. Many of them are too esoteric and break expectations in one way or another. We all just want to write Python code with simple functions and simple data structures and maybe a decorator or two, dammit. None of the complexity that requires us to read documentation and learn new concepts.</p>
<p>Don't get me wrong. Many of these criticism are justified in part. ZCA over-use is a common affliction in some parts (and I shall certainly take my share of the blame). Over-generalisation is the enemy of discoverability. The ZCA, like all inversion-of-control frameworks, encourage separation of concerns to the point where you can't always find the implementation for something without understanding what registrations are currently in effect. Ian Bicking used the term "non-locality" of code, which is definitely something that ZCA espouses - even encourages - and this comes at a cost.</p>
<p>And yet. The ZCA rocks. It's an incredibly advanced and powerful way to build software. When I work in other environments (or other programming languages), I often miss it, and I sometimes end up re-inventing parts of it for my own needs. Zope, Plone, Grok, BFG and the other frameworks that use the ZCA constitute some of the largest and most complex codebases in the Python world. They are also some of the most extensible, customisable products in existence - probably in all of software. The ZCA sits at the heart of that, and has (ignoring a huge amount of legacy code that clouds the picture) facilitated a type of consistency in extensibility that is difficult to emulate.</p>
<p>There is no doubt also that the ZCA adds complexity. It demands that you swallow its core concepts up front (interfaces, adapters, utilities, events) and get to know them pretty well. It has a few nooks where people can do crazy things, usually doing as much harm as good.</p>
<p>But my take on it all is that the "framework backlash" is wrong. It seems to happen when people who've been working on high-complexity software starts building small and simple things, using elegant frameworks like BFG or Pylons. A whole application is just a couple of functions, a few dicts and lists, and maybe a page template or two. Why can't all of our code be like this? But of course it can't. When you start building software that is tens of thousands of lines of code, you need architecture, you need formalisms, you need common patterns and repeatable techniques. You need to cater for teams that change, skills that vary and codebases that get so big no one person can manage it all at once. You need to consider how your code will evolve, because the code you wrote first will be in dire need of refactoring by the time you're half way through your project.</p>
<p>That doesn't mean the ZCA is right for all situations. Rather, I'd argue that learning to use the ZCA effectively is a bit like learning a new programming language on top of Python. You need to "get" those concepts, just like you need to "get" functions, classes, for loops and if statements. You need to gain some experience and learn some common patterns and techniques. In short, you need to invest some time and become familiar with your tools.&nbsp;That investment will pay off for a big project, or a complex one. It probably won't if you're building a small, stand-alone application. And for the huge grey-zone in-between, you're going to have to make informed decisions.</p>
<p>For the ZCA itself, there is clearly an opportunity right now to evolve, and a degree of energy poised to make this happen. My personal wish-list would be the following:</p>
<ul><li>Improve the documentation. Chris McDonough pointed out that when you try to explain something, you'll find holes in your concepts.&nbsp;<a class="external-link" href="http://plone.org/products/dexterity/documentation/manual/five.grok">This tutorial</a>&nbsp;is my latest attempt at explaining the ZCA concepts - it may be helpful, either if you'd like to learn more about the ZCA, or if you'd like to try to write canonical ZCA documentation (in which case, feel free to borrow liberally).</li><li>Document clearly when the ZCA adds value, and when it may be overkill.</li><li>Improve the API, but don't sacrifice backwards compatibility and don't break existing documentation. We've had a long education process to date, getting people familiar with the ZCA concepts. We need to avoid the kind of damaging mega-confusion that surrounded the whole Zope 2 / Zope 3 / Five debacle. Giving a new name to an existing concept or a new signature to an existing method is the kind of thing you do only to spite your users. Live up to past decisions, even if they weren't optimal, and find a pragmatic way forward rather than wish every effort can be turned into "green fields" development.</li><li>Build better tools for introspection and debugging. The ZCA maintains a lot of runtime state about components, which could be used more effectively to help people see which registrations are in effect.</li></ul>
<p>And finally, some advice for projects, such as Plone, that use the ZCA for extensibility and inversion-of-control : Don't let the ZCA be the first API that people see, and don't assume everyone has yet reached ZCA mastery. Think of the ZCA as a building block, not the end goal.</p>
<p>BFG does this very well. A particular feature may be implemented using the ZCA, in order to be allow different policies to be swapped in, say. But for the casual user of the framework, there is a helper method which performs the necessary ZCA lookups and presents a domain-specific, documented API for a particular purpose. And it <a class="external-link" href="http://docs.repoze.org/bfg/1.1/designdefense.html">documents</a> its design decisions. That's maturity for you.</p>
<p>We're trying to do something similar with <a class="external-link" href="http://plone.org/products/dexterity">Dexterity</a>&nbsp;and the ecosystem of tools around it. The same will hopefully be true&nbsp;for other technologies as we move towards Plone 5 and what we hope will be a much improved integrator learning curve. Stay with us. The ZCA certainly will.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-12-01T15:30:07Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/using-hudson-ci-for-plone-projects">        <title>Using Hudson CI for Plone projects</title>        <link>http://www.martinaspeli.net/articles/using-hudson-ci-for-plone-projects</link>        <description>Butler meets Chuck Norris</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>Butler meets Chuck Norris</p>
<p>In a previous life, I used the <a class="external-link" href="http://www.hudson-ci.org/">Hudson Continuous Integration</a> server for Java projects. If you haven't heard of Hudson before, it's like Buildbot, but with a butler. It is also more user friendly and visually appealing.</p>
<p>If you haven't used continuous integration before, now is a good time to start. In any project, you should have a CI server set up that periodically runs your automated unit and integration tests. That way, you are notified immediately of any regressions you may have caused. This is particularly important in a team situation where you have multiple programmers working on the same code base. With CI, you can pinpoint which checkin broke the build (Hudson will tell you down to the revision, checkin message and author) and rectify it quickly.</p>
<p>Hudson will poll your source control system or react to external
events (like you clicking a button or even an IRC message, if you have the right plugin installed), perform a build, and collect test
results. It can distribute tests across several nodes, run builds in
parallel, and integrates nicely with tools like Selenium and JUnit. Oh, and it can post your build status to Twitter.</p>
<p>Hudson is probably better known in Java circles, and has a bit of a Java slant, but the latest version is really rather nice. It's about as simple to get up and running as it could be, and it has a number of plugins, including ones that add the ability to execute Python scripts, various monitoring and reporting options, and that all-important Chuck Norris plugin:</p>
<p class="callout">"Chuck Norris doesn't need a debugger, he just stares down the bug until the code confesses."</p>
<p>And now, you can use it for your Plone project. Well, you always could, but <a class="external-link" href="http://pypi.python.org/pypi/collective.xmltestreport">collective.xmltestreport</a>, a package I just released, provides a test runner that can output the types of XML test reports that Hudson expects to be able to produce pretty graphs and trending information about your tests.</p>
<p>It's pretty easy to set it all up. Download Hudson and start it up like so:</p>
<pre>$ java -jar hudson.war
</pre>
<p>That will run Hudson on port 8080. See the <a class="external-link" href="http://wiki.hudson-ci.org/display/HUDSON/Use+Hudson">Hudson documentation</a> for more details on alternative ways of running the web server.</p>
<p>Then, log into the Hudson console and go to the "Manage Hudson" screen. Install a few plugins. I got plugins for:</p>
<ul><li>Subversion<br /></li><li>Monitoring</li><li>Plotting (graphing)<br /></li><li>Selenium</li><li>Release</li><li>Tagging</li><li>Dashboard<br /></li><li>Chuck Norris</li></ul>
<p>The last one is particularly important, of course.</p>
<p>Then, create a new job. I used the "free-style" build template, specifying a Subversion URL to check out a buildout, a build trigger based on SCM polling, and an "execute shell" build step like:</p>
<pre>cd dev # name of buildout
bin/develop up # update mr.developer sources
bin/buildout # re-build
bin/test -x -s plone.dexterity # run tests
</pre>
<p>The build in question is the Dexterity development build. This has a [test] part which looks like this:</p>
<pre>[test]
recipe = collective.xmltestreport
eggs = 
    plone.dexterity
# other eggs in this list not shown
extra-paths = ${zope2:location}/lib/python
defaults = ['--exit-with-status', '--auto-color', '--auto-progress']
</pre>
<p>The recipe is a special version of <a class="external-link" href="http://pypi.python.org/pypi/zc.recipe.testrunner">zc.recipe.testrunner</a>, which installs the test runner from collective.xmltestreport. This is the runner that adds support for the -x command line option seen in the shell commands above.</p>
<p>Back in the Hudson configuration, enable "publish JUnit test results report" and set the report path to "dev/parts/test/testreports/*.xml". Here, "dev" is the name of the buildout). "parts/test" is created by buildout, and the "testreports" sub-directory is created by the collective.xmltestreport test runner when the -x command line option is given.</p>
<p>Now, activate a build (or wait for Hudson to do it for you). You can watch the console in real-time performing the build happen, and then explore test results and build trends afterwards. It's pretty intuitive and you can get a lot of information about when a test started failing, how long it has been failing for, and what has been happening to your code since.</p>
<p>There is of course a lot more to Hudson. You can set up various notifications, and create multiple builds that depend on one another. You probably also want to set up some notifications (e.g. via email) when the build breaks. We also used to have Hudson jobs for things like resetting the test database (which we would run ad-hoc) and performing a health check on a live website (which we would run every ten minutes, and then all hell would break lose when it failed).</p>
<p>If you need to see what Hudson is doing, look in ~/.hudson. In particular, you will find the source checkout in ~/.hudson/jobs/&lt;name&gt;/workspace, unless you specified an alternative workspace location (which is useful if you want two builds to work on the same checkout, though you need to be a bit careful).</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-11-07T16:48:43Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/using-grok-techniques-in-plone">        <title>Using Grok techniques in Plone</title>        <link>http://www.martinaspeli.net/articles/using-grok-techniques-in-plone</link>        <description>A new manual, which may teach you a think or two about Zope as well</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>A new manual, which may teach you a think or two about Zope as well</p>
<p><em>Update: Gave credit to Godefroid Chapelle, who started five.grok with Lennart Regebro.</em></p>
<p>For a while now, thanks to the efforts of people like Sylvain Viollon, Godefroid Chapelle, Lennart Regebro, Vincent Fretin and others, we've been able to use <a class="external-link" href="http://grok.zope.org">Grok </a>techniques to register Zope adapters, utilities, event subscribers, views, viewlets, and so on in Zope 2 and Plone. This helps lower the Zope learning curve by largely taking ZCML out of the picture for component registration, allowing you to keep the code that makes up a component and the "wiring" for that component to be usable in the Zope Component Architecture (ZCA), together in one place.</p>
<p> <a class="external-link" href="http://plone.org/products/dexterity">Dexterity</a> builds on this with additional grokkers, and the Dexterity <a class="external-link" href="http://plone.org/products/dexterity/documentation/manual/developer-manual">documentation</a> recommends using Grokkers for more basic Zope component registrations. You don't need to be using Dexterity to benefit from five.grok, however.</p>
<p>Today, I've published a <a class="external-link" href="http://plone.org/products/dexterity/documentation/manual/five.grok">detailed manual</a> on using five.grok in Zope 2 and Plone. This also explains the fundamental Zope Component Architecture concepts with examples and analogies, so if you are a little rusty on your ZCA ABCs, and you haven't got <a title="Professional Plone Development" class="internal-link" href="../plone-book/professional-plone-development">Chapter 9</a> handy, you may find it a good read.</p>
<p>I've also openly invited the Grok project to plagarise this manual for their own purposes, should they find it useful.</p>
<p>You can find the manual <a class="external-link" href="http://plone.org/products/dexterity/documentation/manual/five.grok">here</a>.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-11-09T00:43:10Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/the-naming-of-things-package-names-and-namespaces">        <title>The naming of things: Package names and namespaces</title>        <link>http://www.martinaspeli.net/articles/the-naming-of-things-package-names-and-namespaces</link>        <description>Some practical advice on package naming for Plone products</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>Some practical advice on package naming for Plone products</p>
<p>Over the past year or two, the transition from "products" to "eggs" has taken hold. Almost no new third party products (and very few new releases of old products) are released as product tarballs, and it seems almost everyone is using buildout and eggs to distribute their code. This is good, and helps bring Plone's packaging story in line with that of other frameworks.</p>
<p>With eggs come namespace packages: the ability to organise code into namespaces. We see this in Plone itself, with namespaces like <em>plone.*</em> (packages like <em>plone.memoize</em> or <em>plone.browserlayer</em>), and nested namespaces like <em>plone.app.*</em> (<em>plone.app.portlets</em>, <em>plone.app.contentrules</em>) or <em>plone.portlet.*</em> (<em>plone.portlet.collection</em>, <em>plone.portlet.static</em>). A number of other "shared" namespaces have also popped up, such as <em>collective.*</em>, <em>five.*</em>, <em>z3c.*</em>, and so on, as well as namespaces used by specific organisations (<em>jarn.*</em>, <em>slc.*</em>).</p>
<p>Unfortunately, the rules for the use of namespaces are a bit fuzzy, and sometimes cause confusion. It's also difficult (and inadvisable) to change packages names after a package has been released and there are uses "in the wild", so getting the name right the first time is important. I'll try to articulate some of the unwritten rules here.</p>
<h2>Egg name vs. Package name</h2>
<p>First of all, a small, but important point: For Plone packages, we tend to have a one-to-one mapping between package names and egg names, but this is by no means required.</p>
<p>For the avoidance of doubt, the egg name is the thing that is registered on <a class="external-link" href="http://pypi.python.org/pypi">PyPI</a> and listed in the <em>buildout.cfg</em>&nbsp;<em>eggs</em>&nbsp;option or a <em>setup.py </em><em>install_requires</em>&nbsp;line. An egg is an archive of Python code and other resources (like documentation or images). The Python modules included in the egg may or may not be organised into packages, and those packages may or may not be namespace packages.</p>
<p>A namespace package is like any other Python package (i.e. a directory with an <em>__init__.py</em>&nbsp;file in it), except that when a package is declared as a namespace package (which involves a couple of lines of boilerplate in the <em>__init__.py</em>), it is possible to have multiple eggs provide modules and sub-packages within that package.</p>
<p>As an example, Plone depends on packages such as <em>plone.theme</em>&nbsp;and <em>plone.browserlayer</em>. Both of these put sub-packages into the the <em>plone</em>&nbsp;namespace package. If <em>plone</em>&nbsp;was not a top level namespace package, the two eggs would clash (the package(s) from one egg would effectively hide all others using the same top level package name).</p>
<p>The convention of naming the egg after the top level package is useful because it makes it easier to find code: if you are looking for the code behind the module <em>plone.theme.interfaces</em>, you know to look in the egg called <em>plone.theme</em>. It's also one less thing to worry about naming. However, this is not enforced. If you installed the <em>Paste</em>&nbsp;egg, for example, you will get a number of packages in the <em>paste.*&nbsp;</em>namespace, all distributed in a single egg. Other packages, like <em>PasteScript</em>, provide further packages in the same top level namespace.</p>
<h2>Rules of thumb</h2>
<p>There are no hard and fast rules for package naming, but there are some rules of thumb based on accepted practices from Plone and other projects.</p>
<ul><li><strong>A namespace is just that: a way to organise your code</strong>. Packages in the same namespace should be conceptually related.</li><li><strong>Top level namespaces usually relate to code ownership</strong>. This helps avoid clashes: if both Plone and Pinax had package to PyPI called <em>portlets </em>they would clash, and it would be difficult to co-ordinate package naming. By using a <em>plone.*</em>&nbsp;namespace, we can be reasonably sure that we won't have clashes.</li><li><strong>Understand the purpose of namespace before you use it</strong>. If in doubt, ask on the Plone product-developers mailing list or in the IRC chat room.</li><li><strong>Your last chance to get the namespace right is when you make the first public release</strong>. Changing package names after it has been used in the wild is a major pain and should be avoided if at all possible. Everyone who's ever tried to rename a released package have come to regret it. Changing the egg name is slightly less harmful, but will also cause a lot of confusion.</li><li><strong>For internal/customer projects, use your company name as the namespace</strong>. For example, the code written for the fictional "Optilux" chain of cinemas in the Professional Plone Development Book is all contained in the <em>optilux.*</em>&nbsp;namespace.</li><li><strong>There is no shame in releasing a package as open source even if it has an "internal" name</strong>. Witness things like <em>jarn.mkrelease</em> or <em>zest.releaser</em>. Think of it as a bit of free marketing.</li><li><strong>Only use a "shared" namespace if you really intend the code to be community owned</strong>. This is a corollary to the previous three points.</li><li><strong>Avoid using namespace packages as a way to delineate words in a package with multiple names</strong>. It may look cool to have a package called <em>plone.multimedia.tools </em>(fictional)&nbsp;but that's not what namespace packages are for (incidentally, you could use an egg name like <em>PloneMultimediaTools</em> and still use a sane package structure, but as discussed above, the convention in Plone land is to use the package name as the egg name).</li><li><strong>Avoid deep nesting - two levels is almost always enough</strong>. Some programmers have an urge to define everything in deeply nested hierarchies and end up with packages like <em>collective.generic.skel.common </em>(apologies - I'm pretty sure this is a worthwhile package with an unfortunate name). This type of name is both verbose and cumbersome (e.g. if you have many imports from the package). Furthermore, big hierarchies tend to break down over time as the boundaries between different packages blur. These days, the consensus is that two levels of nesting are preferred. For example, we have <em>plone.principalsource</em>&nbsp;instead of <em>plone.source.principal</em>&nbsp;or something like that. The name is shorter, the package structure is simpler, and there would be very little to gain from having three levels of nesting here. It would be impractical to try to put all "core Plone" sources (a source is kind of vocabulary) into the plone.source.* namespace, in part because some sources are part of other packages, and in part because sources already exist in other places. Had we made a new namespace, it would be inconsistently used from the start.</li><li><strong>Pick meaningful names</strong>. Speaking of <em>collective.generic.skel.common</em>&nbsp;- it's difficult to guess what that package may do looking at the name. Two of the four names are generic (erm...) and near synonymous. Ask yourself "how would I describe in one sentence what this namespace is for?", and then "could anyone have guessed that by looking at the name?".</li><li><strong>If in doubt, ask</strong>. The Plone product-developers mailing list is a good place to ask if you want advice on what to call things, as is the #plone IRC chatroom. See <a class="external-link" href="http://plone.org/support">plone.org/support</a>.</li></ul>
<h2>The common namespaces</h2>
<p>There are several namespace packages in use today. Below are some of the most commonly used "community" ones and their purpose.</p>
<dl><dt>collective.*&nbsp;</dt><dd>This name comes from the Collective subversion repository. A <em>collective.*</em> package is a Plone community package not intended for the Plone core. It should live in the Collective repository and be released under the GPL or another open source license. The namespace implies community ownership and invites anyone with Collective commit access (i.e. anyone who wants it) to collaborate and help maintain it. If you are writing a Plone package and you want it to be community-owned, this is probably the first namespace that should come to mind. Examples include <em>collective.xdv</em> and <em>collective.flowplayer</em>.</dd><dt>plonetheme.*&nbsp;</dt><dd>This name is used by the default in the Plone theme paster template. It should be used for Plone theme products that are released as open source.</dd><dt>plone.*&nbsp;</dt><dd>This is the main top level package for Plone core packages. A <em>plone.*</em> package should live in the main Plone repository, be GPL licensed (unless the Plone Foundation Board has explicitly given permission for an alternative license, normally BSD), and thus covered by the Plone Contributor Agreement. The name implies that this is or is intended one day to be part of Plone core. If in doubt, it's best to ask on the plone-developers mailing list before releasing a package under this namespace.&nbsp;</dd>Examples include <em>plone.portlets</em>, <em>plone.z3cform</em> and <em>plone.memoize</em>.<dt>plone.app.*&nbsp;</dt><dd>This is a sub-namespace of the <em>plone.*</em> namespace and the same rules apply. The&nbsp;<em>plone.app.*</em> namespace is used for package that are part of "Plone-the-application", i.e. strongly dependent on Plone's user interface, default content types and so on. The difference between <em>plone.*</em> and <em>plone.app.*</em> is that packages directly under the plone.* namespace should work independently of Plone as a whole, and so be re-usable by other users of Python, Zope and/or CMF. A <em>plone.*</em> package is not allowed to import from any <em>plone.app.*</em> package, <em>Products.CMFPlone</em>, <em>Products.ATContentTypes</em> or other Plone-the-application-specific packages. You will sometimes see pairs of packages - like <em>plone.portlets</em> and <em>plone.app.portlets</em> - where the <em>plone.*</em> package is re-usable outside Plone and the <em>plone.app.*</em> package provides Plone-specific integration and additions.</dd><dt>plone.portlet.*&nbsp;</dt><dd>This namespace is used for standard portlets that ship with Plone. You will also see <em>collective.portlet.*</em>. The rules for plone.portlet.* are the same as those for <em>plone.app.*</em>. The rules for <em>collective.portlet.*</em> are the same as those for <em>collective.*</em>.</dd><dt><span class="Apple-style-span"><strong>zope.*</strong></span></dt><dd>This namespace is used for core Zope Toolkit / Zope 3 packages. Do not use it unless you have written a proposal to the zope-dev mailing list and this proposal has been accepted. <em>zope.*</em> packages must live in the Zope repository, be licensed under the ZPL and be covered by the Zope Contributor Agreement.</dd><dt>z3c.*&nbsp;</dt><dd>z3c stands for "Zope 3 community". This is the Zope community equivalent to the <em>collective.*</em> namespace. These packages are normally ZPL licensed and found in the Zope repository.</dd><dt>megrok.*&nbsp;</dt><dd>This namespace is used by the Grok project for community add-ons.</dd><dt>five.*&nbsp;</dt><dd>This namespace is used for certain packages that provide Zope 2 integration for Zope Toolkit / Zope 3 packages. Examples include <em>five.grok</em> and <em>five.customerize</em>. These packages tend to live in the Zope repository.</dd><dt>mr.*&nbsp;</dt><dd>A tongue-in-cheek namespace used for development and debugging tools such as <em>mr.developer</em>, <em>mr.bent</em>, <em>mr.freeze</em> and <em>mr.git</em>. These tend to live in the Collective repository.</dd></dl>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-11-01T16:59:46Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://www.martinaspeli.net/articles/dexterity-1.0a2-released">        <title>Dexterity 1.0a2 released</title>        <link>http://www.martinaspeli.net/articles/dexterity-1.0a2-released</link>        <description>New features and even better documentation</description>     <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">    <![CDATA[<p>New features and even better documentation</p>
<p>Today sees the second release of <a class="external-link" href="http://plone.org/products/dexterity">Dexterity</a>, the less-boilerplate, more-fun, <a class="external-link" href="http://plone.org/products/dexterity/documentation">better-documented</a>&nbsp;content type framework for CMF and Plone.</p>
<p>This release includes full support for rich text fields with markup transformation and tag stripping, full support for WebDAV, External Editor and other file representations of content, as well as a number of bug fixes and minor improvements.</p>
<p>We hope you'll experiment with Dexterity in your own projects and give feedback and contributions to help close the last few remaining feature gaps with Archetypes and make the platform even better.</p>
<p>If you haven't already, take a look at the <a class="external-link" href="http://plone.org/products/dexterity/documentation/faq">FAQ</a> to learn more about Dexterity, the <a class="external-link" href="http://plone.org/products/dexterity/documentation/how-to/install">installation guide</a> to get started, and the detailed <a class="external-link" href="http://plone.org/products/dexterity/documentation/manual">manuals</a> to see how easy it is to build content types with Dexterity.</p>
]]>  </content:encoded>
     <dc:publisher>No publisher</dc:publisher>        <dc:creator>optilude</dc:creator>        <dc:rights></dc:rights>                <dc:date>2009-10-12T13:38:34Z</dc:date>        <dc:type>News Item</dc:type>    </item>




</rdf:RDF>
