Personal tools
You are here: Home NGO

NGO

March 11, 2008

Andrew Burkhalter: Sightline Daily Recap

Filed Under:

A recap of a developer's favorite features in action on the Sightline Daily Plone-powered website.

Sightline DailyYeah, I know that Jon already let the Sightline Daily cat out of the bag and every day brings ever more impressive and interesting Plone sites, but before I move onto the next project, I'll afford myself a few minutes to get nostalgic.  Thanks for humoring me.  I figure anything that consumes several hundred hours+ and a few months of your life deserves at least a blog post for posterity.  Plus, I'm happy with the result.
 

So, in no particular order, here are several of the noteworthy pieces that make up Sightline Daily:

  • I suppose the first thing anyone notices in a site is the graphic design and, *man*, is Sightline Daily tastefully done.   It's clean, skimmable, attractive, and presents a lot of metadata about news clippings in a non-overwhelming way.  A few times, I found myself mindlessly clicking around and just absorbing the niceness.  Sightline Institute managed the design process with Ryan Swarts and it's a great product.  My colleague David Glick implemented the CSS to perfection with some initial bootstrapping and work by ONE/Northwest friend Trey Beck.
  • By ONE/Northwest standards, there was a rather large team collaborating on this project.  Sightline brings ~10 content editors, bloggers, content creators, and project managers to the table.  On the implementation side, we teamed with Web Collective (they focused on the blog features and portlets mostly, while I did the daily news headline-related programming), bringing the number of programmers, templaters, specification writers, and CSSers to 8.  On top of the implementation work I was responsible for, I had great time working with my fantastic co-worker, Kelley, helping to manage the biggest team I've worked with to date.
  • I believe Jon mentioned the bookmarklet for clipping headlines, but this is fantastic.  It's the fastest method I've seen for *manually* pushing content into Plone.  Leading up to the implementation, I was a bit nervous about this piece, but equipped with a similar snippet produced for Salesforce.com by a co-worker, Steve, some inspection of the del.icio.us bookmarklet, and some Googling about, this was a cinch.  You have to see the screencast below to get a sense for how it works.  Money quotes from Sightline Daily editor Kristin Kolb were "You're saving me from carpal tunnel" and "I feel like I just received my Christmas present early" (I first demoed this in early December) upon seeing this. Awesome.  I couldn't make that up.

 

 

  • Auto-generation of related items based on a Plone catalog query for 2 relevant news headlines and 1 blog post.  The effort to navigate to and hand pick related items was too time-consuming for the editorial process, so we wrote code that takes into account key terms to use for a query of Plone's "SearchableText" index and creates references to the returned results.
  • Sightline Daily Bulk EditA wizard-esque configlet that logically steps through the entire publishing process from choosing the date for the next "edition" of news clippings through to bulk editing all the way to previewing and publishing for site visitors.  The entire process can be done outside the context of the normal Plone user interface.  The highlight is definitely the bulk edit screen (seen to the right), which allows for starring news headlines as "top picks", editing of the keywords that should be used for auto-relating items, and drag 'n' drop reordering of stories.  Kudos to Jon for brainstorming a solid, implementable specification for this that held pretty closely from mockup to implementation.
  • It's been said before, but Zope 3 brings us a fantastic event system.  The bookmarklet mentioned and screencasted above uses Javascript to get the current browser location and pre-populates the news headline with a permalink.   There's no need to slow the clipping down by forcing the editor to manually type or select the source publication as well (i.e. The New York Times or Washington Post).  Rather, site users manage a centralized list of publications (new publications are added organically over time) using ATVocabularyManager.  Using each object's permalink and Python's urlparse, we simply index the permalink's netloc for fast retrieval.  With this, we can compute and index the publication automatically.  This is where Zope 3's event system comes into play.  Because ATVocabularyManager fires off custom events upon edit and deletion of vocabulary terms, our headline's source publication stays up-to-date with some super simple event handling code.  Thanks to the kind soul that baked this capability into ATVocabularyManager, because I wasn't going to port AT-events back from Archetypes 1.5.x.
  • Once launched and under normal load, the site turned out to be unexpectedly fast thanks to Cachefu and some minimal configuration effort.
  • The site includes a nice bit of tasteful, interactive Javascript, again mostly implemented by my colleague David Glick. One can quickly expand and collapse the headlines and toggle between the days of the week. This makes the site highly skimmable.
  • Every morning, Sightline sends out the top 10 or so headlines via email.  In the past, one manual effort involved populating the site, while another involved drafting the daily email for a blast out to subscribers.  This was a flat out waste of time and when you mix in how temperamental email clients are about HTML in email, this was a drain on Sightline staff.  ONE/Northwest often uses an ASP-based email broadcasting service called WhatCounts for the "email newsletter" part of our projects.  This service provides an incredible feature called "Smartget" (and it's near identical siblings "cacheget" and "get" -- which I like to call "Dumbget").  After the morning publishing process is finished on the site, Sightline logs into their WhatCounts instance and are greeted with a 1-line email template that goes out and grabs the raw HTML contents of the following page showing the latest news.  Prefer plain text email, yeah, we did that too.  No double entry at all.  My colleague Sam, did a fantastic job of giving me a plain-old HTML template that was cluttered with the most nasty HTML tables and inline styles needed for a consist look in the wild world that is HTML email compatibility.  I don't think in HTML 4 and tables, so this was a huge boost.
  • Clean urls for news by topic, news by region, and rss by whatever.  I have an unreasonable hatred of nasty urls.  Try passing the following out over the phone http://www.domain.com/some/path/page?query_param=@value@&query_param_2=value2&template=some_template.htm.  That's not even social.  Thanks to Plone, we almost never have to worry about this.  Before this project, I had never noticed the "subpath" (update: I intended to write "traverse_subpath" here, not "subpath" -- sorry if that threw anyone off.) parameter that's available in Zope's request.  Essentially, you can add whatever directory structure onto the end of a skin-based template and it's right there for your consumption as a Python list in the request's subpath.  I do a bit of processing in a browser view and instead of things like ?topic=energy, we have the following clean, friendly urls:
  • In my opinion, Sightline's best content is their in-depth blog entries that are part of a series.  They've done great ones on bicycle neglect and the quest to go an entire year carfree.  Brian and Justin of the Web Collective put together a basic "series" content type and extended the blog entry, so that in the context of a blog post, the author can assign an entry to an existing series.  This isn't rocket science, but it works really well for Sightline's needs and the graphic design for a series object is one of the best templates on the site.
  • Tests, tests, and more tests.  I insisted before development started that because this application was so critical to the organization, because it was fairly complex with significant code interaction, and because there was a decent sized team of folks that had no clue what other developers were doing, that we needed to embrace a test driven development approach and push as much presentation logic into easily testable Zope 3 views.  I even convinced myself that we had budgeted correctly for it ... oops.  Test driven development is paradoxically both time consuming and time saving.  At the end of it all, I don't regret the decision to adopt this approach one bit.  I doubt few do.  At the time of this writing we have 399 unit tests and all of them pass but 1, which I left unfinished to remind me of a feature I couldn't get working within the bulk admin interface and therefore disabled entirely. I wanted to finish that, but it was unnecessary and I needed to move onto other scoped items.  The fact that we still have entirely passing tests after site launch for the enabled features signifies that even as we approached the looming deadline, we didn't abandon our agreed upon approach.

 

So, there you have it.  I suppose I could write another post or two covering all the lessons learned and the endless details that went into getting this site launched, but for now, I'll leave things at that.  It's best to reflect on what worked well in the end anyways.  Furthermore, I think Jon still plans to do a case study and possibly a screencast about the editorial process.  That will certainly be interesting and take a closer look at the big picture.

 

 


 

February 14, 2008

Andrew Burkhalter: In the Wild: PloneFormGen Speaking Directly to Salesforce.com ...

The Salesforce Adapter for PloneFormGen sees the light of day.

... or "So, we're hiring a database developer to help with CRM implementations ..."  But, that alternate title isn't really the point (unless you're interested ;) )

As far as I know, the following PloneFormGen "Form Folder" is the first publicly available, advertised, and production use of the Salesforce Adapter for PloneFormGen (please correct me, if I'm wrong).  If you haven't heard about this piece of code that connects Plone to Salesforce.com via PloneFormGen, you might want to start here or here

This is great for a couple reasons:

  • The particular use case (i.e. collecting applicants for an open job offering) is one that I certainly never would have thought of -- and that's the point.   Creating these shouldn't take a Plone developer.  Nor should coming up with the possible use cases.  It should be the responsibility of staff that need to build the relationships they need in order to do their work.  My colleague Steve is no slouch with CRM and Salesforce.com, but the portion of getting this on our Plone-powered site doesn't take any additional expertise.
  • It will help flush out any bugs, so that we can push onto a more mature-sounding release (i.e. final, not beta or release candidate)
  • It comes equipped with the following explanation, which I think is fantastic:
Geek FYI: this is a form built in Plone that sends your data directly to our Salesforce.com database. We'll receive a notification when that data gets created. You'll also be automatically added to a Campaign that will capture all applicants. I've got a view in the Console for keeping track of all the applicants for this position. If you understood all that, or really want to, that's a good sign...

So, um, test it out if you want...

August 11, 2007

Andrew Burkhalter: New Salesforce PFG Adapter Release Up on the Plone Software Center

Salesforce PFG Adapter 1.0 alpha 2 up on the Plone Software Center with several key usability enhancements to the field mapping user interface.

While creating a working demo for my post on Saving PloneFormGen Data Directly to Salesforce.com, I was reminded of and discovered several new irritating bugs present with the current field mapping user interface.

Jesse Snyder and I were able to pick of several of these during today's ... er, yesterdays ... Open Source Friday session and package up a 1.0 alpha 2 release. Fixes include:

  • Due to some trailing and proceeding character stripping that happens within DataGridField's FixedRow implementation, inadvertently named fields like "My Form Field with Trailing Spaces   " (spaces intentional), could never be successfully mapped to a Salesforce.com SObject field. NB: We're still using the Title of form fields as the "key" for our mapping, which has its limitations, but is easiest in this more proof of concept phase of work.
  • Because we're eliminating a user's ability to wipe away form fields by disabling DataGridField's add/remove row features (this is by design, as a "read-only" paradigm is much clearer for users), re-titled and deleted fields were polluting our available form fields for mapping user interface. We've now got code that cleans up those form fields which are unmappable to Salesforce.com SObject fields anyway.
  • We've also got a nice little, fully passing suite of 25 tests, which is starting to get into the realm of respectable for our code base.

Up next is likely to be i18n work, improving usability around a chosen SObject's required fields, and enabling the mapping of PloneFormGen's DateTimeField to Salesforce.com's Date/Time string format. 

Let us know if you come up with anything that's not currently on our todo list

August 09, 2007

Andrew Burkhalter: Saving PloneFormGen Data Directly to Salesforce.com

For this next installment in my series of posts on integrating Plone & Salesforce.com, we cover the tools useful for an integrator aiming to allow those in the content editor and site administer space (albeit the more technical ones) to integrate with Salesforce.com without ongoing developer intervention. The first post mostly covered the underlying technical infrastructure, while the second was of the integrator variety and described how to display Salesforce.com data within Plone using Zope's templating machinery.

The Background

The more I've dug into and studied PloneFormGen, the more enthusiastic I am about it as a project, concept, and code base. I think readers of this post already likely have a lot of respect for how SteveM conducts the project, but I'm also continuously impressed with the amount of flexibility that's built into the code base. In this case, I'm talking about the ability to add custom action adapters. In the NGO-space, it really doesn't get much more critical than allowing content editors to build forms that collect information from would be constituents.

Someone in the Open Source Friday crew (I believe it was Brian Gershon or Jon Baldivieso), thought up the idea of writing our own custom action adapter for PloneFormGen that stores form data directly to Salesforce.com. Seeing as we use Salesforce.com as a constituent relationship manager and PloneFormGen to do things like sign constituents up for email alerts, volunteer opportunities, and events, cutting out the extra data entry is ideal.

In PloneFormGen's SaveDataAdapter and FormMailerAdapter we have a perfect example of an incredibly useful action adapter and what it would take to create our own for PloneFormGen. In addition, we already have Salesforce Base Connector providing a bridge, via beatbox, to Salesforce.com via its SOAP API. With these pieces in place, creating our Salesforce PFG Adapter was significantly easier.

Setting it all up

First, make sure you're all caught up with the setup from the previous post (you can stop when you get to the section titled "The Code"). Once you've stepped through that, it's just a matter of getting the dependencies needed for Salesforce PFG Adapter. These include:

  • PloneFormGen
  • Scriptable Fields (bundle)
  • Salesforce PFG Adapter
  • DataGridField - At the time of this writing, you need a particular branch from the Archetypes subversion repository. The following within your Products folder should do: svn co https://svn.plone.org/svn/archetypes/MoreFieldsAndWidgets/DataGridField/branches/1.5-RC1 ./DataGridField. Hopefully, that won't be the case in the future.
Alternately, you can grab the development bundle for testing with the following:
svn co https://svn.plone.org/svn/collective/PloneFormGen/adapters/salesforcepfgadapter/bundles/ ./

Once you have all these items, restart your instance and use the quick installer to add Salesforce PFG Adapter as shown below (this will ensure that all dependencies are also added):

Installing SF PFG Adapter

Salesforce PFG Adapter in Action

This is all hypothetical, but let's say you run a website that encourages users to submit information about upcoming concerts featuring local artists in an effort to market regional arts. Your goal might be to display this in a calendar on your site. This alone, would not be reason enough to integrate with Salesforce.com, as we've already got the event content type available in Plone.

However, to add a twist, let's say you also want to award prizes to those that submit the most events, send users annual appeals to donate to your organization, and use the events most frequently submitted to determine where you should be doing advertising for your organization. The logic of these tasks already live in your CRM. Something along these lines would be a pretty common nonprofit story and would require one to do a lot of custom programming with Plone. A better option would be to integrate your Plone site with an existing Salesforce.com application.

If you've got PloneFormGen, you might setup the following form (it's a bit unrealistic, but you get the idea) for your site:

The full unpopulated form

By default, you can get this emailed to you. But, that introduces the boring, error-prone manual data entry problem when you want to get this into your CRM. With Salesforce PFG Adapter and a standard Salesforce.com instance, we can take care of this data directly.

I deliberately created a more complicated example to highlight the capabilities of PloneFormGen and our Salesforce PFG Adapter, but let's start with the basics.

First and foremost, we have 3 fields (first name, last name, and email address) that are not intended to be a part of the event object itself. Remember my use case above where I describe needing to send out annual appeals to all those submitting events, thus encouraging them to donate to your organization. We use these fields to build up our pool of engaged Salesforce.com contacts.

Using the add new item menu on our Form Folder, we add our first Salesforce PFG Adapter.

Adding a Salesforce PFG Adapter

The title is unimportant. The "Salesforce Object Type" field however presents a list of eligible SObject types your Salesforce.com instance has to offer. I choose contact in my example.

Choosing Contact Adapter

From there, we hit next until we get to the "Field Mapping" section of our Salesforce PFG Adapter. This is where things get interesting. Using the DataGridField, we present a mapping-like UI for choosing which Form Fields should be associated with their corresponding SObject fields. The drop down list of SObject fields are limited to only those associated a Contact, the chosen SObject type on the first screen of the created Salesforce PFG Adapter.

The following screen shot shows how I mapped my contact-related form fields:

Contact Field Mapping

Next, we disable the default enabled Form Mailer Adapter and ensure that our Contact Adapter is selected.

Disable the Email Adapter

A quick test of the form, with the following data...

Create the First Contact Fields

... yields a new contact in Salesforce.com:

First Contact in Salesforce

At this point, nothing is happening with the remainder of the form data. This is by design. You may choose to retrieve the rest of the form data with a different adapter. Lo and behold, this is what we want to do :)

After adding another Salesforce PFG Adapter to our Form Folder and providing a title, we choose the Salesforce.com "Event" SObject type:

Event SObject type

We then provide a mapping of those form fields we want associated with the newly created Event object:

Event Field Mapping

Going back to our form we now fill out the entire form with data from a fictitious user for an upcoming show I'm looking forward to attending :) ...

The Full Populated Form

In the interest of full disclosure, the Event SObject is actually one of the more complicated data types we could choose to create. We're getting around this a bit by assuming the user will submit an appropriately formatted date/time string and an integer with the duration in minutes of the event. The real world doesn't work like this (see "What's Next?" below), but these are Salesforce.com Event object requirements. Additionally, to fulfill my use case where awards are given to those submitting the most events, I add a custom field "Submitted by Email" to my event type. The *right* way to do this would be to use a lookup to get the unique id of the newly created contact. This will require some additional features to be added to Salesforce PFG Adapter (again, see "What's Next?" below).

