Blog

Drupal development, project updates, occasional knee / head slappers

Jul 18, 2010

heard about Reqall.com here, and thought the idea was awesome - you send audio to a service via e-mail and it transcribes it for you and sends it back. I'd like to be able to take audio-based notes with Evernote and Reqall sounded perfect. After evaluating it for a bit, I think I'm going to have to wait on integrating it into my workflow. Here are my thoughts:

  • It touts Evernote integration, but it only integrates by pulling data from Evernote to match the internal notes. I would need it to send the transcription to Evernote
  • There is a 30 second limit - perfect for quick to-do items, but not for random journaling.
  • The test I did transcribed perfectly, which was really cool.

If I found out that I was able to work with the 30 second limit, I could have the transcription forwarded to my Evernote e-mail account, which would add it in - albeit without any tags.

I've checked out Google Voice for transcription services, but it's limited to 3 minutes. If it was worth it, you could just keep leaving 3 minute voice mails and see how well the audio transcribes.

Jul 20, 2010

The problem

Often I come to a crossroads where I can either experience a moment or capture it. This is a difficult decision. Do I take a picture, or do I watch with my own eyes? Do I think unrestrained, or do I write it down? Do the benefits of having the memento or reminder outweigh being a little more in the moment? 

That question is tough enough. But then the time spent out of the moment is compounded when sharing the moment with others. Downloading images from the camera, uploading them to Flickr, tweeting about it or updating your Facebook status. It takes time, and it's hard to measure the payoff. Are these artifacts that we're sacrificing a little slice of our lives for really worth it?

I'm pretty sure good to share, particularly with the right motive. If it took no time at all, the effort can only land on the side of good to convey interesting experiences or ideas to others. We can add to the global consciousness and do our part in the push towards greater things. But the reason I don't blog, and I don't tweet, and I don't FB these days is because the cost is too steep. I have specific work-oriented goals I'm shooting for, I have a son I'd love to spend a lot more time with, and another one on the way. I have a yard to mow and a body to keep from languishing. I feel like I'll have time to share someday, but usually it's not now. Or, when I share it can only be for very specific reasons that match up with other goals too.

I've been steadily working towards solving the first problem of capturing. A service called Evernote (you may have heard of it) plays a huge part. Of all the data-capturing applications I've worked with, Evernote streamlines the capturing process. It has a global hotkey (at least for Mac), so I can use it even if it's not open. All I need my mind to do is think that hotkey, and in a second (or a couple if the app has to open) I'm capturing. It syncs up with my iPod Touch so I can capture on the road.

In order to enrich my ability to capture other media, I recently purchased a mobile phone with audio and video capturing abilities. I can e-mail these to my Evernote account. This streamlines the capturing process so it feels like the cost is about as low as it can get without having embedded photo sensors in your forehead. No transferring of media, it just syncs up on its own.

This wasn't enough for me. I also wanted to tackle the problem of the lowering the overhead of sharing to the point where it felt like it was no longer a matter of if I had the time, but rather if the information was worthy of sharing.

One issue I have with sharing information is the multiplicity of channels. How can I expect that someone will monitor my Flickr, Twitter, Facebook, Blip, Digg and Delicious accounts, plus several of my own media channels. And even though there is some integration between these services, as far as I know there's not a single application that provides a centralized method of distributing media, so managing the distribution of the data I want to share requires hooking into multiple interfaces. Even if there was a unified interface, there's then two places to manage that data - your local copy and the copy on the channel, and I feel like it should be possible to reduce this to one. Change it locally, and it changes on the service as well.

The issue of centralizing the consumption of your media can be solved by pulling in all the data to a centralized feed - like a blog. It can aggregate your tweets, your videos, your blog posts, and anything else. But, there's still the problem of getting that data into the blog in the first place, and managing it once it's there.

The solution

So, I started putting a couple of pieces together. Evernote provides a method of embedding files of various types inside the notes, and it syncs them with a remote server. I remembered reading that Evernote also had an API, so I started looking into it to see if there might be a way to sync up a web site with Evernote. If so, then I could feasibly create a post locally and have it automatically appear in my blog. If I could centralize my media into Evernote and use it as a blog broadcasting tool, then I would have a solution to multiple problems: 1) Having only one interface for distributing multiple types of media, solving the multiple channels issue 2) Since I capture ideas and information in Evernote anyway, sharing it wouldn't add any overhead at all. 3) If I could broadcast out to multiple channels, I could get a lot of leverage for the data I capture, making it more likely that I would want to capture it in the first place - a useful feedback loop.

The idea really excited me, and as I started digging into the Evernote API, I realized it was totally possible. It's times like these that I'm really happy to be a developer.

I'll be posting more about the solution I came up with, but the idea is to use a Drupal site as a hub which polls Evernote for new notes that meet particular criteria (i.e. they have a particular tag) and adds them as nodes (pages) to the site. Any updates that are made in Evernote are automatically pushed to the site. I built a Drupal module (which will be available soon) that manages this process, and allows two types of tagging - the traditional type which organizes the nodes (i.e. family, recipes, etc) and the second which can be used as triggers for other activity. On this site, for example, I can add a tag called *tweetand Drupal will automatically tweet the node with a shortened URL. If I add a *fb tag, then the twitter post will be sent to Facebook as well.

So just to be clear, here's the workflow:

  1. I create a note in Evernote
  2. I give it the tags *tweet and *fb

That's all. The note is broadcasted to my blog, to Twitter and Facebook. You don't even have to save your note in Evernote, it saves it in the background. If there are any media files attached, it automatically saves them to the appropriate place in Drupal. If that media changes in Evernote, it will be updated in Drupal.

You'll have to excuse me, but I think this is pretty bad ass.

One other issue I wanted to solve was the issue of inter-linking between notes. Evernote is suspiciously wiki-ish, but there's no way to link between notes. What this Drupal module will do is post back a new note with a list of the pages that have been published through the module - with links - so you can copy and paste the links in other notes. Because Evernote has awesome search, it's easy to find the link if you know even a single word.

Oh, and one more piece of awesomeness? Evernote OCRs images on their server, and this module will capture the OCR-ed text and pull it back into Drupal to add to your pages in a variety of ways. Images become searchable! Damn!

The upshot is that I now have a tool that makes it amazingly natural to share information. Of the things that I think are worthy of capturing for my own benefit, there's a handful that I can see being useful to others. To share it, I only have to add a tag.

More to come about this, as well as a release of the Drupal Evernote module. 

Jul 8, 2010

Disabling the Update Status module made my "MySQL Server has gone away" errors go away for a little while. But then it came back. Along with the errors, the cron job wouldn't complete, and therefore the cron_semaphore (do you know what a sempaphore is?) variable in the variable table wouldn't reset, and thus cron wouldn't run again. I talked to Site5 support - they have added instant chat support since the last time I had a major issue - and they got it fixed by upping the MySQL memory limit in a my.ini file that contained the following: 


[mysqld]
max_allowed_packet=64M

Apparently you can modify the MySQL settings as well as php.ini this way. Nice.

Jul 18, 2010

Below is a video of a talk I gave this year at DrupalCamp Colorado that summarized some of the important lessons I've learned after 7 years of freelancing. I do talk about the logistical details like pricing and saving money on taxes, but my big focus is on how to build a vision for the life that we work so hard for. The talk initiated some great conversations afterwards, thanks for everyone who took me aside to share.

Jul 14, 2010

I always run into a memory limit or upload limit issue with Site5. Luckily, they let you set your own php.ini file to up the limits. 

  1. Create an empty php.ini file in your public_html directory
  2. Copy this to a file in the root directory and name it something like phpini.php
  3. You will need to change the $customPath to match your directory. You can find this by creating a file and putting <?php phpinfo();?> in it. Or, if you have command line access, you can run the /cwd command.
  4. You may need to change permissions on the php.ini file to be written. 666 should work okay.
  5. Open the script in your browser by going to http://mysite/phpini.php (script found here: http://tips-scripts.com/php_ini)
- - Start Script Here - -
<?php
// Put all the php.ini parameters you want to change below. One per line.
// Follow the example format $parm[] = "parameter = value";
$parm[] = "memory_limit = 64M";

$parm[] = "upload_max_filesize = 400M";

$parm[] = "post_max_size = 100M";
// full unix path - location of the default php.ini file at your host
// you can determine the location of the default file using phpinfo()
$defaultPath = "/usr/local/lib/php.ini"; 
// full unix path - location where you want your custom php.ini file
$customPath = "/home/[site5username]/public_html/[yourdomain.com]/php.ini";
// nothing should change below this line.
if (file_exists($defaultPath)) {
  $contents = file_get_contents($defaultPath); 
  $contents .= "\n\n; USER MODIFIED PARAMETERS FOLLOW\n\n";  
  foreach ($parm as $value) $contents .= $value . " \n";
  if (file_put_contents($customPath,$contents)) {
    if (chmod($customPath,0600)) $message = "The php.ini file has been modified and copied";
      else $message = "Processing error - php.ini chmod failed";
  } else {
    $message = "Processing error - php.ini write failed";
  }
} else {
  $message = "Processing error - php.ini file not found";
}
echo $message;
Jul 7, 2010

Below are the slides for my DrupalCamp Colorado talk about freelancing. I will be posting a video of the talk once it's happened. :)

Jul 7, 2010

I was asked to speak at this year's Career Day at our local high school, and thought it would be an awesome opportunity to skew the vision of young minds towards the possibilities that a work life in web design / development can offer. I did a similar talk a couple years ago at the last career day, and realized that in order to keep these guys from drifting off I had to make a concerted effort to break the third wall.

So, I put together this presentation that basically converts the room into a web development firm and introduces the multiple roles you can take on, all the while building out a spec for a popular web site clone (MySpace was the choice each time). I was really impressed with the kids' willingness to participate, and heard it went over pretty well.

Why you would watch this

I'm posting this video just in case folks out there are called upon to give similar presentations to one of the toughest audiences out there - the significantly-younger-than-you kind. The structure I used is low tech, brings the kids in for approachable tasks, and assigns roles to them based on what skills they see in themselves. I figured that if I could get them to connect what they consider their assets to a job title, it would have a greater chance of sticking in their minds, and when they get to the point of genuinely considering careers, they have at least a starting point. But, who knows, it was at least fun and allowed me to test out some ideas on how to make a presentation more compelling for a younger audience.

Stuff that worked well:

  • I started by asking for a volunteer to videotape the presentation. This insured that at least one student was going to be involved the whole time, and they were indeed the ones that asked the most questions. Plus, it also established a level of trust and broke that third wall immediately.
  • I asked the students what they were good at, and assigned them positions based on that. The idea was to give them a feeling like their positive qualities could have an impact on the roles they play down the road.
  • I gave them name tags and spoke to or about them when describing the position, making it less abstract. Also, if they kept the name tags on, I thought other kids might ask them about it and they'd have to articulate at least something that they learned during the talk.
  • I kept it low-tech, using just a white board. Doing this meant less technical overhead, and maybe making the whole idea more approachable, that you didn't need fancy tools to get a lot of the work done.
  • I practiced maybe 4 or 5 times while jogging to make sure I could fit everything into a half hour. I had to cut a bunch of stuff and really streamline the process to get this to work.

Jul 7, 2010

I'm chairing the "Providing Professional Drupal Services" track for Drupalcon San Francisco in April and am looking for interesting sessions and speakers to help seed the Drupalcon sessions list. We already have some great folks on board. Sessions will be opened up for public submissions soon and the earlier your session gets added, the longer people have to vote on them.

So, if you're interested, ping me with your session idea. If you're looking for ideas, I've put together of potential subject matter for my track here, as well as a Drupalcon Talk Idea Generator to get your juices flowing.

Disclaimer and clarification: I posted this with the goal of connecting with people who are thinking about or have already prepared sessions for the track I'm chairing. I'm not in charge of fielding all Drupalcon session proposals and I won't be the one that decides which sessions ultimately get chosen, but I should be able to help folks with the submission process.

Jul 7, 2010

It's a horrendously long blog title, I know, but I wanted to mash in all the keywords I was looking for when trying to find a solution to this very sticky problem so that other folks running into the same issue can spend the next six hours doing something more productive.

jQuery makes grabbing one group of elements from a page, duplicating them and adding them somewhere else really easy. You just use a combination of clone() and something like append(), as in the following:

$('#surrounding_div').clone().appendTo('#some_other_div);

The problem with dynamically adding form elements in IE

Woot! So easy! Right, until you start goofing with forms and IE (Internet Explorer) (appropriate sound). The problem is that IE doesn't allow you to manipulate the 'name' attribute in the DOM directly. So, something like this won't work:

$('#form_element').clone().attr('name', 'new-name').appendTo('#my-form);

If you do that with a radio button, the interface will tell you that there's a problem, because since the new radio button has the same name as the original one, only one can be selected. Bugger!

Luckily, the solution is clear, but it took forever to figure it out. Instead of adjusting the name attribute directly with something like attr(), you need to edit it manually in a block of html and then add that html to the page. So, something like this would work:

$('#form_element').parent().html().
replace(/orignal_name/, 'new_name').appendTo('#my-form');

There's a couple of key points here:

  1. Because we're getting the html using $.html(), we need to move up the DOM to grab the element surrounding the element we wish to add using $.parent(), then we can grab the html using $.html().
  2. I'm using the javascript replace() function to pass a regex pattern and replacement text to the html.

What about dynamically cloning groups of inputs with jQuery?

In my particular use case, I was grabbing a set of form elements and adding them this way. There were a couple of challenges, which was that I couldn't use $.parent() to get the outer element, and the other was that the names of the form elements were being set dynamically. I learned a couple of tricks to help with this:

Use the regex modifier /g to replace all insteances of a pattern. So, when doing replace(), if I needed to replace ALL instances instead of just one, it would look like this:

replace(/original_name/g, 'new_name')

Because I couldn't use $.parent(), in the end I had to wrap an element around the html using simple contatination, like so:

var newHTML = '<div>' + $('#element').html() + '</div>';

I hope that helps you, it was sure a bugger to figure out.

Jul 7, 2010

Skip to video and slides

A couple weeks ago I put out a blog to garner feedback on why Drupal kicks serious a**, and a big thanks to everyone who responded. I integrated a number of the comments with my own personal experience with Drupal and presented my talk last week to a diverse group of 20 or so web tech people in the local Boise Idaho area. Judging from the audience participation, I think the presentation went really well. I recorded the talk (from two different camera angles, no less!) and am posting the video and slides for folks that are curious about what they missed, or who are interested in giving a similar talk themselves.

I did a little research before hand about how Drupal compares to popular CMSes like Joomla, Plone, Wordpress, ExpressionEngine, and SharePoint. The talk was also directed in many ways to audience members who have rolled their own CMS, because that was my experience coming into Drupal and I found that Drupal solved many of the problems I was attempting to solve myself, but in much more elegant ways.

Drupal kicking butt - Video and slideshow



The format of the talk was "10 ways Drupal (might) kick your CMS's a**", and here are the 10 things about Drupal that stand out to me as particularly steller:

#1 - The Drupal Community

The community is a big part of what keeps me involved in Drupal at the level I am. I helped found and participate in a local Drupal users group, which provides important face-to-face time with other people using the Drupal, and keeps us all abreast of important news in the project. I also talk about regional conferences and Drupalcon, IRC, and leadership in the community.

#2 - Central Module Repository

Drupal keeps all of its modules in one place, unlike many other CMSes. This has many benefits, and has helped to keep significant licensing problems to be an issue in the community. Also, a standard module release process allows both developers and administrators to have a clear path forward with module upgrades and choosing the correct module version for the Drupal version they use

#3 - Drupal is a Framework

For developers, Drupal does a lot of heavy lifting and really lets you get plugged virtually anywhere in the platform. The module structure encourages good coding practices and good organization.

#4 - Drupal is Mature

Drupal has been actively developed for 8 years, and lots of big web sites are using it, like the White House, The Onion, Fast Company, BMG Records, NASA, Warner Brothers and Yahoo Research. Even if you don't understand the nuances of security and scalability, you can point to hear examples of how Drupal must provide a solid framework for both.

#5 - Flexible Data Structures

Drupal allows you to create flexible content, much like Access or Filemaker, and even creates full CRUD (Add, edit, view and delete forms) on the fly. So, storing custom content is easy, and doesn't require any programming or touching the database. (video includes demo)

#6 - Flexible Content Feed Output

Once you have content, you have many options for how you want to output the data. You can pass content filters via the URL or even expose filters to users so they can narrow down content based on whatever criteria you specify. The ability to generate these lists of data via configuration without touching queries or code can be a powerful administrative tool.

#7 - Flexible Path Aliasing

In Drupal, you can specify how you want a path to look based on virtually any information in your content, including title, date, or custom fields. Drupal can handle redirecting duplicate URLs (also called aliases) to a single URL with a 301 redirect to prevent a duplicate content filter in search engines.

#8 - Multi-Language Support

Including another language is trivial, and you can even override content within the same language. There's community infrastructure to support translators even if they don't know how to use, install or develop in Drupal.

#9 - Making Forms is a Breeze

Creating forms in Drupal is as easy as creating content types, and can be done without any programming. If you do need to program a form, however, there is a powerful API which will allow you to generate a secure, robust form in just a couple of steps. There is also a nice utility for generating module configuration forms.

#10 - A Bunch of Other Stuff

Including distributions for intranets and social aggregation, cross-database compatibility, an active usability team, hierarchical taxonomy, a powerful theme layer and AJAX framework.

Post-presentation discussion

During and after the presentation, there were a lot of great questions and discussion about topics like:

  • How does Drupal store content types?
  • Can Drupal work with obscure databases like BDB?
  • How do you create a wiki in Drupal?
  • How much does Drupal break from one version to the next?
  • How difficult is the upgrade process from one Drupal version to the next?
  • How much of this stuff is handled by core Drupal, and how much by contributed modules?
  • What versions of MySQL and PHP are the different Drupal versions compatible with?
  • How many people non-developers use Drupal?
  • Discussion on ecommerce solutions for Drupal

Syndicate content Syndicate content Syndicate content Syndicate content Syndicate content