Quick plugin to sync new cart66 subscriptions to MailPress users

I’m working on a subscription site in WordPress for a client, and they are using cart66 as the shopping cart, and MailPress as the mailing list software. I needed a way to automatically sign up new Cart66 accounts to the Mailpress users. This tiny plugin does just that:

<?php
/*
Plugin Name: Cart66 MailPress Sync
Plugin URI: http://ponderwell.net/
Description: Creates mailpress account for cart66 accounts
Version: 1.0
Author: Michael Tracey
Author URI: http://ponderwell.net
License: GPL
*/
add_action( 'cart66_after_order_saved', 'cart66ToMailpress' );

function cart66ToMailpress($orderInfo) {
  $order = new Cart66Order($orderInfo['id']);
  if($order->account_id > 0) {
  	$account = new Cart66Account($order->account_id);
  	if (class_exists('MP_User')){
  		sync_mp_user($account->email, $account->first_name ." ". $account->last_name, 'active');
  	}
  	else {
  		echo "<!-- MailPress is not available! -->";
  	} 	
  }
}
function sync_mp_user($email, $name, $status = 'active'){
		$xl = strlen($email);
		$xl = ((25 - $xl) < 0) ? 0 : 25 - $xl;
		$x = $email . str_repeat( ' ', $xl);
		if ( !is_email($email)) {
		 	return false;
		}
		
		if ( 'deleted' != MP_User::get_status_by_email($email) ){
			
		}
		else{
			MP_User::insert($email, $name, array('status' => $status, 'stopPropagation' => true));
		}
		return MP_User::get_id_by_email($email);
}

Just put this in your plugins directory, name it something like ‘cart66account2mailpress.php’ and then activate it. New accounts get signed up to the mailing list (at least for me!).

This scratched my itch on a site that I was working on, hope it works for you too. No warranty or guarantees, etc…

Google OAuth2 Class for Phil Sturgeon’s Codeigniter Spark

There’s a lovely Codeigniter Spark by Phil Sturgeon which does OAuth2 login for Facebook and GitHub and Windows Live. The spark is here. I’d set it up for Facebook a month ago, on our dev site for the Community Media Project. Then yesterday and this morning I checked the spark again, still no Google auth, so I decided to write that. After all a Google+ or Facebook account covers most people, and it feels less proprietary than just offering Facebook as a login.

So I wrote it. The code is here – it’s just a provider class which hooks into the OAuth2 framework. The only tricky bit was that Google uses POST to get the authorization token, so I chose to do that bit with cURL. DON’T TRY TO USE THIS CODE – see below for why.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class OAuth2_Provider_Google extends OAuth2_Provider {  
	public $name = 'google';

	public $uid_key = 'uid';
	
	public $scope = 'https://www.googleapis.com/auth/userinfo.profile';
	
	const google_redirect_uri = 'http://<something something>/auth/';


	public function __construct($options = null) {
		parent::__construct($options);
		$this->redirect_uri = self::google_redirect_uri;
	}
	
	public function url_authorize(){
		return 'https://accounts.google.com/o/oauth2/auth';
	}

	public function url_access_token(){
		return 'https://accounts.google.com/o/oauth2/token';
	}
	
	public function access($code) {
		$fields = array(
			'code'		=> $code,
			'client_id'	=> $this->client_id,
			'client_secret' => $this->client_secret,
			'redirect_uri'	=> 'http://newscollab.com/auth/',
			'grant_type'	=> 'authorization_code'
		);
		$fieldstring = http_build_query($fields);
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $this->url_access_token());
	    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($curl, CURLOPT_POST, count($fields));
	    curl_setopt($curl, CURLOPT_POSTFIELDS, $fieldstring);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	    $response = curl_exec($curl);
	    curl_close($curl);
		return json_decode($response, true);
	}

	
	public function get_user_info($token){
		$url = 'https://www.googleapis.com/oauth2/v1/userinfo?'.http_build_query(array(
			'access_token' => $token,
		));
		$user = json_decode(file_get_contents($url));
		return get_object_vars($user);
	}
}

So far so good. But now, belatedly, I’ve just looked at the github repository for that spark, and sure enough someone beat me to it. I could have saved a few hours by doing the basic checking more carefully before I started.

It does look like they’ve picked a slightly different approach, based on the fact that there has been some good improvement in the original spark. The constructor is cleaned up and the provider superclass now decides whether to GET or POST the token collection. That makes the code above out of date.

Sigh. Well, it was fun, anyway.

PonderTech 1: Bookmarking and Content Curation Workflow

Spark Dog owner, Clark Mackey

Guest Speaker: Clark Mackey of Spark Dog

Join us on February 2nd at 6PM EST, on Ponderwell’s Google+ page for the first official episode of PonderTech, a Google+ Hangout.  Our guest speaker in the Google Hangout will be Clark Mackey of Asheville based web marketing firm, Spark Dog.  He will be discussing leveraging your web based content in a workflow to improve your online marketing strategy.

Our Topic: “Your content is the face that launches a 1000 ships: How to building a bookmarking and content curation workflow that kicks ass.”
— Clark Mackey

The format of these new PonderTech weekly events will be a short news review, where we discuss the week in tech news as people continue to join the hangout, followed by a 10 – 15 minute talk by an expert on a tech related topic.  Then we will have open questions and discussion for the rest of the hour.  The hangouts will be recorded and shared on Youtube (and on this page) after the event.

Remember to add our G+ page to a circle before Thursday.  If you would like an email alert on Thursday morning reminding you about this episode of PonderTech, join our mailing list:



Thanks, see you Thursday!

New Service Launching: WNCAdGuild

We are preparing for a spring launch of our vertical ad network for Western North Carolina, WNC Ad Guild. Those of you following Ponderwell’s Community Media project already know that we are interested in local community news. One of the challenges in providing local news is having relevant local advertising to go along with it. We started WNC Ad Guild as a companion to our community journalism efforts, as a way for our publishers to earn money from their hard work. But as we developed it, we realized that a local advertising network can be of benefit to the entire community here in Western North Carolina. So we’re opening it up to everyone who calls this area home.

With the proliferation of large ad networks that are not niche targeted, having a network that is specifically for the mountains of Western North Carolina allows local businesses to target residents and tourist vistors who are already looking for information on our area. It allows us to help each other by keeping our cash circulating close to home and promoting businesses we already know and love. It also gives local content publishers an easy revenue stream without having to pound the streets to find advertisers. They can concentrate on creating quality content. Everyone wins.

If you are interested in becoming a beta publisher or advertiser, or you just want to check out what we are up to, visit WNC Ad Guild.

We’re Giving a TEDx Talk!

tedx logoPonderwell has been invited to present a talk at this year’s TEDxAsheville event on Sunday, November 13. Amie will be representing us up on stage, talking about the future of community media, why it matters and what we have to build to make it work. It should be a fantastic event; along with our talk there will be everything from talks on how we can use Skype to teach internationally to the experiences of Joyce Roush, the first American to donate a kidney to a total stranger. You can see the full lineup here.

If you’d like to come see it all live, we’d love to have you there. Tickets are $35 (or $100 if you want to go the VIP route), available here. The event, itself, will be at Diana Wortham Theatre here in Asheville, doors open at 1:00 pm.

If you can’t make it, don’t despair! Our talk, along with all the other presentations, will be filmed and put up on Youtube after the event, and we’ll be sure to include a link when we write up our experience.

So wish us luck…hopefully we’ll be able to convince a whole new crowd that community media really matters.

Community Media Initiative, Now That Council Has Spoken

On October 12, the evaluation committee for the Community Media Development Initiative recommended to Asheville City Council that they enter into a three year contract with Ponderwell for the development of our proposal for an online community media outlet. Council responded by voting not to fund anything. We were…surprised. Not necessarily by the decision not to fund our project, but by the lack of questions put forward about it. Opening statements from Council members indicated that we had not managed, in our initial proposal, to convey our vision of an online, community-based newsroom and what it could offer to the people of this area. Given the limited number of pages allotted for that proposal, that was to be expected. We had hoped, however, that through questions and answers we could paint a better picture of exactly what it is we want to create. Unfortunately, Council appeared to have already made up their mind. And that, as they say, is how the cookie crumbles. Or at least it was yesterday.

Today, however, we have two questions to answer: what have we learned, and where do we want to go from here?

What Have We Learned?

It takes a lot of time and effort to build a grant proposal, and it’s a nerve-wracking process when you care deeply about the idea you are proposing. It takes on a life of its own and becomes the only topic of conversation, the only topic of thought. You could take the lesson that you shouldn’t care so much. But, if anything, we feel more passionately about this than ever. Guess we’ll never learn that one.

There’s a lot of politics involved. It can be confusing and overwhelming. We’ve learned not to worry about it, and to stay focused on what we do best: programming and ideas.

Don’t expect people to understand the concept, and don’t expect them to ask questions. We’ve learned that we have to explain ourselves better and more concisely.

It’s not just us. We’ve spent years thinking about this project, and one worry going into it was that maybe we were the only ones who would feel as passionately as we do about it. But every time we started explaining it to someone, they got excited, too. They wanted to be involved, they knew other people who would want to be involved. There’s a real need in this community (as there is everywhere) for community reporting that is open to everyone and actually works.

Where Do We Go From Here?

Public consumption of media used to comprise almost exclusively print and broadcast media. At one time this meant that public access to media creation (“Public Access Media”) involved writing a letter to an editor or standing on a street corner with a placard and hoping that the television or radio journalists would report your sign or interview you. Efforts to make media creation accessible to the public therefore focused on allowing people the tools and station time required to make and broadcast their own content – a very expensive process which had the potential to reach a wide audience. Unfortunately this Public Access Media struggled for audience against slickly produced mainstream media and entrenched public viewing habits.

But broadcast media is, slowly, dying. Televisions are still more common in homes than computers, but not by much and the gap narrows all the time. People carry phones with cameras and often with internet and sometimes with video capability. Quite good quality still cameras, video cameras, and recording equipment have reached the hobbyist level and hobbyist prices. Anyone can very easily set up a blog or post their pictures to Flickr or their videos to YouTube. That’s very far from Public Access Media, however. The public’s attention is spread incredibly thin by the vast flow of internet information. There’s just no way to be noticed – it’s the same problem that Public Access Media had in the broadcast realm but magnified a thousandfold.

This is the problem Ponderwell set out to solve with our Community Media Initiative. First, we believe that for the public to be aware of its own story, the stories its members are trying to tell about what matters to them, they must have a local, community based outlet. Second it must be visible, so there needs to be a central point where these stories can be found for the community. Third, and most important, there must be a consistently high quality of material at this location. That means there must be a system, as there is in the mainstream media, for training, for editing, and for pushing the most immediately relevant and interesting material to greater prominence. Ponderwell’s idea addresses these three requirements and thus makes publicly generated media – video, sound, pictures and words – actually accessible to the community in which it is created. We believe that by making a site which is designed from the ground up to encourage a supportive community of contributors who make good content, we will make a place which the community turns to and values. A site which allows community to talk about community, to tell its stories.

This is important to us because we think that it’s the only way for a community to really function as a community, to care about itself. We’re very sorry that we couldn’t get this idea across to the City Council, but we’re not going to give up – the idea matters too much. So in the coming weeks we’ll be beginning the search for other funding, talking with more community members to gather even more ideas about how this project can serve the different facets of our area. If you have ideas you think we should know about, drop us a line, either in the comments below or through our contact page. We’re going to find a way to build this, yet, and we want all of you with us.

Community Media Initiative Full Summary

Welcome to Ponderwell’s CMDI proposal presentation page.  On Thursday, September 22, 2011, we went in to explain to a city/county committee exactly what it is we’d like to build for this community.  What follows is essentially what we told them, edited for reading purposes (and without the jitters and gulps of deep breath which were part of the actual presentation).  Feel free to read it over, and ask any questions you may have in the comments section below.  If we get the chance to build this project, we want everyone involved, so your questions really matter to us.

Oh, and if you want to see the nifty handout we prepared, you can download it here: handout-final. If you haven’t read our grant proposal, you can find that here.

Amie Tracey

Amie Tracey Speaks...

Hello, everyone. I’m Amie Tracey, Lead Designer at Ponderwell, and I’m excited to have the opportunity to tell you a bit more about who we are and why we’re so enthusiastic about our proposal for the Community Media Development Initiative.

I’m going to start with a story, because it explains a lot about how we come to be making this proposal in the first place.

About four years ago, I was sitting with Michael Tracey and Martin Haywood on Martin’s porch in Australia, where Michael and I had gone for vacation. And because we’re programmers (which you can understand as “nerds”) what we were talking about was how one could go about building a community journalism site that actually works. We’d wound up there because we’d originally met online in an early community journalism site called Newsvine, and that site had some good points and some bad points, but we had a lot of ideas about how you could build the site on a technical level to create a much better system. It’s really this idea that brought our company together, because while we’ve done a lot of other projects over the years, this is the one that we always hoped to find a way to create. I just want to be clear that I’m not exaggerating when I say that this is our dream.

OK, I am going to tell you a little about what Ponderwell does, just so you have some idea of why we know we can do this, and then we’re going to go right in to giving you more details about what we want to create and why it’s going to really work for our community here in the Asheville area.

You may not have heard of Ponderwell before, but you probably know some of our clients. We build websites, like the one we built for Crossroads Entertainment (an Arden-based record label); we do database work, for example we built the database for WNC Healthy Kids; and we do a lot of consulting for other programmers and companies who hit problems they don’t know how to solve, for example we do a lot of consulting for Arvato, and we get calls from other programmers all across the country when they get stuck. So that’s a quick overview of the kind of thing we do. You can see more examples of our work on our Portfolio page, and hear what some of our clients have to say about their relationship with us over on the Grant Testimonials page.

But I want to go on and talk about the project. You can read our proposal here, but it’s pretty hard to get across in just a few pages exactly what it is we want to create and how it’s all going to work. So let’s start with an example, and then Michael’s going to step in and fill out the details for you.

Let me tell you about Michael Hayes. He founded the Urban Arts Institute, and for over four years he’s been running an after school

Michael Hayes

Michael Hayes

program down at the Reid Center for disadvantaged kids, and what he does is he gets them in and he teaches them to dance. They’re lovely kids, and it’s an inspired program…the only problem is that you may not have heard of it.

Now, imagine you’re down at LAFF, where some of these kids had the opportunity to perform this year. You see them dancing, learn a bit about the program, and you think to yourself what an amazing project this really is. And you realize that lots of other people may not know about it, but would certainly like to. So you go to our site and put the idea up on the Assignment Desk, saying that you want to write this story, but you really need a photographer and a videographer to come along and actually show what these kids are doing. A couple of other folks pick up the assignment, you go down and get the story, and then you submit it to the editors and it goes up on the site. You feel great, because you’ve just spread the word about something you think is really important. You may also get a little financial compensation and some exposure for your brilliant writing, but your core motivation is using the skills you have to grow this community.

So now imagine instead that you are Michael Hayes. He’s been providing this service with no compensation, just because he really cares about helping these kids find a better path in life. And because of the exposure this article is giving his project, suddenly people are aware of and interested in what he’s trying to do. He gets invitations for his kids to come perform at local events. Maybe he even picks up a sponsor or two…people who would have been willing to support him all along, but had no idea he existed.

Dancers at the UAINow on the other hand, imagine that you are a visitor to the site, either a local resident or someone considering coming to our area. With stories like this, you’re getting a real picture of what our area has to offer, how much deeper and more interesting it is than you probably ever realized. And because the contributors to the article were enthusiastic about their story, that enthusiasm infects you, too. Maybe you decide to go to a small cultural event, just because you want to see these kids perform. Or maybe you can’t make it to their next performance, but you go to dinner with some friends and start telling them about this amazing thing you found out about today, and perhaps some of them go. In any event, you’re better informed, and as a result you start making better informed decisions.

So that’s the gist of why we feel this is important. But now I’m going to hand you over to Michael Tracey, one of our lead programmers, who’s going to tell you a lot more details about how this process will work.


Michael Tracey Speaks

I’m going to talk about some of the technical aspects of how our site will work. The heart of our project is the Workflow, because it’s the Workflow interface that allows contributors to publish worthwhile media to the site. Think of it as a community driven virtual newsroom. When contributors log into the website, they will have access to Workflow, an online application that manages the flow of media into the the publicly viewable site.

This is what sets us apart from other standard media outlets and also other attempts at community journalism, the fact that we’ve come up with a solution that makes it quite simple to get quality, peer reviewed, media up on the site. I’m going to explain Workflow using an example from ImageAsheville, a website I created which is a small, cooperative photography showcase for our area. I’m choosing this photo, because it is a somewhat controversial photo, so we can see a more complex description of the editorial controls.

Photo by Bill Rhodes

Bill Rhodes, a local professional photographer and concerned West Asheville citizen, took this photograph of an arrest on his street. He puts this photo into Workflow, captioning it and attaching a request for a reporter to write the article.

Now imagine you are a concerned West Asheville citizen, and have a talent for writing. You see in the pool of possible stories this photo and story pitch, and think I’m involved in West Asheville, I know about this. So you write the article to go along with the photograph. The article is now marked as “ready to publish”, and — inside Workflow — goes into the proper pool for a community editor to see and edit.

So now I’m going to ask you to imagine stepping into the role of an editor. Your role is to open up the article, begin editing, and send it up into the appropriate site sections. Now, let’s imagine the reporter neglected to use the word alleged while talking about the suspect, presuming that they are guilty. The Editor can make notes and send it back to the contributor team (the reporter and photographer) for changes. Once the story is corrected, it goes back up Workflow with all its notes and changes, becomes re-edited, and is now ready for site placement.

So let’s look at the role of a Section Chief. Suppose you have edited quite a few stories, and have a real knack for it. Workflow’s algorithms know this, and you have been promoted to Section Chief for the West Asheville section of the site. The above story was tagged as “West Asheville”, so it gets scheduled for publishing in your section. Your job is to choose which stories are important enough to make top headline news, or schedule stories to expire after they happen. All this content is archived, and available via searches, but you get to choose placement (via drag and drop) and length of time each story stays on the “West Asheville” section. You see this story has been automatically placed in the “new headlines” section, so you drag it over to the “Top Headline” slot, and bump down an article about a band playing at the Westville Pub. You also notice that the band is playing tonight, so you check the expiration to make sure that it doesn’t show on the “West Asheville” section after 7:00, when the band starts.

OK, let’s look at one more role. Pretend that you are a seasoned veteran to the site, and are the section chief of the whole “Asheville News” section. The reporter and photographer did not request that the story go into the “Asheville News” section, but since it was given high placement in the “West Asheville” section, it is brought to your attention as a potential story for you to add to your overarching section. In other words, each subsection has concerned community members who curate it, the parent sections get notified of potentially important stories as they come in, allowing news with a broad interest base to “bubble up” to the front page of the site.

But there’s a couple other ways it could have gone. Let’s imagine that you submitted the story, but decide that you don’t like the editor’s proposed changes. You can always publish any article to your own reporter stream, but it will be automatically marked “Opinion/Editorial” and “Unedited”. It will be available online, we aren’t stopping anyone from sharing, but it will not be eligible for section placement anywhere but the contributor’s online column unless it has gone through the editing process.

Another way this story could have gone, was that the contributors marked the story, “Breaking News, Edit and Publish”, in which case the editor could simply edit the story themselves, and publish without sending it back down Workflow to the contributors. This allows news to get onto the site quickly when time is of the essence.

In our example here, we explained each of the Workflow roles separately, but you can hold multiple roles on the site. The reporter could also be a section chief of “Erwin Sports”, and an editor for the whole sports section. Workflow will make sure that you never edit your own work.

Our forum system allows all the roles involved to discuss with their peers any issues in the process. If the editor has some questions about the alleged terminology, the editor forum is a great place to ask for help from other editors. The Photographer and Videographer forums will let them talk about their crafts, and critique each other’s work. Section Editors can talk about the best timing for leaving things as headlines, or what makes a good headline slug. We’ll be enhancing this camaraderie with in person meet ups and events.

Tipjar in Workflow (Creative Commons Photo Credit: http://www.flickr.com/photos/davedugdale/5025601209/ )

One of the most exciting features of our project is the Tipjar. What is really exciting about this is that it’s an innovative way to encourage positive community culture. The crew that created the article will get 50% of ad revenue for page views on their media. Readers can also use the donate feature right on the article to tip the contributors. Now, going back to our example story, if you are a member of the community and have $3.10 in your Tipjar at the moment, you are likely to tip fifty cents out of your Tipjar into the West Asheville arrest story, if you liked the reporting and photography. By donating directly from your Tipjar, the reporter, Bill Rhodes (the photographer), and the editor all get a 1/3 split of your fifty cents in their jar. They are more likely to tip others, after they see your tip and note of appreciation. In this way, we are using reciprocity to build community.

Another planned Tipjar feature is that upon withdrawal, our contributors will have the option to donate their earnings to a list of local charities instead of transferring the balance to their Paypal account. If they don’t know about the listed charities, they can look them up in our Local Directory.

Our project’s Local Directory isn’t like most of those dull, incomplete and non-factual lists online. It’s basically a landing page for each business or organization that indexes all previous news stories about that business. A good example of this would be “The Hop”. They have ice cream socials almost every week, and donate the proceeds to a particular charity. On ImageAsheville, they’ve been covered a lot. Their Directory page would not only have the web address and business info, but also include historic articles and photos written about them by people attending those events. The charities that they support would also have the ice cream socials listed on their charity page, showing readers that the charity has a wide base of support in the community. Because we are not charging for listings, like many other local outlets, we don’t have a conflict of interest in listing news next to business information.

Now that you have an idea of the the kind of dynamic powerful system we are building, both for visitors and contributors, I’d like to pass this over to Martin Haywood, our other lead programmer, who will tell you how this is going to succeed.


Martin Haywood

Martin Haywood Speaks

I’m going to talk about what makes the project viable. There are two parts to the idea of viability: does it provide a service that Asheville needs and values, and is it economically sustainable? But the two are the same question. We’ve done the numbers, you can see in the budget. We used standard values for click throughs and pages per visitor and ad revenue per click. It adds up – provided we have a vibrant and engaged community of contributors and readers. Then we have the number of daily visitors we need to make the site work financially. That’s why it’s all about community and how we enhance the community of Asheville, and we have some great plans for how to do that, based in education, industry development, and the cultural and economic development of the wider community.

1. Let’s start with schools. We’re putting tools in place that allow a classroom to have a safe environment to publish stories to the site. In this case the teacher becomes the editor and all stories show up in the “schools” section, but otherwise they’re just as visible as any other story written by any other author. The kids get to talk about and engage with their community – they get to be real reporters. They exercise their skills in writing and photography and video, they think about culture and government, and their friends and families can read exactly what they’re doing, after their teacher has exercised editorial control. They can really make a difference and it’s very encouraging for students to be in this position. Kids want to have a real voice, and to learn things by doing things that actually matter rather than just practicing to make a difference.

Reneé Owens is the head of Rainbow Mountain Children’s School in West Asheville. She’s keen to have her school be part of the pilot program. We’ll have classes from Rainbow Mountain be part of the testing phase of site development, and then when it’s running we’ll reach out to other schools and hold their hands through the process of becoming part of it.

2. The second is more of an industry development benefit. Take Joshua, he’s a friend of my daughter’s and he’s about 20. When he finished

Micah and Joshua

The apprenticeship program

high school the thing he really wanted to be was a photographer, so instead of spending the money he’d saved on a car he bought a camera. Now if he signs up on the site he can access photography assignments – covering LAFF, for example. He goes there and takes a bunch of photos, and of course an editor will help him choose which are the best to use for the story. And of course he can use the contributor forums for collegial support, for editors or writers or anyone who needs to ask for help, as Michael was saying. But for someone like Joshua who’s learning, he can tick a box in his profile which means that he’d like “mentoring”. We have editors who have agreed to mentor as well as just edit. Like Micah Mackenzie. Micah is a professional photographer and he’s a community minded guy; I’ve talked to him and he loves the idea. He’ll take Joshua along to cover a story, and they can do it together. There’s nothing like that sort of individual example and help. That’s our “Apprenticeship program”.

Later, maybe Associated Press liked one of Joshua’s pictures and wanted to buy it – we have that facility on the site, the “contributor’s market”. But even without that Joshua’s getting valuable experience and valuable mentoring. When he applies for a job he has a portfolio, he has something to show and he’s a much better photographer than he would be if he just did it as a hobby.

There are a lot of people in the community who would like to share their skills and give back, like Micah. 16% of the county are retirees, increasing to 23% in 2030. Many people from all walks of life would like a way to engage with the community, be part of something bigger than themselves. The community forums and the apprenticeship program are an important part of this, and so are the contributor events and meetups that we organize, so that people can meet in person and form friendships.

Even if you just visit the site enough it remembers you and sends you an invitation to contribute and be more a part of it.

3. Now finally there’s the benefit to readers of the site. They get to see just what a rich and interesting cultural place Asheville is. I’m learning Tango – it’s really hard and I’m still really bad at it – but Asheville happens to have the best Argentine Tango community in the whole

tango

Tango in Asheville

southeast. The other day someone drove from Winston-Salem to take part in a class I was at. But it’s really hard to find out things like that, even if you look at the various event calendars there are online. If you go to this site, though, and you reading stories about Tango in Asheville, then suddenly you can think “oh, I’ll go take a class” or “I’ll go see that exhibition” or “Wow! Roller Derby really sounds like fun!” There’s so many things here – but to really engage people you need the narrative and the pictures, it’s not enough to just see an event on a list, it has to be personal. That has huge implications both for the residents of Asheville and for tourism. We’ve all seen tourists walking around looking lost – they’ve been to Biltmore and to the Arboretum, and now they don’t quite know what to do. We’ll if they’ve been reading this site they have so many more options, and they know enough about them to make that leap to really caring about it. So they’ll stay longer, spend more money, have a better time, and tell their friends. Just by the way if you look at the tourism figures, that industry was worth about 2 billion dollars to Asheville in 2005. And each tourist stayed an average of 2.3 days. If you can get that average up even a little bit it makes an enormous difference to business here.

Let me show you a video of Michael Hayes. He’s a big supporter of our idea, and he really gets it. The thing is that a community exists because it understands itself and talks about itself. If there are parts of the community that no one hears about and no one recognizes, then they’re excluded, they’re on the outside or the margins. But when a community can share what its members are passionate about and tell its stories, then it gets brought closer together. It can help itself. People feel included, part of a larger whole. There’s an awful lot of difference between someone coming in from above and “reporting” and someone telling a story that they’re involved in and really care about.

[vimeo width=”580″ height=”326″]http://vimeo.com/29621576[/vimeo]

You know, the sound is bad on that video of Michael Hayes because the kids were playing in the background. But before I could leave Michael was sending one kid to find his niece so he could make sure I could contact her as soon as this project is going. She is a talented writer and she needs a place to express herself. He was telling another kid “you should be signing up for this in a few months, it would be great for you!” I ended up with a bunch of names.

Which brings me back to the economic viability of our idea. There are four ways we generate revenue on the site… 100% of the ad revenue on all pages that are not articles, 50% of ad revenue on article pages, tip jar escrow, and contributor market sales commission. But it all depends on the site being a place that people really use and really care about. Then the revenue follows and we have a sustainable project.

And for reporting I haven’t got a lot to add to what’s in the proposal but – we believe in transparency. It’s part of giving people confidence in what we do but more important it’s part of us refining and improving what we do. We’ll have the visitor numbers and contributions and click-throughs all reported automatically on a page in the site for anyone to see. We have to have this and make it public, because share part of the ad revenue from contributors’ pages to the people who made the stories. Every six months we’ll use that and feedback from the users and contributors to produce a strategy report which tells us what’s working well and what needs fixing. We use that ourselves, as well as providing it, along with financial data, to the council. It sounds like a simple thing, and it’s not resource intensive, but good analysis is essential.

Now back to Amie…


Amie Tracey

Amie Tracey Speaks...

I want to wrap up by telling you why we feel we are the best choice to deliver a project you will be proud to say you allocated public funding to begin. We’re not building a simple news or blog aggregator for our area; instead the core of our idea is a system which will inspire and support members of our community to feel they have the right and the ability to make their voice heard. We want to get people involved who may never have considered contributing to community journalism before, as well as the long-standing writers and photographers and videographers in this area.

This is what we do: we build complex systems that are simple to use for those who don’t happen to be tech geeks. And this idea is the core of what brought our company together: to be able to create a community journalism site that brings people together and empowers them to report on what they feel is important in their area. We know we can do it well, and we hope you will give us the opportunity.

Thanks for the read through. If you would like to help, leave us a comment below. We’d also be happy to have your testimonial on our testimonial page, feel free to drop us a note.

Ponderwell bids for Community Media Initiative Grant

*** UPDATE*** We have now posted our notes from the 25 minute presentation to the grant committee. This is a good read-through for people who want to know more details about what we are proposing.

The City of Asheville and Buncombe County recently made a request for proposals in relation to a grant of $120,000 for community media development. The grant would be used to create a project which put the new media in the hands of local citizens, and was of benefit to the community from an educational, economic, industry and workforce development standpoint.

Ponderwell submitted a proposal which is dear to our hearts. We want to make an online news outlet that will allow the people who live here in Western North Carolina to share and talk about their community through writing, photography, and videography. While there are already sites which focus on the Asheville area, none are focused on creating an interface to actively promote quality citizen journalist reporting. Our system focuses heavily on building an engine for volunteer edited, peer reviewed news and commentary about our region, in order to create a community of both readers and volunteer publishers and editors that not only consume local news and events, but become part of reporting it. You can see our full proposal here:

pdf Download the full proposal as a pdf.

The founders of Ponderwell have been thinking about this for years. We met and formed Ponderwell as a direct result of our participation in an early community journalism site, Newsvine. One of our founders was a part of bringing the Citizen-Times online in the early 2000’s,  building the publishing platform used there, and more recently we built the very successful local photographer blog, imageasheville.com, which focuses on the events and life of our city. We have the technical skills to bring this vision into reality. Apart from building complicated websites including an online music store with a catalog of 20000 products and audio and video streaming and downloads from the cloud, we’ve also found a niche as the technical people that your technical people turn to when they get in over their heads – from networks to databases to javascript to bezier paths on iPads.

We have had several requests over the last few days from community members interested in our proposal. We’ve already heard from some community leaders, and would love to hear from you. Feel free to drop us a comment below, telling us your thoughts.

Simple caching in Zend Framework

A couple of years ago Ponderwell built a site on Zend Framework (ZF) as a bit of fun. It’s been moderately successful, getting a steady flow of traffic, but every now and then it catches people’s imagination and gets a huge spike of traffic which makes the server fall over. We needed caching.

ZF has a very simple powerful cache class. You can cache pretty much anything and index it any way you want and store it in memory or the database or as text files. The point of failure when the site got a traffic spike seemed to be MySQL, so I wanted to cache the page data creation in the indexController. The model for a post pulled everything into a single object, so that made things easy. I identified the parameters (post name, sort order) which are passed in to the model to pull the correct post and its ancillary data, and made a key string out of them. That will then index the cache. If the index exists, use the cached version. If it doesn’t, call the model to create the data and save it to the cache before proceeding as normal.

The code is here:


$controller_cache_id = 'front_' . $post . '_' . $sort;

if( false === ($sortedPost = $cache->load($controller_cache_id)) ) {
$sortedPost = new Model_SortedPost($post, $sort);
$cache->save($sortedPost, $controller_cache_id);
}

$this->view->post = $sortedPost->getPost();
$this->view->nextlink = $sortedPost->getNext($sort);
$this->view->prevlink = $sortedPost->getPrev($sort);
…. etc.

To set up the cache ($cache, above) do something like this:


$frontendOptions = array(
'lifetime' => 7200,
'automatic_serialization' => true
);

$backendOptions = array(
‘cache_dir’ => realpath(APPLICATION_PATH . ‘/../cache’)
);

$cache = Zend_Cache::factory(‘Core’, ‘File’, $frontendOptions, $backendOptions);

That’s all there is to it. Make sure /cache/ is writable by Apache. I’ll do some testing and let you know how well it works.

Converting SVG Paths to Objective-C Paths – Updated Again!

Further update:

Ariel over at arivibes.com has turned this into a GitHub project and, I believe, greatly improved it: HERE

 

Update: Bob Monaghan from Glue Tools LLC was kind enough to clean up some memory leaks, make the thing compatible with OS X as well as iOS and put in some positioning of the paths in a Rect. The download here reflects this new much improved version.


OS X and iOS have a wonderful library of great drawing and animation tools, many of which are built on Bezier paths. If you’ve created these paths in some other program, such as Photoshop or Illustrator, however, you’ll be left with the task of importing these and converting them to NSBezierPath (on OS X) or UIBezierPath (on iOS) objects. The best way I found to do this was via the SVG format. It’s XML and the paths are represented by «path» tags containing a “d” attribute which is a string containing a series of move, curve and line commands and coordinates. That’s convenient because Illustrator can export as SVG and OS X is good at XML.

What’s missing in this is a parser for the path creation commands. I’ve written one which takes the “d” attribute string and converts it to a UIBezierPath. It’s written for iOS but it would be easy to make it OS X. I left the decomposition of the d attribute string from the SVG text file as a separate piece of code because I’m cutting and pasting the SVG paths into a larger XML document which contains all sorts of program information. It’s perfectly possible, at the simplest, to just search for the string between each ‘d=”‘ and the following ‘”‘ and feed the contents into this code. So far it’s tested against a number of quite complex paths created in Photoshop from the outlines of custom text, imported to Illustrator, then saved as SVG. Be aware, if you do something like this, that for something with an interior space – like an “O” – the two separate lines, the inner and outer circle, must be part of the same path. There will be a ‘z’ command in the middle of that path to close the first line, then commands ending in a ‘z’ to close the second line. Without this a fill command, for example, will fill the entire circle.

To make a bezier path, instantiate an SvgToBezier converter with the “d” attribute string passed to the constructor, then the “bezier” property of that object is the path you can use elsewhere. The code is a single Objective-C class file, although internally it uses a private class called Token. (And, have mercy, I’m new to Objective-C – however critiques of my code are much appreciated.) Here’s the code for that constructor:

- (id) initFromSVGPathNodeDAttr:(NSString *)attr inViewBoxSize:(CGSize)size {
	[super init];
	if (self) {
		pathScale = 0;
		viewBox = size;
		[self reset];
		separatorSet = [NSCharacterSet characterSetWithCharactersInString:separatorCharString];
		commandSet = [NSCharacterSet characterSetWithCharactersInString:commandCharString];
		NSArray* tokens = [self parsePath:attr];
		bezier = [self generateBezier:tokens];
		for (Token *token in tokens) {
			[token release];
		}
		[tokens release];
	}
	return self;
}

Pretty simple, it sets up the valid character sets from constant strings, parses the d attribute as tokens, then generates a bezier from the tokens. “generateBezier” takes each token in turn and draws the command that token embodies into the current path. There are 5 different command families, “move”, “line”, “curve”, “smoothcurve”, and “close path”. Smoothcurve uses the immediately previous curve’s last control handle as its own first control handle. Here’s the code for smoothcurve as an example of how that works:

- (void) appendSVGSCommand: (Token *) token {
	if (!validLastControlPoint) {
		NSLog(@"Invalid last control point in S command", nil);
	}
	int index = 0;
	while ((index + 3) < [token valence]) {  // we must have 4 floats here (x2, y2, x, y).
		float x1 = lastControlPoint.x;
		float y1 = lastControlPoint.y;
		float x2 = [token parameter:index++] + ([token command] == 's' ? lastPoint.x : 0);
		float y2 = [token parameter:index++] + ([token command] == 's' ? lastPoint.y : 0);
		float x  = [token parameter:index++] + ([token command] == 's' ? lastPoint.x : 0);
		float y  = [token parameter:index++] + ([token command] == 's' ? lastPoint.y : 0);
		lastPoint = CGPointMake(x, y);
		[bezier addCurveToPoint:[self bezierPoint:lastPoint] 
				  controlPoint1:[self bezierPoint:CGPointMake(x1,y1)] 
				  controlPoint2:[self bezierPoint:CGPointMake(x2, y2)]];
		lastControlPoint = CGPointMake(x2, y2);
		validLastControlPoint = YES;
	}
	if (index == 0) {
		NSLog(@"Insufficient parameters for S command", nil);
	}
}

Full code is here, as a zip. You’re free to use it under the Creative Commons license below so long as you keep the attribution: leave the attribution comments in the headers.

Creative Commons License
SvgToBezier by Ponderwell, llc is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.