Heading over to our Salesforce.com instance, we now have the newly created contact:

The Contact Associated with the Event

As well as the event, which is associated with the email address of the submitting user:

The Event in SF.com

All this, with no manual data entry required. Bring on the user contributed content...

Why?

Hopefully, the motivations for this work are pretty clear. However, just for emphasis, I want to point out some of the reasons why I think this is pretty neat:

  • It's true -- Salesforce.com already provides a utility called Web2Lead that allows for easy form creation. This, however, creates a Lead SObject, which can only be converted into a new contact, account, or opportunity within Salesforce.com. This is really great. However, you may want, as in our example, to create an SObject type (like an Event) that's not allowed via a Lead or create multiple SObjects with one form.
  • No programmers are needed for simple validation -- This may be incorrect, but my understanding is that Web2Lead provides no or only simple Javascript validation of form data. With PloneFormGen, you get to choose required fields and set simple validation (i.e. is this an email address, is this a valid telephone number, is the integer between X and Y, etc.). You're also using server side validation, which cannot be bypassed when a user disables Javascript in their browser.
  • Adapters are addative - What if you want an email sent, a Salesforce object created, and the data to be saved within the ZODB. You can setup as many adapters as are needed for your form in question.
  • The form is native Plone content, non-technical users can fiddle with the labels, ordering of form fields, add HTML formatted text proceeding the form, setup default values for fields, and more with the feature-set and ease-of-use offered by PloneFormGen.

What's next?

Well, we've already released an experimental version for testing. Time is always short, but the goal is to crank out a steady stream of minor improvements based on issues that arise from use of the product. Because we're integrating with a complex and powerful system in Salesforce.com, there are many both known and unknown bugs and features that are needed. Some of the known limitations include:

  • We want to make sure that all of the form field data types work well with their logical Salesforce.com counterparts. For example, the date/time field doesn't currently work with Salesforce.com, as is exposed in my demo above.
  • Lookups on existing Salesforce.com will require work to get right. Again, it would have been ideal, in my example, to populate the CreatedById field on the Event to create a relationship to the newly created contact, rather than de-normalize (if that's a word) the event by adding the submitted by email address.
  • Required fields for the chosen SObject are not exposed in the Salesforce PFG Adapter UI. This requires a very deep understanding of a Salesforce.com configuration and the needed data types of fields you want populated with your PloneFormGen form.

With that said, when used in calculated cases, this is a very useful add-on Product for Plone. We'll be putting it through its paces on ONE/Northwest over the coming months and I'm thrilled to watch and help it improve.

July 17, 2007

Andrew Burkhalter: Plone & Salesforce.com: Using Salesforce.com as a Content Catalog

For those craving a bit more of a hands on update than my earlier background post on making Plone play well with Salesforce.com provided, hopefully this takes a step in the right direction. I'm going to be demoing the display of Salesforce.com content within the portlet of a Plone site. Credit to Jesse for helping me realize how dirt simple this is. Writing the code to do this took less than 10 minutes and that included asking a colleague a few questions about how exactly Salesforce.com works :)

The Use Case

Recently, the Executive Director of ONE/Northwest, Gideon, sent an email to staff emphasizing the use of quotes as a way to increase our credibility by allowing partners to tell our story in new potential partner circles. Being a nonprofit, think of a trusted grants manager quoted in a proposal to a new foundation or a donor quoted in our annual report. This also includes a quote about a completed web project appearing in our technology solutions section or a scope of work.

Even though we've had a Quote content type in our oft-internally-used, but not widely publicized Pigeonhole product, I thought I'd try an alternate implementation, which I see as very much complimentary, rather than competitive. For us, it makes sense to have our quotes coupled with Salesforce.com contacts. In other cases the ease and speed of doing Plone catalog lookups for related Quotes based on keywords is superior, especially as implemented in Pigeonhole as a lightweight content relation engine.

So, my colleague Steve had done some behind the scenes Salesforce.com fiddling allowing for the addition of a quote that's tied to a contact. I just added a new quote to my own contact record. See image below:

SF New Quote

But, how would we display this and other quotes in a portlet on a local copy of onenw.org...

Beatbox Setup

If you're reading this post, I'm assuming you've got a working Plone 2.5.x instance lying around, which means you've got Python 2.4 as well. You may even have EasyInstall. If not, start here. Once you've met the basic requirements, you can install beatbox from the CheeseShop with:

easy_install-2.4 beatbox
Just to prove this is working, fire up the interactive Python used by your Plone instance and type:

>>> import beatbox

Salesforce Base Connector Setup

Next you need to get salesforcebaseconnector from the Plone Collective (hopefully we'll have a 1.0 alpha 1 release in the Plone Software Center soon). Execute the following from your Zope instance's Products folder:

svn co https://svn.plone.org/svn/collective/salesforcebaseconnector/trunk/ ./salesforcebaseconnector

Upon restarting Zope, head to the ZMI and the Plone site where you'd like to talk to the Salesforce.com API.


Add a Salesforce Base Connector:

Add Salesforce Base Connector

Select the radio button and hit "Add"

Add Salesforce Base Connector, Step 2

Click on your newly added portal_salesforcebaseconnector

Configure Salesforce Base Connector

Enter information for a valid Salesforce.com account. This could be a free developer account.

Configure Salesforce Base Connector, Step 2

The Code

I chose to do this in a Zope 3 view within the DIYPloneStyle-generated product, ONENWSkin, we use at onenw.org, but as mentioned in the previous post, an explicit goal for salesforcebaseconnector was to enable integrators to easily do the same in ZPT or a Python skin script that's not necessarily filesystem-based.

After the obligatory ZCML wiring, I created a file, browser.py, at the root of my product. The following import statements and the "RandomQuotePortletView" class were all that was necessary:


from Products import Five
from Products.CMFCore import utils as cmf_utils
import random

class RandomQuotePortletView(Five.BrowserView):
"""Find recent job listings for portlet display
"""
def __init__(self, context, request):
Five.BrowserView.__init__(self, context, request)
self.sfbase = cmf_utils.getToolByName(self.context, 'portal_salesforcebaseconnector')

def getRandomQuote(self):
"""Returns a random quote from Salesforce.com in a dictionary
"""
res = self.sfbase.query(['Name','Quote_Text__c'],'Quote__c',"Usage_Guidelines__c!='Need to get permission'")

# res looks like a dictionary with a 'records' key
return random.choice(res['records'])

Of note, is the "query" method on our "portal_salesforcebaseconnector" object created at the site root in the setup above. We pass the query method a list of which fields ('Name' and 'Quote_Text__c' -- The '__c' convention signifies a custom field/object) we'd like to retrieve. The second parameter is our desired SObject, the custom Quote object, and finally we have an additional where clause which is based on our internal business rules of never showing any quotes where we don't yet have permission.

That's it! It's basically 2 lines of code (that could be collapsed into 1) within the contents of the "getRandomQuote" method and we're able to retrieve any and everything we might ever want from our Salesforce.com account.

Finally, we setup the following portlet, which defines the view, calls "getRandomQuote" on the view, and then displays the quote text for our randomly collected quote:

<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
i18n:domain="plone">
<body>
<div metal:define-macro="portlet"
tal:define="view context/@@random_quote_portlet;
qDict view/getRandomQuote">

<dl class="portlet" id="portlet-quote">

<dt class="portletHeader">
<span class="portletTopLeft"></span>
Random Quote
<span class="portletTopRight"></span>
</dt>

<dd class="portletItem odd">
<span tal:replace="qDict/Quote_Text__c" />
</dd>

<dd class="portletFooter">
<a href=""
tal:attributes="href string:$portal_url/all-quotes"
>
More quotes&hellip;
</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>

</div>
</body>
</html>

And after a few page reloads, to bypass the other quotes in our Salesforce.com instance, we see the following:


ONE/Northwest with Random Quote


Conclusion

While I only demoed the use of the "query" call to the Salesforce.com API, you can skim the methods of the SalesforceBaseConnector class or read up on the API via Salesforce.com's APEX developer wiki for a better picture of what's possible. Note: Beatbox currently talks to the 7.0 version of the Salesforce.com API (several major version behind), so everything described in the docs may not be supported.

For my money, this piece of the Plone and Salesforce.com integration landscape is probably the most ready for prime-time right now, due to the relative feature-completeness of Salesforce Base Connector. That is, if you ignore the lack of an official release :)

In the next few days, I plan to show off some work done to make PloneFormGen post directly to a Salesforce.com instance.



Jon Stahl: NPower Seattle Likes Plone

Filed Under:

Patrick Shaw, who leads NPower Seattle's Plone consulting practice, shares a few things they like about Plone:

  • You can edit your content from a modern web browser. It’s almost as simple as that - visit your site, login, click the edit button, and change your text!
  • You can quickly and easily create a news or event or “spotlight” posting that populates the home page (or any other page, matter of fact!) of your website, and then stops publishing when the event is over.
  • You can create as many pages as you want.
  • Your sitemap is always up to date
  • The search tool searches both your site and the innards of your Word and PDF documents
  • You can have “member only” sections of the website for board members or staff or for other stakeholders
  • We can implement a Plone website (where you get more of a website, a LOT more) for the same effort level as websites that were challenging for you to edit.
  • Yes, you can integrate your Plone website with Salesforce!

July 13, 2007

Andrew Burkhalter: Making Plone play well with Salesforce.com

The first in a series of blog posts covering efforts in tightly integrating Plone with Salesforce.com

BACKGROUND

Every so often myself or Jon will get a batch of emails asking for the latest status on the Salesforce Connector, since our grant from the Salesforce.com foundation was originally announced in 2006. They always come in groups.

Externally, the product has shown little sign of movement for those that don't scour (and perhaps do...) the Collective Checkins list, which can be a great way to gauge what's active in the Plone community.

As a way to respond to those that have asked or are curious, I plan to post a series of several blog posts on The Plone Blog updating everyone on the latest.

Overall, the progress has been slow and arduous, but there have been a ton of rewarding and committed conversations and discussion with the crew of us up in Seattle (includes the talented Brian Gershon of The Web Collective and RagingWeb.com and Jesse Snyder of NPower Seattle) that get together to hack on Plone and Salesforce.com integration every Friday afternoons for "Open Source Friday's". Throughout this all, a small, but interested community has formed, which is a key to ultimate success in my opinion. Things are looking up.


THE FOUNDATION

Part of the original grant money went towards paying Enfold Systems to assess the status of and cleanup the beatbox codebase. It's a Python wrapper that talks to the Salesforce.com SOAP API written by Simon Fell, who was the original architect of the Salesforce.com API. Beatbox originally lived here, but has seen several homes throughout its life cycle and the active development is now happening at Google Code. (Drop any of us a line if you want to be involved in this project.)

I don't have a ton of insight into beatbox in and of itself, as I've not dug in too deeply, but it's now got a good suite of tests, thanks again to the Salesforce.com foundation and Enfold Systems and in our testing, development, and use of it we've added better support for various core Python data types and Salesforce.com SObject field types and exception handling that can be used within your applications.

It's hard to say how exactly this will evolve, but supporting the latest and greatest Salesforce.com SOAP API (we're 2 major releases behind now) and putting this code up as an Egg on the Cheese Shop are up there. The latter will hopefully be done later this week. We'd be particularly open to help at this level of the stack ;)


BRINGING IT TO ZOPE

Thanks to NPower Seattle and one of its clients, we were able to dust off and extend a simple Zope product, salesforcebaseconnector, that merely manages credentials for a Salesforce.com instance, adds security, handles a volatile connection to Salesforce.com, and extends the Salesforce.com API to those that don't want to write filesystem code in unprotected Python space (i.e. browser views, tools, utilities, etc.) in order to import the need methods for talking to Salesforce.com.

Our primary ambition here is to make this easier for someone that's worked with the other toolkits provided by Salesforce.com that implement the exact same API methods. So even though things like "upsert" and "describeSObjects" might look foreign to a Python/Zope/Plone programmer, it should be comforting for anyone that's written code that talks to the Salesforce.com API.

This product will likely evolve fairly slowly (it's basically feature complete) going forward (there's always better test coverage, using Zope 3 appoaches, and keeping in line with the portions of the Salesforce.com API that beatbox supports) with the chance that we'll do a fairly disruptive name change before officially releasing this. We hope to bite the bullet and decide on this soon.


WHAT'S NEXT

Okay, so we've got these infrastructure pieces that work with our stack, what can we do with them? Stay tuned. Over the next couple days, I'll cover using this stuff to display desired data on your Plone site and a custom adapter we've got working with PloneFormGen.


Update:

<sarcasm>Jesse, Brian, and I sat down with the Open Source Friday marketing and branding team</sarcasm> and decided upon "salesforcebaseconnector" as the product name for the Zope wrapper to beatbox as mentioned in the section titled "Bringing It To Zope" above.

Naming is hard, but the "salesforce" portion should be obvious, the use of "base" suggests a developer/integrator focus, and "connector", as its primary focus is managing connections via the Salesforce.com SOAP API.

Finally, we intentionally chose to avoid mentions of various technical approaches (i.e. "tool" or the more modern "utility"), which were included in the original naming. Our intention is at any time to support the 2 latest major Plone releases under a consistent name, rather than allow proliferation of newly named products that implement various approaches for various Plone version. For historical releases, we'll have releases and tags in the subversion tree. This is obviously easier said than done, but that's the goal.

December 14, 2006

Andrew Burkhalter: Being the "expert" for N-TEN

Filed Under:

Transcript for N-TEN's ask the expert session on Plone now available. Plus, some recap.

On the off chance that you don't grace the Plone list for NGOs or missed the training opportunity on plone.org and weren't able to join, Joel Burton of PloneBootcamps.com and myself were asked to help N-TEN represent Plone in it's "Ask the Expert" session.  The transcript for the 1 hour session is now available.  Check it out if you're interested.


So, how did it go?

Personally, it was an honor and I rather enjoyed taking part in the session, despite feeling a bit hesitant about the "expert" labelling.   A few additional thoughts and reactions to the session follow:

  • Joel Burton, of course, was his usual brilliant self at explaining complicated concepts in the somewhat challenging IRC format. 
  • Making the previous point even more impressive ... my only complaint was continually feeling frustrated with the difficulties of articulating answers over the same format.  N-TEN was using a web-based IRC client called Gabbly, which doesn't support tab completion of screen nicks.  It's incredible how big a difference that makes to perceived typing speed :)
  • There were significantly fewer blanket "compare Plone to Drupal and Joomla" questions than I anticipated.  Those questions are fine, but without specific feature requirements and use-cases, it's quite difficult to accurately represent where Plone definitely excels from a content editor perspective (besides the fantastic usability, that is!).  Hint: it excels at everything ;^)
  • It was a lot more of pointing people in the right direction to self-serve, rather than specifically answering their questions.  The scope is obviously vast.  We made a solid pitch to get people to the already incredible and existing resources that the Plone community offers including the lists and the #plone IRC channel.
  • Hosting.  I knew it would come up and it's one of the more challenging ones to answer as it comes down to very fundamental differences to the architecture of Plone versus some other systems with which people may already be familiar.  It's great that we can point folks to Webfaction, High Speed Rails, Six Feet Up, as well as NPower -- all of which credible serve the nonprofit sector.   Additionally, it's great that your typical nonprofit can understand that the potential benefits of the Plone stack are worth the additional $10-20 USD/month, that sometimes commodity LAMP hosting has its drawbacks, and want to invest in their web presence.  Despite all of this, I still think there's an incredible opportunity for all the would-be Plone hosting providers to come into this space and greatly contribute to the story of the platform for the one off site.  
  • In talking with N-TEN's director of programs, I was told it was quite well received by attendees and compared favorably with the other sessions on Drupal & Joomla.

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: