Tuesday, October 16, 2012

Setting up Dreamweaver CS6 with SVN + SSH

I have a customer that has website source code (mostly php) in svn. There is a tidy deployment process whereby commits to trunk are automatically deployed to the test server and tags (with a certain prefix) are automatically deployed to production. This is done using post-commit hooks.

Up until this point they have been using Eclipse to edit the website source files and commit/tag to svn. Eclipse is what we programmers are most familiar with and it worked for this website for years. However, the new web manager wanted to use Dreamweaver instead. Eclipse can be foreign and uncomfortable to a non-programmer and Dreamweaver has extra tools that she was used to. She initially started sneakily working in Dreamweaver and copying files back over to the machine where her Eclipse workspace was in order to commit and tag. That won't do at all, so I started doing research and found that Dreamweaver has svn integration built in. Great!

Except it wasn't so great. If you Google around a little you will find more than a little rumbling about the challenges that face anyone who dreams of using this feature. My problem was that despite following the official instructions to the letter, it just wasn't working. The error message, "Server and project are not accessible! (Can't create tunnel: The system cannot find the file specified.)" didn't tell me much. (Which file? Specified where?) To make matters worse, for whatever reason we only had access to CS6 on Windows. That meant working with svn and ssh on windoze, oh no!

Here are the pieces that we had installed on the windows machine:
FWIW, this machine happens to be running Windows Server edition 2008 R2.

First I wanted to get ssh working, so I tried using PuTTY. I could ssh to our svn server if I provided a password. That's a good start. I already had ssh keys set up on the svn server and so would my customer, so I wanted to figure out how to get the existing key to work on Windows. It turns out that you have to convert the key. To do this:

  1. Run PuTTYgen. 
  2. Click the "Load" button to lead an existing private key file. Enter your passphrase as needed. 
  3. Click "Save private key" to save your key as a PuTTY format private key (I called mine private.ppk)
Then you have to register this key so that you can ssh without a password. To do that, you need to run Pageant. 
  1. Run Pageant if it isn't already running. When it is running you will see it in the bottom right tray area. It looks like a little computer wearing a black hat(?) 
  2. Right click and select "View Keys".
  3. If you don't see your key there (and you won't the first time) then click the "Add Key" button. Navigate to your private.ppk key and add it.
At this point you should be able to ssh via PuTTY without having to enter your password.

At this point we thought that we might be able to connect to svn from Dreamweaver, but all attempts failed. I didn't initially get it from the official instructions that anything else is needed. But,  you need to have a SVN client installed, so we got TortiseSVN. 
One more step: Edit this file
C:\Users\[[Your User Name]]\AppData\Roaming\Subversion\config. 

In the [tunnels] section, specify where ssh client exists. This location depends on where you installed it. Open the file and enter the following within the tunnels section (underneath [tunnels])To use key-based authentication, add -i PathToKey. E.g.

ssh = $SVN_SSH C:/PathToSSHClient/tortoiseplink.exe -i PathToKey

Once you get that installed and you can checkout from svn outside of dreamweaver you are very close.

The final trick was the actual settings in Dreamweaver when setting up version control. This was the magic combination that worked:

Protocol: SVN+SSH
Server address: svn+ssh://[[Your SVN User Name]]@svn.server.domain
Repository Path: /the/path/to/your/project/in/svn/trunk

The piece that I was missing at first was the user name in the server address field. For us, it didn't work without that.

So, there you have it. Now we can checkout, check in from Dreamweaver! No more sneaking files around just to be able to use the right tool for the job.

Friday, April 6, 2012

Best Training Ever: Internal Drupal Hackathon at Goodwin College

I just wrapped up a week-long training with my development team today and this was the best training ever: we eschewed the traditional bring-in-the-expert-to-drone-over-some-powerpoint model and styled our week-long training as a hackathon instead.

There were six developers from my team and two from another department all looking to learn how to use Drupal for different projects. These are real projects with real (internal) customers and we all thought that Drupal might be the right tool for the job, but none of us knew how to use it very well. Some of us had played around with it, but some of us hadn't. For one person it was their first time working with a cms. For me it was my second time getting my hands on a drupal instance.

We didn't know how to develop for it as a platform and we didn't know how to install and configure it so that it would be a reliable and secure content management system for our customers. We didn't know how we would set up our dev, test and production workflows, and we just plain didn't know where to begin wading through the sea of modules to find the right tools for our specific needs. Our boss hired an outside consultant to join us for the week to either teach us or work along side us for the week, whatever we needed. We really lucked out getting Tim Plunkett from Zivtech--this guy is an active contributor to many of the Drupal modules that we ended up needing. He knows his stuff and he was excellent at not only teaching us what we needed to know but also teaching us how to find answers when it comes to Drupal and its many modules.

Why was it so awesome?


I have never, ever, learned so much in such a short period of time. It was so efficient. I felt like I was in flow most of the time. I felt that rare electric feeling like the whole room was in flow, like we have never been as a group.

Learn by doing--it's how I learn best; it's how a lot of us learn best. Even better was that because we were all learning different things at different times I had opportunities not only to learn but to teach what I just learned to someone else. This cemented my learning, in a matter of hours, not weeks. On that note, I am sure, SURE, that what I accomplished on the second day would have taken me at least two weeks on my own. That feels amazing.

Here's how it worked


For the most part it was one (or more) project per person, but I was actually on a team with one other developer because our project has a deadline of April 16th (just over a week after the hackathon--ambitious!).

Here were some of our projects:
  • Porting of some static html to CMS with theming (this was mine--with the short deadline), laying groundwork for future massive site migration in to CMS
  • Porting a wiki-based site to Drupal to take advantage of better add-on functionality
  • Q&A site for teachers (replacing existing software)
  • Faceted search/browse prototype for a customer with a ton of diverse but related content
  • Hardware inventory/maintenance history logging system for sysadmins
  • Massive open online course platform
  • Site for alum-teachers to share videos and other resources with each other

Ahead of time

Ahead of time we set up a wiki page to keep track of the projects and all of the Drupal questions we had going in to the week. I set up a rough agenda that basically said on the first day we each talk about what we are going to do during the week, then each day we work and stop in the middle to check in (or show and tell) and then on the last day we have final presentations. That's it. I wanted to keep it simple and informal so that we could get as much done as possible. We got some budget to buy snacks and pizza for the week and I found us a room that we could use each day for a whole week (surprisingly difficult!). My colleagues and I agreed that it was important that we get away from our desks if we were going to be able to really focus on learning and getting deep in to Drupal quickly.

The week before I sketched out a layout for the room, a rectangle of tables, with enough room so that the consultant or other people could hop in between people. We sent out invites to our internal customers, asking them to stop by for a check in or to give us some feedback. The Friday before my colleagues helped to set up the room, with my colleague Amir making sure that we had things like an ethernet switch, lots of ethernet cables and power strips and even laptop locks. We checked on things like spare monitors, mice and keyboards, which were conveniently around the corner in the main IT office if we wanted to borrow them.

We checked in with Tim, our consultant, to pick up some best practices for getting our dev environments ready. He suggested things like setting up a space in source control for each project and having php, drupal and drush installed and in the right versions.

The hackathon week began

Once we were all there and we got past the initial introductions and started working it was like magic. I was never stuck, wrestling with a bug or a mystery. Either Tim had the answer, or could find the answer or one of my colleagues had it. When enough of us wanted to see something Tim would do a demo for the group and then we would get back to work. People would bounce around the room from time to time, sharing things they had learned and asking questions. We worked like crazy all day and I never had that feeling in the afternoon like I needed a nap--I was actually energized at the end of the day. (I am exhausted now, but it's a great exhaustion, like after an amazing long run.)

We did check-ins each afternoon, except Wednesday we did a mid-week show and tell just to share what we had learned and accomplished so far. This helped us identify people who had already done the things we needed to figure out how to do. I wrote the first module on Tuesday. Well, it was mostly Tim telling me exactly the words to type and what files to create, but it was a very effective tutorial on module building and a first glimpse for me in to some of the APIs and how Drupal works. On Thursday I learned features and had packaged up my work from the first half of the week in to a feature that could be checked in and pushed out to the other development instances.

About mid-week we realized that a lot of our projects were for different parts the same internal customer's (massive) website and so they should actually live in one big Drupal instance. That required a new project, which was the multi-project multi-developer infrastructure and workflow project. Prior to that we had all been playing in our own sandboxes. By the end of the week we had a solution figured out and the development layer set up so that we could develop features and push them out to each other and keep our development instances in sync. Amir even had a prototype of a staging instance and a workflow for deploying up from development with a plan for how that would work for production too.

In the end we covered just about everything that we had hoped to cover and in a lot more depth than I had imagined possible. We made real progress on real projects and we know a lot of how to do what we have left. Plus, we have learned how to figure out the rest.

So what's next?

At the very end of the event I led the team in a retrospective and almost everyone mentioned that we should do this again. There are a few things that we might do differently, like nail down or narrow down our goals to get even deeper and further along on fewer things or set up a better way to organize common questions and answers that have come up so that we can more efficiently share the knowledge we have gained between us. On the whole everyone loved it and we hope we get to do this again and again and again.

My question is why can't every week be like this at work? Is your work like this?

Tuesday, August 23, 2011

Show all blog posts on multiple static pages in WordPress

I am working on a hybrid blog/website project using Wordpress and I had a special request come in from one of my clients; He wanted his home page to be a static page, which is easy to do, but instead of having another page as the blog posts page he wanted two blog posts pages. The sidebar would be different for these pages, but the posts would be the same. His reason for this made sense, so I went about looking for a good way to implement it. Using the Reading settings you can only set one page as the posts page. Plus, I wanted to be able to specify a different layout (really just the sidebar is different) for each page, so I couldn't use the Reading settings for this.

The way I addressed this was to create two Pages. I created the layouts for each page with my iThemes Builder Style Manager plugin. Then I created a new page template, so that the pages would display posts instead of the page content. I took my theme's single.php code and expanded it so that it would show all of the posts plus the static Page's title at the top. I copied the loop code from my theme's single.php file. Below you can see the part that I changed, which is just the top part of the file:
<?php
/**
 * Template Name: Posts Page
 *
 * A custom page template for DataPoints
 *
 */
function render_content() {
?>

<!-- Display the page title -->

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
 <div class="post">
  <!-- Display the Title as a link to the Post's permalink. -->
  <h1><?php the_title(); ?></h1>
  <hr/>
 </div>
<?php endwhile; endif; ?>

<!-- Show all of the blog posts -->
<?php query_posts( 'posts_per_page=5' ); ?>
<?php if ( have_posts() ) : ?>
  <div class="loop">
   <?php while ( have_posts() ) : // The Loop ?>
    <div class="loop-content">
     <?php the_post(); ?>
<!-- The rest of this is identical to my theme's single.php file -->
...[SNIP]...

Monday, November 22, 2010

Listing Sub-Pages on your Page in WordPress

I know I'm a WP noob, but this took me about an hour to figure out. Maybe I can save someone else some time.

Most of the code below comes from the WordPress docs, but there was one critical piece missing, $post->ID was returning nothing, even though I was in "the loop". I got around that whole thing once I learned that you can get the page id with get_the_ID().

<?php
// display only this page's children
$my_id = get_the_ID();
$subpages = wp_list_pages("title_li=&echo=0&depth=1&child_of=".$my_id);

if ($subpages) { ?>
<h2>Sub-topics</h2>
<ul>
<?php echo $subpages; ?>
</ul>         
<?php } ?>

I am using WordPress 3.0.1, if that helps anyone.

Wednesday, October 6, 2010

Product Sashimi is delicious!

On Saturday I participated in a Product Sashimi workshop with J. B. Rainsberger and Bonnie Aumann.

This workshop was all about learning how to "slice a product thinly" so that you can actually ship something of value quickly. We also spent a lot of time working on how to help turn a fuzzy customer product idea into something concrete that you can start to work on. I summarized it to my team like this: You customer comes in and they are usually asking for a whale. At the end of the project what they really wanted was a crab. Your job is to start from their request for a whale and 1) trim the whale down to the meaty parts they really want/need and 2) slice that meaty part thinly so that you can actually start development and deliver value soon.

I happen to work in an academic environment where my customers are colleagues with ideas for software and tools that will help their research or will be used internally for staff. No money actually changes hands for each project, but my team is a scarce resource and we have a lot of projects to handle, more than we can actually deliver. It's not that different from when I was a consultant with paying customers who need the maximum solution at minimum cost and they need it yesterday. You always want to get to delivering value as soon as possible, which means slicing the problem thinly, and you want to make sure that you know you are working on the most valuable things first, which means understanding their business and their needs.

The biggest challenge is understanding what the customer is asking for. Often times they struggle to put it in to words. Sometimes they can describe the solution they are looking for, but it doesn't match the problem they are describing. As knowledgable tech resources we immediately want to get to the meat of what they want, so our first question is "why do you want that?". A great reminder that J.B. and Bonnie kept mentioning is to consider how what you say sounds to the customer. Have you ever had an exchange like this:

Customer: I want an X. Can you make that for me?


Dev: Why do you want X?


Customer: What do you mean, 'why do I want that'?!

Depending on your tone and your relationship with your customer it can sound like you are questioning their own judgement of their needs, when in fact you are really just trying to understand their needs better. J.B. Gave a lot of great examples for what you can say instead. I won't give them all away, but one of my two favorite takeaways from the workshop was the Magic Wand technique.

Customer: I want an X. Can you make that for me?


Dev: Okay, (using imaginary magic wand) TADA! You have an X. Tell me a little about how you are going to use it.


Customer: Well...

This is going to go much better than the example above. It takes a lot of practice to get good at posing those questions.

My second favorite technique is the Lost Luggage Technique. Have you ever been the last one waiting for your bag to arrive on the luggage belt at the airport and then the belt shut off? So you go to the little room and tell them your bag is missing. Usually they will hand you a laminated sheet with pictures of suicases on it and ask you "which one of these does your bag most closely resemble?" followed by "How does your bag differ from the one in the picture?". This is a great technique because it grounds the conversation in something concrete and focuses both of your attention on the ways in which your understandings of the object in question differ.

For example, the customer describes what they want. It sounds a lot like a blog to you. So you say, "What if I give you a WordPress blog? What more do you think you need?"
and then listen to what they say. Oh, and write it down. Maybe they don't know everything a blog is capable of, so you might share that with them and check again. At this point it is all about listening, and keeping the conversation grounded in concrete terms as much as possible.

As you are listening and writing down what you are learning this is when the sashimi slicing begins. First you want to want to figure out the scope of this
You have to identify the simplest most barebones solution that could possibly fit the description of what the customer needs and then build out from there to find a simple solution that you can actually deliver. As J.B. put it succinctly, the goal is to learn what you don't have to do and try not to do it.

Once you have cut down the big fuzzy product description into a smaller fleshy piece now the slicing begins. In the training we went over techniques for identifying the major problem areas (maybe 4-8 of them) and then breaking those down in to features and then generating scenarios for those features.

I just gave my team a recap of some of the things that I learned at the sashimi workshop and it started a great discussion about how we are doing in understanding our customers' needs, how to define what is good enough (if you and your customer are both happy could you still not be done?) and even a quasi-role-playing session with our boss as the customer for a real request that had just come up. I am going to need a lot of practice asking those gently leading questions like "Tell me more about how you'd like to use that" and "I'm curious how you came up with the idea of a X".

When we got out of the meeting another one of our internal customers came over with a real request and we decided to see if we could use our new skills to help us learn more about what she is asking for. They ended up beating her with imaginary magic wands, but at least they didn't start off with "Why do you want that"!?!

I did successfully apply the lost luggage technique earlier this week. It's such a simple technique. I found myself with another developer and a customer and we were all talking in abstract terms about a report that she wanted. So, I drew a picture and I said "What if this was the report? would that meet your needs?" and the conversation became much more productive after that. A lot of practice is definintly needed, but I feel like I'm already getting value out of these techniques. I really wish this workshop was a month long so that I could soak up and really practice all of the things that Bonnie and J.B. were sharing with us.

Wednesday, August 25, 2010

Agile Philly Code Kata Night August: Architectural Katas

Thank you to Andre, Bonnie, Adam, Aaron and Sebastian for coming out to Code Kata night at the Math Forum! This was an experimental kata night in that we were trying out architectural katas for the first time.


In the beginning we went through a summary of the basic elements of architecture: communication/distribution, presentation/interaction, state management, processing, resource management and tools. For this we followed the slides that Ted Neward provided especially for this event and exercise. The idea is, roughly, that when you are designing the architecture of a system you have to consider each of these elements. I think we can all agree that one way or another requirements inform your technological choices. Asking questions about the system with regard to each of these elements can make it more likely that you don't miss support for a critical aspect of the system. Here are a few examples:


  • Communication/Distribution: In what format does data travel? JSON? XML? Over what medium? http? filesystem?
  • Presentation: What sort of perspectives in to the system do you need? do you need an admin console?
  • State Management: Does the state need to be persisted across different sessions?
  • Processing: Does processing need to be transactional?

Then we made two groups, each randomly selected a kata and spent 25 minutes trying to come up with a suitable architecture to meet the requirements. At the end of the time each group presented their proposal for 3 minutes and fielded 2 minutes of Q and A from me and the other group. I played the role of the customer/game master, answering clarifyng questions about the



I think it is fair to say that these exercises were hard. One of the exercises was to build a MMORPG. None of us had any experience building similar systems, so there were a lot of open questions about what was possible and how it could be done. I was probably not the best customer for this project either, since I have hardly seen a MMORPG before, let alone thought about how I would want one to work. Even if you are familiar with the domain and know about some of the relevant technology, it is still hard to cover all of the architectural bases in 25 minutes.



In the retrospective that followed the question came up, what are these exercises good for? Would this exercise really be valuable to the customer? Andre voiced his skepticism of architecture as a subject because that is not how he would ever work with a customer. As agile-minded folks, we prefer to see the architecture emerge as you are iterating and building the system with your customer. I don't think these exercises are really intended as practice for starting a project with a customer, although I may have set that up by calling myself the customer at the beginning of the exercise and saying that I would decide if I wanted to buy the system at the end. I like these exercises because it is an opportunity to wonder about how things work, and it piques my curiosity to go learn about technology that I haven't had a chance to use at work before (or yet?).



One benefit that we saw of these exercises is that they could get the whole team involved in design. Sebastian told us that his team actually does something similar on a regular basis. Pairs will take a card off the wall, think about how they are going to do it and "pre-sell" the approach to at least on the other pair (more for major changes). When the story is done they can present the result and the rest of the team has a chance to say "hey--that's not what you sold me!" which can help to reveal what the pair learned while they were building it. We also discussed ways of displaying architecture or the state of the system in the team area. One idea was modular printouts on the wall, legos or knex. All of these could be kept up to date as things changed. Sebastian once used the printouts as a progress chart, checking off parts of the system as they were completed.



All in all this was a fun kata night and I look forward to the next one. Many thanks to Ted Neward of Neward & Associates http://tedneward.com for letting us use his slides and architectural katas for our kata night.

Thursday, May 20, 2010

Setting up Alfresco 3.3 Community Edition Standalone Deployment Receiver for WCM

I'm trying out the latest edition of the Alfresco content management system community edition. This is a free, open-source content management system that can do both document and web content management (and much more). What my company wants to use it for is web content management (managing html, php, css, images etc. for our many websites).

We like open source software so we are trying to use the completely unsupported, not guaranteed OS version instead of the fully supported and tested enterprise version. Without support or thorough documentation I am on my own (with the help of generous community members) to get this thing installed, configured and up and running and to keep it that way.

One aspect of getting this project off the ground that was especially tricky was getting a Standalone Deployment Receiver working so that I could deploy content (again, html files, css, php) from my Alfresco repository on one machine to a folder on my web server. Here is how I did it:

Before I started I already had a Web Project in alfresco with some dummy content in it (index.html, and a directory with another html file in it).
  1. Downloaded Linux Installer for Standalone Deployment Receiver, Alfresco-DeploymentCommunity-3.3-Linux-x86-Install, from http://wiki.alfresco.com/wiki/Community_Edition_file_list_3.3
  2. Ran the installer (requires gui environment, expects to be able to pop up a window to walk you through installation)
  3. Accepted all defaults, including port numbers
  4. Started it up(start.sh)

Then I went to my web project in alfresco, and edited the web project settings and added a deployment receiver.  (My Web Project -> Actions -> Edit Web Project Settings -> Next -> Add Deployment Receiver) I added my remote machine as a test server.

Then I should be able to click My Sandbox -> More Actions -> Deploy, choose my test server and the content as it exists in my sandbox should be copied over to the remote server, but it didn't work.


Could not connect to remote service [rmi://144.118.94.157:44100/deployment]; nested exception is java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is: java.net.ConnectException: Connection refused

I did some googling around and found several people mention that you need to do two things: add a setting to JAVA_OPTS for your alfresco tomcat and set up /etc/hosts in a certain way. I tried a bunch of different things that were suggested, but here is what I did that actually resulted in a successful deployment:

1. Made sure that my remote server had the 44100 port open
2. Made sure the deployment receiver was running on my remote server
3. Added to catalina.sh (/tomcat/bin/catalina.sh) the following line near the top before the first time JAVA_OPTS is used:

JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=144.118.68.94"

4. Modify /etc/hosts on the alfresco server to include a mapping from its IP address to the domain name like this:

xxx.xxx.xx.xx mydomainname.com

xxx.xxx.xx.xx is not my real IP address, obviously. On the remote server I did the same thing, mapping its IP to its domain name and mapping the alfresco server's IP to the alfresco server domain name, although I'm not sure that was necessary.

5. Restarted alfresco and the remote server (and started the FSR on the remote server again)

Finally! I am able to deploy snapshots from my sandbox to a test server. By repeating the process and setting the second machine as a "Live Server" in the web project settings I am able to deploy snapshots of approved committed content from all users to another remote server. On the remote servers you can do whatever you want, like deploy your web content to a directory that an apache instance serves up and voila! you have a website.

FYI, here are some of the sources I used to piece together this soution: