Apr 02 2019
Apr 02

DrupalCon Seattle Gold Sponsors

Commerce Guys is joining forces with some of our Technology Partners and a variety of contributors to promote Drupal Commerce at DrupalCon Seattle from April 9-11, 2019.

We're excited to introduce the Drupal community to Centarro Toolbox, a collection of SaaS products and support packages that help Drupal Commerce teams build with confidence. First revealed at MidCamp last month, we can't wait to show it off to the community at large while also connecting about all things Commerce 2.x.

Come demo Centarro Toolbox (and grab some sweet swag)

There's a lot to see inside Centarro Toolbox!

It includes three of our own SaaS tools designed to complement any Drupal Commerce site. They provide update automation, code quality monitoring, and a sales and analytics dashboard that delivers key insights to merchants. We've also bundled in offers from our partners at Avalara, Human Presence, and Lockr, and we'd love to share all about them.

We'll be handing out some exclusive swag this year, including our first pressing of custom coins ... no clue why it took us a decade to think that up! We're also stocking the booth with some rad sweatbands to keep your brows clean at the after parties Dave Grohl style. Finally, visitors to the booth can enter to win:

  • 1 of 3 copies of Preston So's book, Decoupled Drupal in Practice (winner chosen at random each day)
  • An Xbox One courtesy of PayPal (winner chosen at random Thursday afternoon)

Drupal Commerce in the spotlight

There's a lot to be said about how Drupal Commerce is making merchant and agency teams more productive, and you don't just have to take our word for it. Add the following sessions to your schedule to learn more:

Last but not least, if you've made it this far, chances are you're really into what we're doing with Drupal Commerce. If that's you, we'd like to invite you to an exclusive reception at Avalara's HQ. We'll enjoy food and beverages from the 18th floor looking out over downtown Seattle. The party will be from 6:30 - 8:30 PM Wednesday, but space is limited! Reach out in advance or find us early at the show to reserve your spot.

Schedule Time to Meet

If you're heading to DrupalCon, we'd love to chat about Drupal Commerce with you. Use our meeting request form to get on our calendar to discuss a particular project or need, or subscribe to our newsletter to be kept in the loop more generally.

Feb 06 2019
Feb 06

At the end of 2018, Dries Buytaert, creator of Drupal, asked folks involved with the project to share their thoughts on what's "holding Drupal back." His prompt came on the heels of two great blog posts related to his company Acquia's growth strategy and lessons he's learned and applied from Amazon's growth strategy. I didn’t beat his third post on overcoming Drupal’s obstacles to the punch, but the series did prompt me to think long and hard about the barriers we face as maintainers and leaders of the Commerce project within the Drupal ecosystem.

For the entirety of our existence, Commerce Guys has focused on building and promoting Drupal as an eCommerce platform, first through Ubercart and then Drupal Commerce. While eCommerce is a huge industry, our reach within the community has only averaged around 5% of all Drupal sites. Given the diverse and varied types of users Drupal serves, I consider this relatively low number unsurprising. (A certain percentage will also choose to integrate third party shopping cart systems, but historically that’s always been a fraction of the number of Drupal sites using our native solutions.)

It’s tempting to be fatalistic about Drupal Commerce’s growth and accept that our growth rate will be pegged to Drupal’s own growth rate so long as our relative percentage holds. It actually is an important baseline to acknowledge - our success is tied to Drupal’s success, and so we prioritize contributing to initiatives that help improve Drupal’s core APIs, make it easier to maintain and upgrade, and attract new audiences through API-first / JavaScript initiatives. However, I think we can and should do better than just waiting for growth to happen upon us.

Why should I think we can do better?

After Dries’s posts last year I compared our usage statistics for Commerce 2.x (on Drupal 8) to our usage statistics for Commerce 1.x (on Drupal 7) at the same point in its life-cycle. What I saw convinced me we have plenty of room to grow:

  • In 2013, Drupal Commerce 1.x grew from 23,224 to 33,989 sites.
  • These numbers represent growing from 4.02% to 4.50% of all Drupal 7 sites.
  • Our average growth rate that year was 3.89% month over month; Drupal’s own growth rate was 2.72%.
  • In 2018, Drupal Commerce 2.x grew from 3,097 to 6,980 sites.
  • These numbers represent growing from 1.41% to 2.85% of all Drupal 8 sites.
  • Our average growth rate last year was 8.65% month over month; Drupal’s own growth rate was 1.23%.

Just based on those numbers, even though Commerce 2.x grew over twice as fast last year as Commerce 1.x did in a similar timeframe in its life-cycle, we still represent only half of the relative number of Drupal sites we did back then. We can double our user base on Drupal 8 without challenging our historical average representation at all. That’s good news!

Our growth rate right now is fantastic, especially compared to Drupal's own. There are likely a variety of factors at play here, but I think it boils down to some combination of recognized maturity, excellent word of mouth from a steady stream of case studies, and our contributed module ecosystem stabilizing to a point that Drupal 7 / Commerce 1.x sites are finally porting to Drupal 8 / Commerce 2.x. As our 2.x project lead recently observed, we’re now up to over 250 contributed modules on drupal.org and maintain a community support Slack channel with over 1,000 participants.

Eliminating barriers to growth in 2019

In order for us to keep up and even accelerate our rate of growth, Commerce Guys has been working hard to identify our barriers to growth and develop solutions to them. As a small team playing in a large market (against very well-funded competitors), we can only do so much … but every bit of progress on any of the following fronts will help.

1. Features and integrations

The biggest barrier to growth has historically been our under-developed contributed module and integration ecosystem. Ecosystem development is incredibly important - agencies don’t often have the expertise or confidence to develop new features or integrations themselves. Our major competitors (Magento, Shopify, et al) all have massive ecosystems that third-party software vendors take the initiative to join while our own ecosystem remains dependent on our own team or the core of our development community to expand.

2. Developer support and education

It’s tempting to point to performance and scalability as another barrier to growth, but we see poorly performing Drupal Commerce sites as a symptom of another issue - lack of exposure by the average Drupal developer to best practices for scaling sites with a large amount of authenticated (or otherwise cache-breaking) traffic. We know that we can scale Drupal Commerce to support 10,000+ transactions per hour and thousands of concurrent users, but we also know that otherwise capable Drupal teams struggle at a fraction of that scale. In other words, it’s not a capabilities gap, it’s a knowledge gap, and we’re to blame for not sharing what we've learned with our userbase.

3. Reaching our core audience

Finally, we’re hardly communicating to the market at all about why they should be choosing Drupal Commerce. Our websites are aging, and organizations who do decide upon Drupal are often confused about what sort of support, if any, we might offer them if they choose to adopt our software. We understand how our solution differs from other major players in the market and where it should be seriously evaluated (e.g. cross-border commerce, digital product sales, subscription billing), but we aren’t doing enough to demonstrate our capabilities or provide a vision for why merchants will be better off using Drupal Commerce than a competing application.

We certainly have our work cut out for us in 2019, but we’re encouraged by last year’s growth and the support of our friends and champions within the Drupal community. We believe we can work to eliminate these barriers to growth while building a sustainable business that allows us to grow without compromising our values. In reverse order, the basic roadmap we’re targeting to address those known-blockers above will be:

  1. Relaunch our company and project websites to more clearly communicate who we are, what our software can do, and how we support eCommerce teams to build with confidence on Drupal.
  2. Standardize our consulting efforts and support retainers into concrete, documented offerings that anyone can understand.
  3. Coordinate our development roadmap with more agency and technology partners to ensure essential contributed modules receive the attention they deserve and our integration roster continues to grow.

We'll be encoding our expertise into productized solutions that allow us to grow a team focused on ensuring eCommerce sites built with Drupal are optimized for stability, security, and scalability. We've always valued the impact we have on the Drupal community even as a small team, and we believe addressing these issues will afford us the opportunity to grow, broaden our impact, and grow Drupal itself as a result.

Jul 13 2018
Jul 13

I'm currently serving as one of two community elected At-Large Directors on the board of the Drupal Association. The D.A. supports Drupal in a variety of ways, including maintaining drupal.org, running DrupalCon, and marketing Drupal to foster its adoption and community growth. If you use Drupal at all, you benefit from the work of the Association staff, and I couldn't be prouder of the work they're doing. The team really is incredible, and it's been a pleasure to get to know them more this past year.

Serving on the board has also given me the opportunity to get to know the other board members, including the At-Large Director elected before me, Shyamala Rajaram. She has focused on helping the D.A. board and staff consider how to foster adoption and growth around the world, including in her home country of India where she is a Drupal agency leader and community organizer. Not only has she brought a unique perspective to these conversations at the board level, but she contributes with a humble, generous spirit that has led and served us well. Thank you, Shyamala!

Her term on the board is expiring, and the Drupal community is currently engaged in electing her replacement from a very qualified list of candidates. The D.A. is a key part of the Drupal ecosystem, and each member of the board has the ability to influence how it uses its websites, events, and marketing programs to support the project and foster its growth. Its influence is often indirect, but it is no doubt consequential.

Today is the last day to vote! Anyone who has used their drupal.org user account in the last year is eligible, and I encourage you to vote. Once you've reviewed the candidates, click the bright green "Vote now!" button in the top right hand of the election homepage. You can rank your choices in order of priority (1st, 2nd, 3rd, etc.), but you can also just pick one person as your 1st choice if that's all the time you have.

If you do vote, thanks for your contribution!

May 15 2018
May 15

On April 2, 2018, Acquia retired Mollom, a spam fighting tool built by Drupal founder Dries Buytaert. As Dries tells the story, Mollom was both a technical and financial success but was ultimately shut down to enable Acquia to deploy its resources more strategically. At its peak, Mollom served over 60,000 websites, including many of ours!

Many sites are looking for alternatives now that Mollom is shut down. One such service Commerce Guys integrated earlier this year in anticipation of Mollom's closing is Human Presence, a fraud prevention and form protection service that uses multiple overlapping strategies to fight form spam. In the context of Drupal, this includes protecting user registration and login forms, content creation forms, contact forms, and more.

Similar to Mollom, Human Presence evaluates various parameters of a visitor's session to decide if the visitor is a human or a bot. When a protected form is submitted, the Drupal module requests a "human presence" confidence rating from the API (hence the name), and if the response does not meet a configurable confidence threshold, it will block form submission or let you configure additional validation steps if you choose. For example, out of the box, the module integrates the CAPTCHA module to rebuild the submitted form with a CAPTCHA that must be completed before the form will submit.

We believe Human Presence is a great tool to integrate on its own or in conjunction with other standalone modules like Honeypot. Furthermore, they're joining other companies like Authorize.Net, Avalara, and PayPal as Drupal Commerce Technology Partners. Their integration includes support for protecting shopping cart and checkout forms, and we are looking for other ways they can help us combat payment fraud in addition to spam.

Learn more about Human Presence or reach the company's support engineer through their project page on drupal.org.

Apr 07 2018
Apr 07

Commerce Saloon sponsor badge

Commerce Guys is joining forces with some of our Technology Partners and several contributing agencies to promote Drupal Commerce at DrupalCon Nashville from April 10-12, 2018.

We are colocating our booths to create the Commerce Saloon, your one stop shop to learn all things Drupal Commerce. Our booths will feature jam band instruments, multiple demos (including a new store theme), exclusive swag, and case studies to help you learn how teams are succeeding with Drupal Commerce.

Come try Drupal Commerce 2.x

DrupalCon Nashville is the perfect time to learn what's new by joining our week long sprint at the "Power Up" tables by the Commerce Saloon. We'll be training new contributors and working on the project together using sprint kits powered by DRUD's ddev local development environment.

We prepared the following sessions to help you learn more about Drupal Commerce and its ecosystem:

  • Contributing to Drupal Commerce (for beginners)
    Tuesday, April 10th, 12:00 PM | Commerce Saloon: "Power Up" Table | By: Matt Glaman
  • Drupal Commerce 2.x Update and Roadmap Planning (add it to your conference schedule)
    Tuesday, April 10th, 3:45 PM | Room: 203A | By: Ryan Szrama / Bojan Zivanovic
  • Marketing and Selling the Drupal Commerce Ecosystem (as seen at DrupalCon Vienna)
    Wednesday, April 11th, 10:45 AM | Commerce Saloon: "Power Up" Table | By: Ryan Szrama
  • Decoupled Drupal Commerce / REST APIs (for developers)
    Wednesday, April 11th, 3:45 PM | Commerce Saloon: "Power Up" Table | By: Matt Glaman
  • Subscriptions and Recurring Billing in Commerce 2.x
    Thursday, April 12th, 10:45 AM | Commerce Saloon: "Power Up" Table | By: Bojan Zivanovic

Hear from every Commerce Saloon sponsor

There's a lot to be said about how Drupal Commerce is making merchant and agency teams more productive, and you don't just have to take our word for it. Each Commerce Saloon sponsor has something unique to teach you about succeeding in eCommerce, and we encourage you to seek them and their sessions out:

  • Acro Media (Booth 803) - Test drive Commerce POS at their booth and hear its business case from Becky and Josh! You can also purchase (for free) a limited edition Drupal Commerce t-shirt through Acro Media's demo site.
  • Authorize.Net (Booth 911) - Authorize.Net offers several payment tools that let merchants get paid securely online. We've joined forces to demo Accept.js, their new drop-in solution for PCI compliant payment.
  • Bluespark (Booth 908) - Bluespark contributed significantly to Commerce 2.x development via their Sport Obermeyer project (check out their awesome case study) and have long promoted Drupal Commerce as a hotel booking solution.
  • Commerce Guys (Booth 809) - Stop by for a demo of Belgrade, our new default store theme for Commerce 2.x, or for a demo of, Lean Commerce Reports, our first SaaS product that offers a plug-n-play sales dashboard for Drupal Commerce.
  • Drupal Commerce Technology Partners (Both 811) - This booth features representatives and demos from Avalara and Lockr. Talk to them about tax automation and about eCommerce security respectively.
  • MailChimp (Booth 813) - MailChimp has revitalized their approach to eCommerce email marketing and has a full integration available for Drupal in the MailChimp eCommerce module. Stop by to learn more!
  • Zivtech (Booth 909) - Zivtech has a long history of implementing eCommerce in Drupal, including joining the Drupal Commerce project in late 2009. Talk to them about using Drupal Commerce as a front-end for third party applications.

Finally, be sure to catch Promet Source's showcase session on helping The Corning Museum of Glass migrate from Commerce 1.x to Commerce 2.x and Rick Manelius's session on the dos and don'ts Drupal Commerce project estimation.

Schedule Time to Meet

If you're heading to DrupalCon, we'd love to chat about Drupal Commerce with you. Use our meeting request form to get on our calendar to discuss a particular project or need, or subscribe to our newsletter to be kept in the loop more generally.

Feb 24 2018
Feb 24

Many of my longest friendships were born in the Drupal community. I’ve been attending DrupalCons, Drupal Camps, and other events since DrupalCon Barcelona 2007 and centered most of my professional life around contributing to the project as a developer and a teacher. In 2010 that included serving as a mentor in the Google Summer of Code program for a new contributor who wanted to work on Drupal Commerce’s affiliate module, bojanz.

Bojan at MCDonald's

Bojan Živanović and I got to know each other that summer through many IRC chats and coding sessions. After he completed his project successfully, we met at DrupalCon Copenhagen and celebrated at McDonald's. I sure knew how to treat a friend! Wink

I later convinced him to join Commerce Guys’s development team based in Paris. He served on our client services team before diving head first into Commerce Kickstart 2.x development and then creating a whole suite of modules to support usage based billing for subscription services like Platform.sh.

Around DrupalCon Austin in 2014, it appeared Bojan's mission with Commerce Guys might be complete. However, I saw an opportunity for him to develop further as a leader in our company and community. I was already busy leading client services with our U.S. team and then with acquiring and refocusing Commerce Guys around Drupal Commerce. It made perfect sense to me to appoint him to be project lead for Commerce 2.x.

That decision has served Commerce Guys and Drupal Commerce well over the last several years. Bojan brought renewed vigor to the project and discipline around competitive research and automated test coverage that far exceeded my own. He's also proven to be an able mentor in his own right, helping dozens of contributors and whole agency teams learn Drupal 8 development in general and Commerce 2.x development in particular.

Today is Bojan's birthday, and reflecting on our almost 8 years of friendship has obviously made me sentimental. At our first meeting in Copenhagen, my daughter Éowyn was just taking her first steps and wouldn't ever remember meeting Bojan. Today she sees him regularly during company Zoom calls and his occasional visit to our home in Greenville, SC. He's not just some random person from daddy's work, he's Uncle Bojan and a trusted friend.

We're all wishing you a happy birthday, Bojan, and we're grateful for your years of contribution and leadership in our midst. I'll have to hit the 2.x queue this evening to send you a birthday present disguised as a patch.

Feb 22 2018
Feb 22

When Commerce Guys raised $5m in 2012 to grow Drupal Commerce and its ecosystem, we invested a big chunk of it in improving our user experience for both customers and administrators. With competing platforms like Shopify and Magento really coming into their own, we knew it was essential to provide a solid out-of-the-box experience. While Drupal Commerce was and is truly unique as an eCommerce framework natively extending and deeply integrated into a CMS, it turns out "flexibility" doesn't pitch nearly as well as a polished demo.

Investing in Drupal Commerce adoption

The product we developed to address that need is Commerce Kickstart, by far the most popular Drupal distribution ever built. I named it such to underscore the fact that we intended it to be an accelerator, both for Drupal Commerce's own adoption but also for newcomers wondering how to demo and develop with the software. At its height, we supported over 13,000 sites reporting in to drupal.org, and we continue to see new sites launch with it to this day.

Building the distribution proved to be a fantastic learning experience. The project drove improvements that worked their way into many contributed modules and Drupal core itself (e.g. contributions to Views, VBO, Entity Reference, Inline Entity Form). Its broad appeal also gave us a platform to invite Technology Partners to invest in the community in a way that Drupal hadn't seen before, many of whom continue to invest in Drupal today (e.g. Authorize.Net, PayPal, Avalara).

It was a ton of work, but Bojan, Jonathan, and their team accomplished everything we set out to do and more. With the release of Commerce 2.0 last fall, we now find ourselves regularly fielding the question, "What's the plan for Commerce Kickstart on Drupal 8?" The reality is, porting Commerce Kickstart as it is to Drupal 8 would be both too costly for our team today and a poor strategy for the way the Drupal market is developing. We're doing something new again.

Accelerating adoption today

Another frequent question we field is, "Why does Drupal Commerce require Composer?" Composer is often highlighted as a barrier to Drupal 8 adoption, and I can understand why. I always felt the same way about drush. I had a UI; why did I need a CLI? I had my process and never had to battle the command line to make sure drush worked, was up to date, and did what I expected. I always felt that way ... until I buckled down and learned it. Now I can't imagine using Drupal without it.

I felt the same about Composer at first, but I was determined to learn how to use it as I learned Drupal 8 and modern PHP in general. I know I'm not the only person suffering from tool fatigue (cf. Dries ; ), so we're doing what we can to help you ease into using Composer on your own terms.

We started by releasing Ludwig last summer, a Drupal project that lets you manage Composer dependencies similarly to the familiar Libraries module. We also expanded and documented a Composer project template that lets you create a new Commerce 2.x site with composer create-project, and we then began planning how to let users customize a project template via the browser while prototyping a GUI for Composer.

With today's release of the new CommerceKickstart.com, developed in partnership with Acro Media (thanks to Shawn McCabe, Mike Hubbard, Jace Bennest, et al), we're taking the next step!

Commerce Kickstart for Drupal 8

What you'll find there is that Commerce Kickstart has been reimagined for Drupal 8 rather than rebuilt on Drupal 8. The quickest way to get up and running with Drupal Commerce today is not through a distribution as it was 6 years ago, it's through Composer. This is the tool for modern PHP developers, and we see prioritizing Composer while also making it simpler to use as essential to growing Drupal Commerce adoption both from without and within the Drupal community.

While still in its infancy, CommerceKickstart.com presents a form that lets you construct a Composer JSON file ready-made to support Commerce 2.x and the contributed modules you specify. Module categories include payment and shipping providers, product catalog and search tools, data migration, and more. As with Commerce Kickstart 2.x, it features Technology Partners whose modules we have integrated into Commerce 2.x, and we expect the selection to continue expand.

Future plans for the tool include clarifying and improving the tool's usability, adding additional modules and Technology Partners, and evolving it to continue to lower the barrier to entry for new Composer users. If you give it a whirl, we'd love to hear your ideas as well in the Commerce Kickstart issue queue.

Nov 01 2017
Nov 01

Drupal Commerce is more than just a module project. As I laid out in my session at DrupalCon Vienna, it is an entire ecosystem supported by dozens of agencies and powering well over $1.5bn in online transactions annually. This makes Drupal Commerce one of the largest open source eCommerce projects in the world, and it's thanks in no small part to our Technology Partners (comprised primarily of payment providers) that we are able to invest as much of our time in it as we do.

Braintree is one such partner and a fantastic supporter of Commerce 2.x since last Summer. During our sprint to release a beta at DrupalCon Dublin, they sponsored Bojan's time for two weeks to expand and improve the core Payment API.

As a result, they also became the first integrated payment gateway and the test case for any payment provider following their integration pattern - individual iframes embedded into the checkout form for each payment field, making it easy to securely collect payment card data through your own checkout form.

For the initial release of the Commerce Braintree integration on Drupal 8, we targeted basic credit card payment support via their Hosted Fields API. As of this week, we've finalized patches that add support for PayPal Express Checkout and PayPal Credit alongside credit card payment through Braintree. They are a PayPal company, after all!

PayPal Express Checkout modal in Commerce 2.x
Customers can pay via credit card on-site or Express Checkout via a modal dialog.

You can test the new features end to end by grabbing the latest release of the Commerce Braintree module and configuring it to work through the Braintree sandbox. If you get stuck, you can find us in the #commerce channel in the Drupal Slack or open an issue in the queue if that's not possible.

Thanks again to Braintree for their support and development sponsorship. If you'd like to learn more about how Technology Partners benefit our ecosystem, consider joining me and Commerce Braintree's D7 co-maintainer Andy Giles this weekend at DrupalCamp Atlanta (Nov. 3-4). I'll present a longer version of my DrupalCon session, Marketing and Selling the Drupal Commerce Ecosystem, and naturally I'll tap Andy to help me answer all your hardest questions. ; )

Jul 20 2017
Jul 20

Last weekend I had the pleasure of attending Drupal Camp Asheville 2017 ('twas my fourth year in a row : ). I absolutely love this event and encourage you to consider putting it on your list of Drupal events to hit next year. The Asheville area is a beautiful (and delicious) place to spend the weekend, but the bigger draw for me is the people involved:

Drupal Camp Asheville is always well organized (props to April Sides et al; seriously, it's in the best of the best small conferences for venue, amenities, and content) and attended by a solid blend of seasoned Drupal users / contributors and newcomers. I live only an hour away, so I get to interact with my Drupal friends from Blue Oak Interactive, New Valley Media, and Kanopi on occasion, but then on Camp weekend I also get to see a regular mix of folks from Mediacurrent, Code Journeymen, Lullabot, Palantir, FFW, CivicActions, end users like NOAA, and more.

This year we got to hear from Adam Bergstein as the keynote speaker. Unfortunately, that "we" didn't include me at first, as I managed to roll up right after Adam spoke ... but his keynote is on YouTube already thanks to Kevin Thull! I encourage you to give it a listen to hear how Adam's experience learning to work against his own "winning strategy" as a developer (that of a honey badger ; ) helped him gain empathy for his fellow team members and find purpose in collaborative problem solving to make the world a better place.

I gave a presentation of Drupal Commerce 2.x focusing on how we've improved the out of the box experience since Commerce 1.x. This was fun to deliver, because we really have added quite a bit more functionality along with a better customer experience in the core of Commerce 2.x itself. These improvements continued all the way up to our first release candidate tagged earlier this month, which included new promotions, coupons, and payment capabilities.

Many folks were surprised by how far along Commerce 2.x is, but now that Bojan has decompressed from the RC1 sprint, I expect we'll start to share more about the new goodies on the Drupal Commerce blog. (If you're so inclined, you can subscribe to our newsletter to get bi-weekly news / updates as well.)

Lastly, I loved just hanging out and catching up with friends at the venue and at the afterparty. I played several rounds of a very fun competitive card game in development by Ken Rickard (follow him to find out when his Kickstarter launches!). I also enjoyed several rounds of pool with other Drupallers in the evening and closed out the night with cocktails at Imperial Life, one of my favorite cocktail bars in Asheville. I treasure these kinds of social interactions with people I otherwise only see as usernames and Twitter handles online.

Can't wait to do it again next year!

May 03 2016
May 03

Three months ago Commerce Guys separated from Platform.sh to refocus the business around Drupal Commerce. Even as a three-person team (we're now four - welcome, Doug!), we worked hard to dedicate Bojan completely to Commerce 2.x in anticipation of DrupalCon New Orleans. As I discussed in the most recent DrupalEasy podcast, this resulted in great progress both for Commerce 2.x and for Drupal 8 itself. (It also kept us near the top of the most prolific contributors to Drupal. : )

While we're preparing to present the latest in Drupal Commerce in our session at 10:45 AM on Thursday, we're also getting ready to sprint on Commerce 2.x the full week from our booth. This will be our first opportunity to jam on code as a full team since our spinout, and we'd love to have you join us.

Look for us near the permanent coffee station (intentional) beside Platform.sh and Acro Media, our delivery affiliate in the U.S. whose partnership and vision for enterprise Drupal Commerce have been invaluable as we've rebooted our business.

If you'd like to get up to speed on the current status of development, we recommend the following resources:

Naturally, we're happy to help anyone begin to contribute to Drupal 8 / Commerce 2.x. Bojan has mastered the art of integrating developers from a variety of agencies of all skill levels into the development process so far. For an espresso or a Vieux Carré, he may even train you, too. ; )

Feb 09 2016
Feb 09

Commerce Guys has long been a leader in the development of e-commerce websites using Drupal, with our flagship Drupal Commerce project running on over 60,000 sites. We are now releasing alphas of Commerce 2.x for Drupal 8 every two weeks, with alpha3 up next. Our first production ready beta is scheduled for end of March, but developers are already using our standalone libraries for addressing and currency localization in production. Written to support Commerce 2.x, these libraries gave us a chance to share our knowledge and experience with the broader PHP world.

Over the last several years, we have also developed and launched a second generation Platform-as-a-Service for web applications, Platform.sh. With thousands of customers and an ever expanding list of supported technologies, Platform.sh is now becoming an independent company led by my two partners, Frédéric Plais as CEO and Damien Tournoud as CTO. With the full support of our existing investors, Platform.sh will use this move to grow and adapt to meet the needs of the new development communities it serves.

As the remaining founder, I have acquired Commerce Guys' Drupal Commerce business. I am succeeding Fred to manage the company as its President / CEO and will lead it to refocus on the development and support of Drupal Commerce and its community. My co-maintainers, Bojan Živanović and Matt Glaman, will continue to lead our software development and consulting programs respectively, with goals to achieve a Commerce 2.x release candidate by DrupalCon New Orleans (join us! : ) and to offer more strategic consulting and support to companies implementing Drupal Commerce.

Finally, we are adopting a new operating model whereby we deliver full Drupal Commerce projects through exclusive regional affiliates. I'm pleased to announce two launch partners, Actualys of Paris, France and Acro Media of Kelowna, BC, Canada:

  • Actualys has acquired Commerce Guys’ France-based services team and clients. They will deliver Drupal Commerce projects as Commerce Guys France and facilitate promotion and development of the software in France, Switzerland, Belgium, and Luxembourg.
  • Acro Media has acquired Commerce Guys’ U.S.-based services team and clients. They will deliver Drupal Commerce projects in affiliation with Commerce Guys in the United States and Canada and are dedicating developers and designers to the development of Drupal Commerce (and especially Commerce 2.x).

We expect to deliver strategic consulting services to these and other agencies and to deliver projects in territories not represented above. However, we do plan to engage additional affiliates in strategic territories throughout 2016.

Jul 04 2015
Jul 04

A friend of mine is a DUI lawyer who uses a Drupal site for content marketing and lead generation, managed by my friends at EverConvert. They quickly identified the weekend as the best time for the website to directly appeal to visitors who found the site after a Friday or Saturday night arrest. In addition to live chat, they decided to alter the site's appearance by publishing content only during these times that contains large, direct calls to action.

Fortunately, Drupal provides the tools to build this with nary a line of code.

Introducing the Rules Scheduler

The primary module you'll use to create something similar is Rules with its Rules Scheduler sub-module. Most purpose built content scheduling modules that I've seen allow you to set absolute dates for pieces of content to be published or unpublished. However, you wouldn't want to have to enter in every single weekend date to get that content published at the right times. Fortunately, Rules Scheduler allows you to schedule arbitrary actions using relative date strings (in addition to any other format supported by strtotime()).

Before we dive into the configuration I proposed to them, you should understand that the Rules module basically adds a GUI based scripting language to the back end of Drupal. In addition to configuring actions to be performed after certain events when a set of conditions are met, you can create Rules components that are essentially subroutines that can be directly invoked by Rules (or code) without being triggered by events.

To setup a Rules Scheduler based content publishing schedule, you have to create two Rules components: one will publish the piece of content and schedule it to be unpublished on a relative date (i.e. "next Monday"), while the other will unpublish the piece of content and schedule it to be published on a relative date (i.e. "next Friday"). Another Rule will need to react to content being created or updated to initiate the publishing schedule.

Using Fields to Avoid "Magic" Behavior

One of the keys to building a maintainable Drupal site (or module) is to ensure that every "automated" action is explicitly enabled. In the early days of Drupal Commerce development, I adopted an approach to some module behaviors where a feature just automatically worked if certain conditions were met (e.g. the representation of attribute fields on Add to Cart forms). "Neat!" I thought, until I realized that it was difficult to document and even more difficult to ensure users knew to look for said documentation. Much better to include explicit user interface components to enable functionality.

In the case of a scheduling system, you wouldn't want to build the site to just automatically enter every piece of content, or even every piece of content of a certain type, into the publishing pattern. Your client, a.k.a. the end user, really expects (and needs) to see an indicator on a form that submitting it will lead to a desired outcome.

Checkbox enabling the publishing pattern for calls to action.

For my friend's site, my recommendation was simply to add a Boolean field using a checkbox widget to the relevant content type reading, "Schedule this content to be published on Fridays and unpublished on Mondays." If the site required more publishing patterns than just the weekend pattern, I would've used a List (text) field with radio buttons or a select list identifying the different available publishing patterns.

Building the Scheduling System in Rules

Working with Rules is fairly simple if you can write out long hand what it is you're trying to accomplish. Considering all of our constraints here, we need a set of rules that accomplishes the following:

  1. When a call to action is created or saved with the scheduling checkbox checked, delete any scheduled tasks related to the content. (This is possible because Rules Scheduler lets you assign an identifier to scheduled rules, so identifying our scheduled tasks with the node ID will allow us to delete the tasks when needed in the future.)
  2. If the call to action that was just saved isn't published, schedule it to be published next Friday.
  3. If the call to action that was just saved is published, schedule it to be unpublished next Monday.
  4. When a call to action is automatically published on Friday, schedule it to be unpublished next Monday.
  5. When a call to action is automatically unpublished on Monday, schedule it to be published next Friday.
Actions that queue up a publishing schedule.

The first three items will be accomplished through a single rule reacting to two events, "After saving new content of type Call to action" and "After updating existing content of type Call to action." The rule will first delete any scheduled task for the piece of content and then it will invoke two rules components that will schedule the appropriate task based on whether or not the call to action was published.

Components that manage the publishing schedule.

The final two items will be accomplished through rules components that perform the necessary action and then schedule the appropriate task. As mentioned above, we'll use relative time strings ("next monday" and "next friday") and choose task identifiers that include the call to action node IDs ("unpublish-call-to-action-[node:nid]" and [publish-call-to-action-[node:nid]" respectively).

Give it a whirl!

It only took me about 10 minutes to create and test the rules based on the specification above, but if you aren't familiar with the Rules UI, it could take much longer. I believe Rules is worth learning (we built Drupal Commerce around it, after all), but there's something to be said for ready made examples.

I've attached to this post a Features export of the content type and related rules configurations for you to try on your own site. Give Scheduled Calls to Action a whirl and let me know how it works for you in the comments!

(Note: to see the rules configurations and scheduled tasks, enable the Rules UI, Views, and Views UI modules if they aren't already enabled on your site.)

Jan 31 2015
Jan 31

When I first wrote Ubercart's Cart module, we knew we were going to support both anonymous and authenticated shopping carts and checkout. The decision came at a time when there wasn't consensus around the impact of forced login on conversions, but we knew we wanted it to be optional if at all possible. Additionally, for authenticated users, we wanted to preserve items in their shopping carts so they would see the same items when logging in from multiple devices or across multiple sessions.

This resulted in a small conflict that we had to figure out how to deal with: users could have items in their authenticated shopping carts but browse the site anonymously, create a new shopping cart, and then log in. What should happen to the items in their authenticated carts vs. the items in their anonymous carts?

There are three basic resolutions: combine the shopping carts together so the user still has a single shopping cart, remove the items from the previous session and leave it up to the customer to find them again if desired, or retain the old shopping cart but ignore it until the customer has completed checkout for the current cart. In Ubercart, I chose to combine the items, but in Drupal Commerce I changed course to retain the old cart but, from the customer's point of view, treat that anonymously created cart as the current cart after login.

We got some push back for this decision, but ultimately I didn't change the default functionality of Drupal Commerce. We just made sure there was an appropriate hook (hook_commerce_cart_order_convert()) so developers could alter this behavior on a site-by-site basis as need be.

From the merchant's standpoint, the thinking behind combining carts goes that you don't want customers to forget they intended to purchase those products in the past. However, from the customer's standpoint, suddenly having additional items in the cart after logging in during the checkout process is quite jarring.

In fact, I've been bitten by this behavior when shopping online at Barnes & Noble. Weeks prior to placing an order, I had put a Wheel of Time novel in my shopping cart but eventually bought the book in store. When I came back to the site to purchase a gift for my wife, I used a login button on the checkout form to quickly reuse my previous addresses and payment details. Unbeknownst to me, the website combined my old shopping cart with my current one such that my "quick checkout" experience made me accidentally order a book I already owned! I then had to spend 30 minutes with customer service canceling the order and placing it afresh just for the book I actually wanted.

That experience confirmed in my mind we made the correct decision not to combine carts automatically. As eCommerce framework developers, we have no clue where a developer might like to integrate login during the checkout process. Best to let them decide if it's safe to do something with those previous cart items instead of silently making the decision for them.

That said, I believe we can improve the experience even further. Right now, Drupal Commerce retains the old shopping cart order, and after the customer completes checkout they'll see the previous shopping cart as their current cart. This can be confusing as well!

My ideal situation would likely be a user interface component on the shopping cart page where customers can see items they had added to their carts in previous sessions, giving them the option to add those products to their current carts. If they decide not to, I don't see any harm in then just deleting those historical carts and moving on.

There's always room for improvement. Smile

Photo credit: alphageek

Jan 22 2015
Jan 22

I've been privileged to attend almost every DrupalCon since Barcelona in 2007. I missed Paris in 2009, but I had a good excuse - my wife was due to give birth to our first child around the same time.

The relocation of the Commerce Guys headquarters to Paris has given me plenty of time to catch up on the missed sightseeing, but I still need to figure out how to get to Sydney after missing that one. Lol

Without access to those hundreds of Drupal developers and enthusiasts in 2007, I never would have known anyone was even using Ubercart. I didn't know how to engage other developers remotely (my early forays into IRC were similar to webchick's, I believe), and there wasn't much going on in Louisville, KY where I called home. Meeting others in the Drupal community, learning from my peers, and being mentored directly by many of the same has grown me personally and professionally in ways I never would have expected.

That's why I'm excited about the opportunity to travel to Bogotá, Colombia for the first DrupalCon in Latin America, February 10-12. I can't wait to hear the keynotes from both Dries and Larry, two of my Drupal heroes, and to learn more about the latest developments in Drupal 8 core and contributed modules.

I'll personally be addressing two topics: Drupal Commerce 2.x for Drupal 8 (on behalf of bojanz) and growing a Drupal based product business. I also look forward to the conversations, shared meals, and sprints that make the conference so rewarding.

I strongly encourage you to come if you're in a position to do so! Smile

With the help of Carlos Ospina, I've recorded a personal invitation in Spanish that I trust doesn't have me saying anything embarrassing. I'm sure my Spanish will be better for at least a week after spending time at the conference. Tongue

Jul 02 2014
Jul 02

Damien, Yohan, Andrei, Jonathon Kuma. Talking through the changes in Drupal 8.

With the entity API maturing in Drupal 8 as it approaches its first beta, Commerce Guys gathered a variety of Drupal Commerce contributors and maintainers in its Paris office to begin active development on Drupal Commerce 2.x. The week long sprint began with architectural debate and validation incorporating the collective experience of our professional services teams and delivery partners.

Bojan going over entity architecture.

Drupal Commerce 2.x will ultimately be a complete rewrite, reflecting the drastic changes in Drupal 8 itself. We’re excited to announce that long-time community contributor and Commerce Guy par excellence Bojan Zivanovic has been added as a co-maintainer to help us make it happen.

Pizza for lunch! Left to Right: Maciej Zgadzaj, Jonathan Sacksick, Bojan Zivanovic, Yohan Tillier, Julien Dubreuil, Fabien Gasser, Franck Stauffer, Fred Marand, Richard Jones, Dan Polant, Ryan Szrama.

The Commerce 2.x kick-off sprint marks the first time Commerce Guys has brought together the Drupal Commerce development team with its office technical leads, key members of local delivery partners, and members of the wider Drupal community in Paris. We were honored to have special guests offer their feedback and advice, including Fabien Potencier of Symfony, Thomas Rabaix of Sonata, and Franck Stauffer of RBS Change.

One of our key goals for Commerce 2.x is to create and use a few generic PHP libraries that can be used by other eCommerce projects or as standalone pieces in custom PHP applications. Plans thus far include a pricing library (prices, taxes, discounts, fees) and an address library, both of which provide functionality currently missing in the PHP ecosystem.

Initial impressions and ideas from the sprint include...

Stores

Commerce 2.x includes a new store entity type, already committed to the 8.x branch on drupal.org. There are many potential use cases for such an entity type (multi-domain stores, multi-seller scenarios, fulfillment centers, etc.), and contrib has the opportunity to unlock them all.

Product architecture

Node based product displays are no more. Products can now be displayed on their own, with product hierarchies being managed via parent-child relationships within the product entities themselves. A product can now be viewed on its own or selected from its hierarchy group such as this one:

When you configure the architecture of a product type, you determine which “levels” of the hierarchy can be displayed at unique URLs, which should redirect to the parent URL, and which define actual purchasable SKUs.

This brings us many things:

  1. Simpler Add to Cart form generation. We no longer need to load and process every product variation to recreate its attribute field hierarchy when the form is rendered. This information will be contained in the product type definition.
  2. Field inheritance. Add an image for "Blue" at the second level and automatically use it for all sizes. Field inheritance will be configurable per field.
  3. Faster product creation. This allows us to do bulk creation by reading the hierarchy information and creating the full set of variations as the Commerce Bulk Product Creation module supports today.

Discussing entity storage requirements with Yves Chedemois.

Prices

A price is now an object that knows how to apply a tax rate, discount, fee to itself:

<?php
$price
= $product->getPrice();
$price->addTaxRate($frStandard);
$price->addDiscount($fiftyPercentOff);
$price->addFee($amexFee);
?>

The price object will handle the interactions between discounts and taxes, different rounding rules, cumulative taxes, and other complexities.

All this will be a part of a powerful pricing library (taxes, discounts, fees) that will be shared with the wider PHP community.

Coding time, Fabien Potencier and Jonathon Sacksick discussing interaction between Symfony and Drupal.

Taxes

With the guidance of David Kitchen, we're rewriting our tax handling to better support VAT and changing tax rates (19.6% until 2014, 20% from 2014) out of the box.

This means that european merchants won't need commerce_vat and commerce_eu_vat
anymore.

Payments

In Commerce 1.x the API for payment gateways is light in order to allow maximum flexibility, but it also provides room for bugs and duplicated effort for each new implementation. We're brainstorming a more structured API that would allow for lighter implementations. We're not yet sure where this API belongs (in commerce_payment, a library built on top of omnipay, parts of it in omnipay itself, etc).

We're also exploring the idea of integrating Omnipay, a light PHP payments library. This would give us access to a wide base of existing integrations, and allow us to co-operate more closely with the wider PHP community.

Long days, but great work. Fabien Potencier (Sensio Labs), Fabien Gasser (Smile), Thomas Rabiax (Ekino, Sonata lead), Jonathon Sacksick, Fred Marand (OSInet), Chris Merritt, Dan Polant, Bojan Zivanovic, Ryan Szrama, and Josh Miller (taking picture).

To be continued...

This is just a snapshot of some of our discussions, plans, and current development. We have a few long days of coding ahead of us, after which we will provide more in-depth presentations of the new product architecture, pricing and taxes, checkout form management, payments, and other hot topics.

During early development as we create dozens of new classes and affect a variety of files with each patch, we’re taking advantage of GitHub to improve the code review and contribution process. To follow along, watch or star the commerceguys/commerce repository or fork it to prepare your finest contributions.

May 26 2014
May 26

I don't like being sandy but I love building sand castles. The potential is high but the stakes are low. You have unlimited raw material to build whatever you can imagine, and if you screw up you can just knock it over (to the delight of your children) and start again.

When your constant is impermanence, you adjust your expectations accordingly. If the sands shift or the tide rises, you shrug it off and start again or go back to bocce. However, if you were somehow bound by the fruit of your labor, you'd think twice about the when, where, and how of your building.

Lyle and I started developing Ubercart when Drupal 5 was still in beta, and we put up with the impermanence because we were just two dudes learning a lot and working from a clean slate.

Moving that forward to Drupal 6 took even longer because our codebase grew unwieldy, so I decided at Commerce Guys to trim the fat and start over. We didn't learn every lesson moving to Drupal 7, though, as it was still unstable when we began developing Drupal Commerce. With an unstable Views module. And an unstable Rules module. And an incomplete Entity API. Tongue

I don't think we would've done any differently, as the flip side of the instability is the opportunity to positively impact the development of the projects you depend on. For Drupal 8 we ended up contributing to core in other ways while tackling a full Drupal Commerce rewrite more slowly than we hoped. Even the code that we did develop against Drupal 8 is now outdated, as we had to juggle managing our existing ecosystem, writing new code, and rewriting that code to track changes in Drupal 8 itself.

However, we've recently been given the opportunity to host a variety of developers / documenters in Paris from June 30 - July 4 to re-evaluate our Commerce 2.x roadmap with the direct help and guidance of key members of the Symfony project. Specifically, we'll be looking to both move our code "upstream" from our Drupal modules into generalized libraries and take advantage of existing Symfony projects where possible.

Our target is an even leaner codebase with connections to the broader world of PHP based eCommerce. If you have any insights in this direction, please comment or contact me directly and consider joining us in Paris to learn and contribute.

Photo credit: j.s. clark

May 13 2014
May 13

Earlier this year I helped my friend Samuel bring his used cell phone resell business online using Drupal Commerce. The site is still in maintenance mode while we finish the self-service features, but his staff currently uses it logged in from their various locations as their point of sale system. Knowing the ins and outs of Commerce, I didn't have any problems tailor making an eCommerce application for his business, but I did have one hiccup during deployment that I'd never seen before.

We built Wikiwoo.com on Pantheon, a Drupal Platform as a Service, using a free developer site until it was ready for use in stores. Pantheon really helped us collaborate on the site build, with me doing the coding and configuring while he filled the product catalog. We did everything on the site's dev environment, including letting his partners take a look around to find things worth fixing, until we were ready to go live.

One of the last things I did to prepare for the launch was update the auto_increment value of the commerce_order table to account for the number of orders they processed in the previous year and a half. However, we weren't really migrating old eCommerce data, so I just expected the first order on the new site to start where we wanted and we'd watch them grow from there. A quick test showed it working as expected, so I deleted the dummy orders and sent him a link to upgrade the account to a paid plan to take it live.

Unfortunately, when I went back to the site the next day, I saw that orders were being created with IDs starting back at 1. I knew there was nothing in Commerce that would effect such a change, so I hit up Pantheon support and got a quick confirmation that nothing they do would intentionally reset auto_increment values either.

Sidebar: I really should emphasize quick. Any time I've ever contacted Pantheon support, they've responded right away. "Groovy," said Josh Koenig in this particular instance when we nailed down what was happening. "Groovy," I say to Pantheon's customer service. Cool

It turns out what I experienced was a result of InnoDB's treatment of auto_increment values. The auto_increment counter is only stored in memory, not on disk, and it is recalculated on server startup. InnoDB simply looks for the highest used ID and sets the counter to the next value, explaining why my order IDs shrunk back down to 1 after I cleared out all of our dummy orders.

In our case, it was the upgrade from a free account to a paid account that restarted the database server, triggering the reset of the counter. However, with cloud based Platforms as a Service, I imagine there are other scenarios where an expected alteration to an auto_increment value is apparently "lost" on migration between environments or builds. This is probably mostly an eCommerce issue with respect to Drupal sites, as merchants often want or need order IDs to account for historical sales, but perhaps the tip can save someone else a bit of head scratching.

To get around my issue, I simply reset the auto_increment to where I wanted it to be, created a cart order for myself, and waited for a real order to be created before deleting my dummy order.

Problem solved, it's been fun to watch the order count grow from there.

Photo credit: Max Barnes

May 12 2014
May 12

I accidentally started publishing open source software in 2006, the first integration of the QuickBooks Web Connector with anything. This was pre-Ubercart when I was just cutting my teeth on PHP / MySQL development at Prima Supply, and I thought it would be fun to claim the code was written by wombats while I just published it online. I decided to own the silliness and start blogging on bywombats.com using Drupal 4.7 at the time - and immediately picked up a freelance contract doing QuickBooks integration work. Tongue

Fast forward a few years, a couple of eCommerce projects, and a Drupal startup, and the moniker has apparently run its course. A lot of folks over the years assumed "By Wombats" was the name of a Drupal shop and tried to contact me for work. Little did they know my site's contact form hasn't been working for years. Shock

This past week I finally got around to fixing that by moving from Rackspace to Digital Ocean and configuring my server to send mail through Mandrill. I upgraded to Drupal 7 (about time?) and played around with Mike Crittenden's Meedjum theme until I liked the look. He's presently trying to bribe me to help maintain the theme, but I'm holding out for better beer.

Migrating was the fun part, as it was my first opportunity to make use of the Drupal-to-Drupal data migration module. I couldn't get moving files to work for some reason, but I figured out how to make options settings work in the configuration form (leave the select lists alone and put the value in the "Default value" text field) to make use of the preserve_files option. I copied the old files to the Drupal 7 files directory and ran the migration with that flag set for it to start managing the files that were already in the directory.

Migrating taxonomy terms was straightforward, but it took me a while to get blog posts right. I learned I had to select the taxonomy term migration in the "Source migration" select list to ensure blog posts got created in the Drupal 7 site referencing the correct term ID (since they changed during migration). I had to do the same for files, choosing the "Upload [upload]" source field and selecting the file migration I used as the source migration. I also had to set the optional MigrateFile class to "MigrateFileFid" to ensure the new blog's file field referenced the appropriate file IDs.

Perhaps the best thing about Migrate is its ability to rollback migrations and re-import them to debug the process. I did this several times for the various migrations. I also made use of its ability to import a representative subset of the awaiting content while I was debugging the term / file association process. Clever module - Mike Ryan rocks.

The future for this blog is a consolidation of various other things I'm doing online, including blogging about life in Greenville, SC (hint: it rocks) and Roguelikes / indie games (again with the Wordpress?). Once that's done, I'll carry on with the blogging about Drupal, startups, and a few other things, including my recent explorations with R and Commerce Guys's Platform.

I hope to hear from you soon. Smile

Jul 22 2013
Jul 22

I'm currently helping some friends rebuild the theological education website, BiblicalTraining.org, in Drupal 7 with Drupal Commerce. I built the Drupal 6 version some years ago to move the website from a bespoke PHP application into Drupal, using modules like Ubercart, Quiz, and Organic Groups to solve most of the requirements. However, the donation code was more or less a straight Drupal port of the PHP script handling donations via PayTrace at the time.

With the rebuild onto Drupal 7, we have the opportunity to unify the donation form with the course payment checkout form to begin using Commerce Reports and multiple payment methods, including the newly released Commerce PayPal 2.0 for Express Checkout payments. However, we still have to deal with actually creating an order to represent the donation payment on the checkout form.

On this site, we don't use product display nodes. I decided instead to directly instantiate the Add to Cart form at a custom URL and avoid the need to create a product display node type just for the one form.

I started by defining a donation product type so the site administrators could create a product to represent the various campaigns donors could give toward. Since I am building the form in a small page callback function, I can easily support as many donation products as get created without introducing the human process of making sure administrators both add the product and update a product display node to reference it.

I created a single menu item at /donate whose page callback is the following:

<?php
/**
* Page callback: builds a donation Add to Cart form.
*/
function bt_donation_form_page() {
// Create the donation line item defaulted to the General fund.
$line_item = commerce_product_line_item_new(commerce_product_load(5), 1, 0, array('context' => array('display_path' => 'donate')), 'donation');
$wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);// Set the line item context to reference all of the donation products.
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'commerce_product')
->
entityCondition('bundle', 'donation')
->
propertyCondition('status', TRUE);$result = $query->execute();

if (!empty(

$result['commerce_product'])) {
$line_item->data['context']['product_ids'] = array_keys($result['commerce_product']);
}
// Do not allow the Add to Cart form to combine line items.
$line_item->data['context']['add_to_cart_combine'] = FALSE;

return

drupal_get_form('commerce_cart_add_to_cart_form', $line_item);
}
?>

To build an Add to Cart form, you have to pass in a line item object that contains all the information required to build the form. Our page callback starts by building a donation product line item, a custom line item type that allows for custom donation amounts as demonstrated in this tutorial video from Randy Fay. The product the line item references, "General fund", will be the default selection on the Add to Cart form, and the context array I pass to the line item creation function populates the line item's display_path field to link this line item to the donation page.

Next I use a simple EntityFieldQuery to find all the enabled donation products on the site. These product IDs are added to the line item's build context array, which the Add to Cart form builder function uses to know which products the form should represent. In a product display scenario, these product IDs would come from the value of the product reference field. Here I pass them in directly and get a simple Add to Cart form that is now ready to be themed to perfection:

Additional improvements on the site involve changing the "Add to Cart" button to read "Donate Now" and using a custom message upon submission with a redirect to /checkout. In case the donor cancels checkout and ends up at /cart, I do two things to ensure they can't manipulate the quantity of the donation line items: I removed the quantity textfield field from the View, but in case we need to add it back in later for other line item types, I also use a form alter to convert any donation line item quantity textfield to the plain text quantity value:

<?php
/**
* Implements hook_form_FORM_ID_alter().
*/
function bt_donation_form_views_form_commerce_cart_form_default_alter(&$form, &$form_state) {
// Loop over the quantity textfields on the form.
foreach (element_children($form['edit_quantity']) as $key) {
$line_item_id = $form['edit_quantity'][$key]['#line_item_id'];
$line_item = commerce_line_item_load($line_item_id);// If it's for a donation line item...
if ($line_item->type == 'donation') {
// Turn it into a simple text representation of the quantity.
$form['edit_quantity'][$key]['#type'] = 'value';
$form['edit_quantity'][$key]['#suffix'] = check_plain($form['edit_quantity'][$key]['#default_value']);
}
}
}
?>

This might actually make a handy contrib module...

If the donor leaves a donation line item in the cart and goes back to the donation form, you'll notice toward the end of my page callback that I also indicate in the context array that the form should not attempt to combine like items during the Add to Cart submission process. I actually realized the form builder function was missing some documentation for context keys, so I added those in straightaway.

All told, I spent a couple hours building a custom donation form and workflow that now perfectly integrates with the checkout process used by the rest of the site. This will make it easier to customize and maintain long term, and it allows us to use existing Drupal Commerce payment method modules to manage donations instead of having to write and maintain a custom payment module for the task.

Apr 12 2013
Apr 12

In Drupal Commerce, we deal in entities, fields, and field-based relationships between entities (i.e. references). The extent to which we implemented our data model on these systems from the earliest days of Drupal 7 is what grants Drupal Commerce developers a level of flexibility previously unavailable to eCommerce developers in general. Cool, right? Wink

Unfortunately, the Drupal entity trade can be dangerous when dealing with historical data that isn't supposed to change - when a reference should do more than merely "refer" but also express constraints.

Such is the case with customer profile references on orders.

Once customer information (e.g. a billing or shipping address) is entered for an order, we don't want the order to lose that information at a later date. This means we have to prevent not just the deletion of the referenced customer profiles but also changes to them - the latter because our references are to entitiies, not revisions of entities.

Side note: honestly, I'm fine with that - I can't imagine a reasonable UI or update strategy for entity revision references. It's hard enough to keep straight as is. Tongue

The most common place users encounter customer profile duplication is when they go to update a customer profile through the UI. If any field values are changed, the Order module will prevent the update if it detects the customer profile is referenced by a non-shopping cart order. It empties the profile IDs in a presave hook, forcing the save to create a new customer profile instead of updating the existing one.

This same process affects not just customer profiles being edited through the UI but also customer profiles being updated through code. However, if you combine the fact that customer profiles have revisions with the absence of the duplication related messages you see when performing the operation in the UI, it's easy to see how this functionality might appear to developers as a case of revisions gone awry.

There are a couple of functions developers can refer to to read comments describing the process and see the implementation itself:

  • commerce_order_commerce_customer_profile_presave()
  • commerce_order_commerce_customer_profile_can_delete()

It's worth noting that we've coded this functionality to be paranoid - if there's a slight chance something substantive may have changed in the field data, we force duplication instead of updating the original. Better to duplicate than to lose vital data.

Still, the keen observer will note that we actually do permit customer profiles to be updated through the UI on one condition. If an administrator edits a customer profile through the edit form of the sole order referencing the profile, we permit the update.

You may have a need in custom code to perform an update to a customer profile field that you know does not affect the historical record in a substantive way. Maybe it's simply a matter of changing some internal field that has no bearing on the fulfillment of orders. In such cases, to bypass customer profile duplication, you can imitate the process the order edit form uses to identify an order as safe to delete.

To do this, add a temporary "entity_context" property to the customer profile object. This is the property the Order module looks for in the presave hook to determine if the customer profile is being edited in the context of its sole referencing order. If you properly identify this order in the entity_context, the Order module will permit the update to occur without duplication:

<?php
$profile
= commerce_customer_profile_load(1);
$wrapper = entity_metadata_wrapper('commerce_customer_profile', $profile);
$wrapper->field_referral_source = 'MySpace';
$profile->entity_context = array(
'entity_type' => 'commerce_order',
'entity_id' => 1,
);
commerce_customer_profile_save($profile);
?>

Obviously, this is obtuse.

In Commerce 2.x, we'll do well to improve the developer experience here. It gets even worse if you want to make such an update on a site using Commerce Addressbook where you do want to update a customer profile referenced by multiple orders without enacting duplication. In fact, until I wrote this post, there would have been no way to achieve this short of a miraculous hook_query_alter().

This whole post came out of a quick e-mail exchange with Forest Mars, whom I'm looking forward to meeting at next week's Florida DrupalCamp (you going?). Since I've had a chance to think about the issue in a longer form post, I'm going to go ahead and add a query tag so it's at least possible to target the "can delete" query without committing developer sins.

And that is how e-mail and blogging improve open source projects, my friends! Cool

Mar 10 2013
Mar 10

A year ago I moved to Greenville, SC to live closer to family. I haven't looked back since, and I've fallen more and more in love with my new hometown every month. I had cursory knowledge of its great sights, food, culture, and climate before we moved, but the big surprise has been the city's vibrant tech community.

A few months after moving, I discovered The Iron Yard, which at the time was running a three month startup accelerator. Peter and the crew were all very welcoming and invited me to hang out with the teams giving and receiving in turn... and of course occasionally talking Drupal. I wrote more about their program and space on my therapeutic moving blog, One Ville to Another.

In recent months, The Iron Yard merged with this awesome co-working space (creatively Wink ) named CoWork. They then scored a 30,000 sq ft office space ("the forge") in the heart of our wonderful downtown to gather not just their programs but also like minded design, development, and creative firms into a single space. They also launched a Coder Dojo to teach kids web development (along with Scratch game programming and Arduino hacking) and are now expanding the school to education for adults, too. Hence the blog post.

Starting next month, The Iron Yard Academy will take a small class of folks through an intense, full-time, three month course in front end development. The two teacher-mentors will be Mason Stewart and Marco Suarez, a killer development / design pair who recently launched the attractive Etsy curation site Haberdash Fox.

Their class will cover the basics (HTML, CSS, JavaScript) and quickly move into pertinent topics for front-end Drupal development, especially with Drupal 8 - Git / the command line, HTML5, jQuery, Backbone.js, responsive design, and more.

In addition to the course, students will get a MacBook Air, lodging in the city (if needed), access to The Iron Yard mentors, and guaranteed job placement (again, if needed) within a year doing front-end development in a startup - hopefully locally. The whole course is only $9,750 and will be repeated a couple more times this year if you can't make it so soon.

The program is definitely open to students who already have experience in web development, even if you're currently employed. If you have an underutilized dev who wants to super charge their front end skills, I'd highly recommend sending them to learn and grow in this great community. I look forward to meeting the new class, and I hope some of the new talent makes its way into the Drupal community. Smile

Dec 12 2012
Dec 12

Back in September I had the privilege of attending a web development conference in my new hometown, Greenville, SC. The occasion was REST Fest, which was primarily a barcamp format gathering of REST API developers and thought leaders from around the world.

I got to meet several local web developers along with encouraging and helpful out of towners like Mike Amundsen (author of Building Hypermedia APIs with HTML5 & Node, highly recommended) and Sam Ramji (erstwhile champion of open source at Microsoft, now with Apigee). I also got a second chance to meet David Zuelke, who I somehow missed at DrupalCon Munich where he presented on RESTful Web Services. (In addition to REST, he and I geeked out over the BMW Performance Track, which I enjoyed the day before thanks to demo day at The Iron Yard, our local startup accelerator and host to REST Fest and other tech events.)

The event was quite the eye opener, an opportunity for me to be out of my element with nary a Drupal developer in sight. However, the topics covered and examples shared were incredibly practical for me, as we were in the middle of researching and implementing RESTful Drupal Commerce at Commerce Guys for a client project and for a Commerce Kickstart mobile app developed with the help of Sumit Kataria.

Fast forward now three months and I'm finally circling back around to pump up the Commerce Services module to turn any Drupal Commerce site into a REST API server. My focus thus far has been on improving GET requests to support a variety of query parameters offering:

  • Response format specification (i.e. a subset of an entity's properties / fields when you don't need the entire entity)
  • Filtering by property names, field names, and multi-column field column names
  • Sorting by those same parameters
  • Paging through the result set via limit and offset parameters
  • The ability to include referenced entities in the response
  • The ability to flatten field value arrays to the current language and from arrays to scalars for single value, mono-column fields

As a best practices guide, I've been using an incredibly helpful eBook from Apigee called Web API Design: Creating Interfaces that Developers Love. The idea here is to follow standard patterns for all of our entity resources that allow API clients to easily browse the API.

Additionally, my goal is for Drupal Commerce API servers to actually be RESTful, not simply RESTish. If you aren't familiar, a great articule to bookmark and read when you need it is A Brief Introduction to REST by Stefan Tilkov. As we build out the Commerce Services module and deploy projects from client sites to mobile apps, we'll also publish developer documentation that defines and demonstrates best practices use of the system.

My end goal here is to keep pushing forward to a holy grail of sorts - HyperDrupal. By simply creating powerful resources that respect HTTP methods (and other headers) as defined, we're two thirds of the way there. The final step (as identified by the Richardson Maturity Model) is to format our responses using a "hypermedia type" - a media type that includes the hypermedia controls we're used to in HTML like links (a), forms (forms that POST), query templates (forms that GET), and the like. See Mike Amundsen's book (referenced above) for more detail.

The media type I'll be focusing on first is Mike's Collection+JSON media type. Even as I do my testing with Commerce Services, I'm using the beginnings of what I hope will become the Collection+JSON response formatter for Services based REST servers. The "big idea" here is that an API client like a mobile app could browse your API like a user would browse your website.

For example, the app would start at the "front page" of your API where it might find the link to your product list. When the customer chooses which product to view, in addition to the product information, the GET response includes a form with the necessary parameters to submit a POST request to add the product to the cart. If built to consume this information properly, the client never actually need to know how your URLs are constructed, whether or not you've recently changed API responses, or when you've added new features to the site. That information would all be communicated through API request responses.

This process has been awkwardly acronymized as "HATEOS" (pronounced had-ee-us) - Hypermedia as the Engine of Application State - and is further described in Haters Gonna HATEOS by Steve Klabnik, proprietor of the living eBook Designing Hypermedia APIs. It may sound a bit "pie in the sky", but the advantages of Drupal / Drupal Commerce offering this level of API functionality out of the box are too good not to pursue.

The good news is that Drupal 8 is well on its way toward beefing up our REST cred. Larry Garfield, Klaus Purer, Lin Clark and others have been hard at work laying the groundwork for solid REST in core through the "Web Services and Context in Core" D8 initiative. I don't believe hypermedia is on the menu for D8 release, but they were just granted a reprieve in the form of the D8 feature completion phase to ensure solid core support for levels 1 and 2 in the Richardson Maturity Model of REST APIs.

Being able to focus specifically on Drupal Commerce helps me research and iterate quickly to implement and use hypermedia with Commerce Services, but it does keep me a bit downstream of all that's going on in core (and for D7 in modules like Services, RESTws, and others). What I can say from here is that the future looks bright, and more members of the community are engaging around and communicating about proper REST API design. Together, I'm confident we'll see a successful push toward HyperDrupal in the very near future. Cool

Dec 11 2012
Dec 11

Naturally, I have to answer Drupal. While it hasn't seen the level of activity a more targeted community service like Stack Exchange generates, Quora still generates a fair number of questions about Drupal and about CMSes and eCommerce in general. I've seen several seasoned Drupallers around answering questions, including Dries himself.

I'm still a fresh face at Quora, but this question was easy enough to answer. It's funny to think about it in such terms, but I've spent over a fifth of my life developing eCommerce solutions on top of Drupal. For the past three years at Commerce Guys, I've helped make the public case for our vision to make Drupal the number one open source eCommerce platform in the world. I think we're on our way.

I'd hope that many others in the community would be able to make a strong case for Drupal as the best CMS for eCommerce, so I've reprinted the bulk of my answer here. If you haven't thought along these lines before, maybe some of the strengths I highlight can make it into your next pitch! ; )

Drupal is an incredibly powerful and flexible CMS, used for sites ranging in size from simple blogs to The White House and for sites as highly trafficked as GRAMMY.com on the night of their awards show. Its strength lies in its community, which includes thousands of active developers around the world working together to make the solution better. Every contributed module is freely available on drupal.org, including the two eCommerce projects I've worked on - Ubercart (which took an "application" approach to eCommerce by porting the osCommerce feature set into Drupal 5) and my current project, Drupal Commerce (which takes a "framework" approach to eCommerce by defining the basic data models and systems you need to do commerce on Drupal 7).

Now, why turn to the community and highlight free? In my opinion, the nature of Drupal's licensing and community governance is a huge win for anyone using it to develop eCommerce features and sites. Developers are incentivized to collaborate, not develop silos of functionality that they can sell for a few dollars (to a few hundred dollars) a pop. Drupal Commerce didn't have to define its own Views engine for listing products, line items, orders, etc. - it just integrated with the already existing Views module. Drupal Commerce didn't have to write its own conditional evaluation engine to power pricing, taxes, discounts, etc. - it just integrated with the already existing Rules module. Instead of silos, we have fully interoperable contributed modules all built on the same base Drupal 7 components. Each new module that comes along simply uses the underlying API and can suddenly be used alongside existing modules without those modules ever having to know they exist in turn.

This results in a fair amount of "Aha!" moments when you realize the next feature you need to add to a site already exists. By way of example, on my Drupal Commerce powered cheese site, Real Milk Cheese, I wanted to offer a discount to anyone who connected via Facebook. I didn't have to write Facebook integration or buy a module from someone - I simply grabbed the FB Oauth module, which happened to have been already created by a friend, and integrated it with Rules to use FB connection as a condition in my pricing engine.

There are a fair number of hosting options available tailored specifically to Drupal, with Acquia Dev Cloud and Pantheon being two of the leaders, and Commerce Guys preparing to enter the market via our Commerce Platform. These services are built on PCI compliant cloud providers, but there are also a wide variety of payment gateway modules already integrated that offer PCI compliant payment through redirected / tokenized payment solutions (think PayPal, Braintree, Stripe, etc.).

Last but not least - Drupal is first and foremost a CMS and community publishing tool. It excels at search engine optimization and offers a wide variety of community features, enabling you to reach and engage your potential customers. As expected, there is even a Drupal specific internet marketing company called Volacci (ran by another friend from Austin - see, we're all very friendly ; ) that can help further optimize your site and draw a crowd.

Commerce Guys has a very aggressive strategy to court and integrate new service providers. The Drupal market is huge, and eCommerce players want to have access to this market. Look for us to continue to build out the offering in the Commerce Marketplace, which will enable you to easily find and enable integrations with payment, analytics, e-mail, and other services providers.

We think it's much better to turn a CMS into a full-featured eCommerce system than it is to try and tack on a CMS to an eCommerce application. By the last reckoning, over 20,000 other people agreed (cf. http://drupal.org/project/usage/commerce).

You want your best SEO, performance, and flexibility driving eyes to your product pages and engaging customers there, not on your blog posts and policy pages.

Nov 16 2012
Nov 16

This week we finally packaged the full release of Commerce Shipping 2.0, and I couldn't be happier. Thanks to the efforts of my co-maintainer, googletorp, and contributors helior, cvangysel, and andyg5000, we have a solid shipping framework for Drupal Commerce that offers more flexibility and granular control than any other shipping system I've seen, Drupal or not.


Commerce Shipping checkout panes on the default checkout form.

What's the big deal?

As I wrote in the release notes, this milestone really is a big deal for Drupal Commerce. Among the many benefits this module brings to the table are:

  • The ability to use any number of shipping methods to calculate shipping rates on a site, using Rules to control when a particular method should be enabled. You can use one carrier to quote domestic rates, another to quote international rates, and a flat rate to offer free shipping if certain conditions are met.
  • An architecture that subdivides shipping methods into their individual shipping services (e.g. Ground, 2nd Day Air, Next Day Air, etc.), giving you granular control through Rules over which services should be available to an order. You might use this to ensure perishable products only ship overnight or to only offer guaranteed delivery dates for items in stock.
  • A shipping rate caching system that allows carrier rated quotes to be fetched in a single API request and stored locally (with an optional timeout) for the duration of the checkout process.
  • A shipping rate calculation API that lets you perform additional calculations on top of the base shipping rate for each service through custom modules or Rules. This allows you to add taxes, handling fees, discounts, and more to your shipping rates. It also turns the Flat Rate module into the basis for more complex shipping calculation schemes - weight based, quantity based, etc.
  • A checkout pane that can automatically recalculate shipping rates as customers enter their billing and shipping information. This lets you display accurate shipping rates that depend on address data on a single page checkout form.

Additionally, in conjunction with last month's Commerce 1.4 release, Drupal Commerce supports copying addresses and other matching field data between your billing information and shipping information checkout panes. Many thanks to the contributors mentioned above for working out all the kinks between this feature and the recalculation of shipping services.

This architecture removes limitations found in other open source eCommerce systems, like Ubercart and Magento, that often take an "all or nothing" approach to showing shipping services from any given carrier on the checkout form. Even better, features that this module delivers for free would actually cost you extra to add to systems like Magento that nickel and dime you through plugin marketplaces just to make your checkout form more customer friendly. Tongue

Next steps for Commerce Shipping

With this release there are already modules to support Flat Rate shipping, carrier rated quotes from UPS, FedEx, USPS, and others, and in store pickup facilitated by Kiala. Additional contributed modules focus on extending the system with other features, like joachim's Shipping Weight Tariff module that offers a simplified table based interface for setting shipping costs by total order weight.

Next steps involve bringing these contributed modules and their dependencies (like the Physical Fields module and Commerce Physical Products) to a full release, an effort already underway thanks to andyg5000 and other contributors / maintainers.

This work has been a community effort, and it has paid off for everyone. Smile

Oct 03 2012
Oct 03

Drupal 7's Forms API included several sweet improvements making it easier than ever to build dynamic forms (with or) without writing custom JavaScript. I'm sure there are better summaries than I have time to bake up right now, but a quick list of pertinent properties includes #attached, #states, and #ajax. This post focuses on the #ajax property and how you can use it to execute arbitrary JavaScript during a form refresh.


A form element that uses #ajax to allow address copying in checkout.

Briefly stated, what I'm calling the form refresh is what happens when Drupal finally asks the callback function pictured above what response to send to the client. This can be one of two things:

  1. A piece of the form that will be rendered to replace the contents of the wrapper element specified in the #ajax array
  2. An array of AJAX commands to execute in the browser

We do both in Drupal Commerce, sometimes simply refreshing part of the form that has been updated and other times sending back a nice fat batch of commands to update various parts of the page. We use commands arrays to great effect to make attribute widgets on the Add to Cart form dynamically update product fields that have been rendered into node pages. This is how product images change based on the color selected, for example.

To create these commands, you use functions like ajax_command_replace(), which simply swaps out the contents of an element on the page with something else as if you'd used the first type of response. The other commands are mostly similar manipulations of the DOM, with the full list of commands available here.

I personally think we need more modules brave enough to use ajax_command_alert() in their #ajax callbacks. Cool

One thing you won't find in that list is something like ajax_command_eval() to execute some arbitrary JavaScript back at the client. We've had just such a need a couple times now, once in Commerce Shipping where I wanted to trigger a shipping rate recalculation when an address copy button was clicked and another time on a client site where updating attribute widgets on the Add to Cart form needed to trigger updates in a Flash based product customizer.

Our solution was to use ajax_command_invoke(), which executes a jQuery method with whatever arguments you pass it. Your module should first define a jQuery plugin to hold your code, which is surprisingly easy. Your form them needs to use the #attached property to ensure the JavaScript file is included when your #ajax enabled form element is rendered. Then you just have to invoke your custom jQuery method via ajax_command_invoke(), and you're golden.

This diff from the Commerce Shipping module shows this (hack?) in action. Theoretically, ajax_command_invoke() invokes a jQuery method on some element selected from the DOM, but this example currently just triggers another element's click event using a small jQuery plugin that breaks a design rule by returning nothing to chain to. C'est la vie.

Sep 25 2012
Sep 25

It was my pleasure to demo Commerce Kickstart 2.x at DrupalCon Munich as I presented Next Steps for Drupal Commerce. The relaunched distribution has been a long time coming, and I couldn't be happier with the release our Kickstart team at Commerce Guys has produced. They've proven the idea that we could keep the core of Drupal Commerce a slim eCommerce framework and wrap it in a usability layer that makes it both attractive and easier to administer.

Beyond the sheer amount of polish that has gone into the UI from the installer to the "Shiny" administration theme, its two most exciting features for me are the Inline Entity Form and Views Megarow functionality.


An inline entity form on a product display node with multiple variations.

Inline Entity Form allows us to embed product details forms inside node forms, simplifying the product vs. product display architecture that has made Drupal Commerce notorious (and truly flexible). I could write a whole post about just how we've implemented it, but I'll save the gory details for a later time.

I will at least point out that if this were a single value product reference field, instead of the drag-and-drop table pictured here, the module would simply embed the product related form elements directly into the node form.


A Views Megarow in action after clicking the "Quick Edit" link.

An equally impressive technical implementation, Views Megarow makes it simple to edit groups of products and orders inline in a View through some fancy AJAX row expansion. It gives you easy access to bulk product edit forms and order summaries complete with order activity streams and administrator comments.

Both of these features have been meticulously planned, designed, user tested, and revised to provide a very streamlined user experience for store administrators. With my time mostly focused on other development, I happily applaud our team for putting out such high quality work.

However, even with this release under our belts, we're hardly ready to sit back and relax. We have plenty more to do in the development of Drupal Commerce distributions, contributed modules, and the core framework itself. I spent the final part of my session at DrupalCon proposing the topics and timeline under consideration for a Drupal Commerce 2.x roadmap targeting Drupal 8.

To make sure we're meeting these challenges head on, I proposed a Commerce 2.x planning and development sprint at our offices in Paris in mid-October. The primary goal of the sprint is to research and plan development on Drupal 8, including how to best utilize and work with the various core initiatives, what new modules to add as dependencies or bring into core as new features, and what core code needs refactoring.

This sprint is on the calendar for October 15-19, and while we likely won't be laying down a lot of code, we're still looking for collaborators. We're particularly interested in folks with experience developing for Drupal Commerce on Drupal 7, bonus points awarded to those who have had to work around its limitations.

I'll post more on the topic in the near future, including specific items we intend to address in 2.x development. In the meantime, it's about time for a Commerce 1.4.

Mar 16 2012
Mar 16

We built Drupal Commerce to be an eCommerce framework because of the limitations we kept running into using and developing for Ubercart. Based on our experience, we knew that we needed a module package that made as few hard-coded assumptions as possible about how a site’s eCommerce systems should function. What we have now with Drupal Commerce, Views, and Rules has worked very well for us and our partners on numerous large eCommerce sites with complex requirements. If you’ve created one of the 10,000+ Drupal Commerce sites online, we hope it’s proved useful for your projects, too.

However, we knew going in that creating a no-assumptions framework may privilege developers but involves very real user experience trade-offs, especially for non-technical users who prefer or expect to configure and administer every aspect of the store through the UI. We’ve seen the continued confusion in the forums, issue queue, and blog posts, and we know that simplifying the user experience is crucial to Drupal Commerce’s continue growth and success. At the same time we’ve realized that this won’t happen (or won’t happen soon enough) without a sustained, focused effort.

To address this need, we gathered Ryan, Bojan, Nicolas and a couple of other smart people in Paris last month to launch a new and improved version of Commerce Kickstart that we refer to in-house as Kickstart v2 (the final project name being subject to change). Commerce Kickstart is a distribution of Drupal that installs and configures Drupal Commerce for use along with example store content, making it the quickest way to get up and running with Drupal Commerce. We’ve always intended for distributions like this to be the solution for simplified and tailor-made user experiences in line with our philosophy about the limited UX scope of the core Drupal Commerce modules. However, distributions still depend on a lot of module development, theming, and forethought to prove helpful to new users.

The scope of Kickstart v2 will expand to cover the general use-case of selling physical goods through an online store. Our guiding principles and goals for the new version include:

  • Make it easier for new users to setup a Drupal Commerce store by providing clear examples, smart initial configurations, and very thorough documentation.
  • Give users the experience they expect when they install an eCommerce application like a product catalog, shipping options, payment options, coupons, advanced product image features, and more.
  • Make good UI choices that solve the problems experienced by 80% of users (aka "Do not try to solve everything for everybody").
  • Simplify on-site product management by combining the creation of products with the creation of product displays through the one node form.
  • Give more tools to store administrators to help them manage their customers, products, and orders on the back-end of the site.

We plan to reach a stable version of the distribution in mid-August 2012, just in time for DrupalCon Munich. We’ll be developing everything out in the open on drupal.org, so if you are interested in lending a hand or suggesting ideas, keep an eye on the Commerce Kickstart 2.x meta-issue in the project’s issue queue. We’ll link from there to the projects we hope to contribute to and see included in a revamped Commerce Kickstart.

If you’re going to DrupalCon Denver, we’re also planning a "Birds of a Feather" session for Thursday, March 22 to present the wireframes and code in progress (right now limited to the inline product form and addressbook). Check out the BoF board for the time (again, subject to change) and consider joining us - we’d love to have your feedback and ideas!

Finally, we plan to maintain a base Drupal Commerce distribution inside or alongside of Kickstart v2 that includes all the tools you need to build your next Drupal Commerce distribution more quickly. We’ve seen several great Drupal Commerce distributions thus far, but there are still many modern eCommerce use cases and business models that could be addressed in more tailor-made distributions. The more the merrier!

Mar 13 2012
Mar 13

One of the unexpected challenges in raising money to grow your business is keeping mum about the deal until it's time. Time is likely among the many terms you'll find defined in your contract, and between the day you sign the papers and the day that time actually arrives, you're glowing inside because your investors believe in the potential of your business and want to see you do more.

Investors don't magically make a business plan succeed, nor do they single out the sole source of success behind a business or an idea. This is certainly the case with Commerce Guys' raise announced last week. We know for a fact that our investors get open source as much as they do eCommerce. Even as they evaluated us on our ability to execute our business plan, they evaluated us on how well we work within and alongside the larger Drupal community. When they took a close look, they saw the strengths of the community and the caliber of developers collaborating with us to build Drupal Commerce.

That's what makes it so exciting to share the news - investors and developers who have grown their own businesses and, in the case of the team at Open Ocean with MySQL, their own open source projects have looked closely into both Commerce Guys and Drupal Commerce and felt confident enough to front some serious cash for us to kick our efforts up a notch. Many of these guys have built their own eCommerce systems and understand the challenges we're in a unique position to solve through Drupal 7, Views, Rules, and Commerce, and they're guys who understand the importance of the community in the success of any open source project.

So, we're not crazy after all, and what we've been trying to build with our friends at Commerce Guys and in the Drupal community isn't crazy. Ambitious, sure, but achievable. Our vision for Drupal Commerce remains the same - to see Drupal Commerce become the world's leading open source eCommerce framework. For the last two and a half years, my time has been set aside by Commerce Guys to develop the code (with plenty of help from other brilliant Commerce Guys and community contributors) and grow the community needed to make it happen. Now we've sold the vision to some very smart people with deep pockets outside our normal circles and are eager to see what happens next.

Their affirmation is much appreciated, but so is the money that will let us hire and set aside even more developers to "scale me" out a bit. We need to address immediate concerns pertaining to documentation and community support on DrupalCommerce.org. We'll need to make sure we follow-through on our longstanding 2.x strategy to bring some sanity to the user experience for administrators even as 1.x has privileged developers. All the while, there will be more than enough module maintenance and distribution work to go around!

Addressing these needs for Drupal Commerce should only require a fraction of the money we've raised, but it's a good start that will have an immediate positive impact on the thousands of people already using Drupal Commerce to power their online businesses. If you think you can stomach working with me on a daily basis and have the chops to help us succeed, be sure to get in touch.

Jan 24 2012
Jan 24

One of the things I'll miss about Louisville, KY when I move my family to Greenville, SC next month is the buying club we're a part of that sources raw / organic foods and other products from local farms and other good companies. It was put together by a genius I knew through college and church (John Moody, who writes and speaks about food clubs and co-ops), and last year another college buddy (Kane Holbrook) started working with him to help manage the club and oversee deliveries and pick-ups. Among the many yummy things we get through the club are a variety of raw milk cheeses from Welsh Mountain Farms, an Amish farm in Lancaster County, Pennsylvania.

It just so happens that this farmer, yea, though he has no internet access himself, understands the advantages of selling online and asked Kane last year about starting a website to sell his cheese. Kane floated the idea by me, and it quickly became a business plan and partnership to start selling his cheese using Drupal Commerce. Not only did it help the farmer and open a door for Kane and I to do some business together, but it also finally gave me a chance to experience using Drupal Commerce as a site owner and administrator. After two years of planning and development, I finally started eating my own dog food when we launched RealMilkCheese.com in November.

I'll have more to write about the site in the future, as I learned a lot through it and contributed a lot of code from the project to drupal.org. It became the driving factor behind my development of the flat rate shipping module and UI improvements for on-site order management in Drupal Commerce 1.2. It's also the primary example I use to demonstrate multiple flat rate shipping options with conditional availability (think free shipping on orders over a certain amount) and custom discounts to products through an integration with quicksketch's Facebook OAuth module. It was my second foray into theming with Omega and turned up a few tips that I need to pass on to other theme developers with respect to Drupal Commerce components. Finally, it gave me my first experience launching a site on Acquia Dev Cloud using one of those handy coupons they give out at Drupal events.

But the primary purpose for this blog post is to highlight one specific difficulty we encountered while administering orders and the simple solution I put in place to resolve it. In Drupal Commerce, the shopping cart is simply an order in a special status that indicates it's "in progress" and therefore needs to be continually updated to reflect current product prices and availability. By default an authenticated shopping cart order (i.e. for a logged in user) may exist indefinitely until the user finally completes checkout for the order. (There's an issue to expire them through Rules if you're interested in reviewing it. )

We encountered a scenario where a customer added a product to his shopping cart the first week of December but didn't actually purchase the cheese until we sent out a special offer over the holidays for a free 8 oz. cheddar for orders placed in a certain timeframe. It was great to see the immediate effectiveness of the offer (recovered cart sales are a big deal), but because the Orders View on the back-end sorted orders in reverse order by creation timestamp, his order appeared down the page below orders that had already been shipped and marked as Completed. It's not a huge problem, because a filter on the View to only show Pending orders by default would highlight orders needing attention, but it still isn't an ideal user experience.

The thought occurred to me that for our scenario, it would be fine for the creation timestamp of an order to be reset to the current timestamp on checkout completion. As far as we're concerned, that's when an order has been "created" that we actually need to respond to. It actually existed before then, and we'll retain that data in the order's revision log, but we really want to know when the order was finally submitted through a complete checkout process. I started imagining where I would put code to do this when I realized I wouldn't do that at all... a simple Rule would do the trick!

This Rule reacts to the event "Completing the checkout process" and includes a single "Set a data value" action to update the created timestamp to the current time. Because every order save triggers a new revision, we'll have the historical creation date if we want it, but the date that matters to the customer and to administrators (i.e. the date of checkout completion) will now appear properly. If you need the same behavior, you can import the following Rule:

{ "rules_update_the_created_timestamp_to_now" : {
    "LABEL" : "Update the created timestamp to now",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "commerce_checkout" ],
    "ON" : [ "commerce_checkout_complete" ],
    "DO" : [
      { "data_set" : { "data" : [ "commerce-order:created" ], "value" : "now" } }
    ]
  }
}

Now, I should be used to the level of flexibility we achieved in Drupal Commerce by now, but it still tickles me to no end that it really is that simple to change even obscure aspects of your e-commerce system through the user interface. When I communicate the strengths of the project as an eCommerce framework, concrete examples like this make the approach come to life for merchants and store administrators. It's a clear case of the software conforming to your business needs instead of forcing you to work within its constraints, and I look forward to seeing how else we can trick it out to grow our little cheese business.

Jan 22 2012
Jan 22

It's no secret that I love to travel (in appropriate doses) and meet new people, especially those doing e-commerce on Drupal. I love visiting the larger cities in the States, and I love even more visiting the older cities in Europe. Fortunately for me, these are the places that draw large Drupal events and make the most sense for Commerce Guys to put on Drupal Commerce trainings.

I'm currently wrapping up the final commits for a Drupal Commerce 1.2 release this week and will then start revising our training curriculum to accommodate a few recent UI improvements. Drupal Commerce is growing in popularity as an e-commerce framework, particularly among tech savvy developers and organizations (we still need to cater better to those with limited resources and Drupal skills), highlighting the need for better "self-help" documentation and resources and the continued need for personal training from expert users and developers.

I'll be involved in a couple of trainings in the next couple of months, and I hope there will be even more that I don't have to attend. (Unless of course they're in cities that are too good to pass up. )

If you have a project about to start or have recently been handed a site to maintain, consider one of these upcoming opportunities:


  • Paris is both my favorite city to visit and home to my favorite company to work for - what luck! We'll be presenting a three day developer training including personal instruction from myself and a few other members of our team. As my French knowledge goes about as far as a 1 year old's, and since we're expecting attendees from a variety of countries, rest assured this training is in English.

  • This will be our regular one day extravaganza where we introduce all that Drupal Commerce can do for you and demonstrate how to build a store using the core components and a few essential contributed modules. We'll provide a sandbox server so you can follow along and take your site with you when you go.

I've also recently put in work with Kent Bye of Lullabot to turn that one day course into a video series for Drupalize.me. We basically put down about four hours of video demonstrating how to build a site like my RealMilkCheese.com - no code required for a simple catalog, payment via PayPal, flat rate shipping, and a couple types of discounts. I'm looking forward to seeing it edited to a fine polish - Kent's a star at that stuff.

Sep 27 2011
Sep 27

In Drupal Commerce, a line item is any item added to an order that affects the order total. They represent products, shipping rates, certain types of discounts, and more. During sell price calculation for products and rate calculation for shipping, you actually apply discounts, fees, and tax rates as manipulations to the unit price of line items.

I've been dealing a lot with line items during a personal shipping sprint I've been on the last week and a half to help launch a client site. That work has involved a complete rewrite of Commerce Shipping in the 2.x branch to support carrier calculated rates (such as those returned by ConnectShip, UPS, FedEx, etc.). That work in turn has resulted in the release of a Physical Fields module that defines weight and dimensions fields and a Commerce Physical Product module that provides API support for determining when orders contain shippable products, the total weight of the order, and other useful things.

Once this site launches, I'll give more attention to the upgrade path for folks using Shipping 1.x to move up to Shipping 2.x. (I'll also need to rewrite the flat rate shipping method to go along with it.) To push forward integration with different carriers, we'll be holding a Shipping Sprint at DrupalCamp Atlanta, fittingly the corporate home of UPS.

During the course of my work on Commerce Physical Product, I was reminded that determining whether or not a line item represents a product isn't as straightforward as you would first think. It's nothing terribly tricky, but you can't just perform a simple check on the product type to reliably determine if a line item represents a product.

This is insufficient:

<?php
if ($line_item->type == 'product') {
 
// ...
}
?>

The reason is Drupal Commerce allows you to have multiple product line item types, each with their own unique fields that may be exposed through the Add to Cart form. This feature lets you sell customizable products where the various customizations are stored with the product reference in the line item.

A simple use case is adding a custom price field to a donation product line item type allowing customers to tell you how much they want to donate to a specific campaign. This can all be configured through the Field UI and Rules, mitigating the need for modules like UC Variable Price. Trés cool.

Since you can have multiple product line item types, we provide a helper function that returns an array of the names of every product line item type defined on the site. Instead of the code above, you can perform an in_array() check on the type of a line item to see if it is of any of the valid product line item types:

<?php
if (in_array($line_item->type, commerce_product_line_item_types())) {
 
// ...
}
?>

Any time you're writing code that should apply to a product line item, be sure to use this method instead of the first. Hope that helps you as you work on your Drupal Commerce contribs and custom modules. I almost forgot about this when writing Commerce Physical Product. Granted, I haven't been sleeping much recently, but if it's that easy for me to forget, I bet it's a bit unknown to the general public.

Sep 06 2011
Sep 06

One of the best things you can do for your project is highlight the contributors who are helping make it a success. Every patch counts, and every now and then you get someone in the queue who blows you away with a first patch that traces down some sneaky, hidden bug that you know took hours to track down. Attributing such patches has always been a matter of dropping the contributor's name into a commit message and thanking them in the issue in the past, but thanks to Git on drupal.org there is now a better way.

This may be old news for most folks, but I didn't discover this feature until just a couple months ago. It turns out that user profiles on drupal.org now include a Git attribution heading under which you can find the appropriate command line option to pass to git commit to attribute that user with a patch.

Attributing svendecabooter

By way of example, I recently committed a patch submitted by svendecabooter. I still formed my commit message using the tried and true format (including both the issue number and his username), but I also added the indicated text to the command:

git commit --author="svendecabooter <[email protected]>" -m "Issue #1197512 by svendecabooter: pass the entity rendering language down to the linked fields when rendering product fields."

Thanks to Git, even though I am the one committing the code, he is the one credited with authorship of it. This is visible both in the log for that commit and on the committers page for Drupal Commerce. Many thanks to the team for working this all out and helping maintainers give credit where credit is due.

Sep 01 2011
Sep 01

As it turns out, I really enjoyed my time in London. Getting to visit old, historic cities is quite a treat for someone from the Midwest in the U.S.A. There are no castle towers on hills or centuries old steeples gracing my skyline in Louisville, KY, and I'm quite a sucker for both. Getting to visit the Tower of London, which supplies arms to my local museum, turned out to be a special treat. I'm also a sucker for good food and drink (who isn't?), and while it's not the height of elegance, my first experience of fish and chips with mushy peas was good, too. Note to Americans: it's mush-y, not moosh-y.

Fish and chips with mushy peas. Mmm!
Fish and chips courtesy of The George.

My first couple of days in London were my busiest. I delivered a Drupal Commerce training to a room full of students with Greg Beuthin (a.k.a. smokinggoat), our in-house trainer par excellence. Unfortunately, he and I both had sniffles and scratchy throats, so I can only imagine what those reviews will say about our delivery... C'est la vie. We survived, but my day was only just getting started by the end.

For most of the next day and a half I was minding my queue in preparation for the 1.0 launch of Drupal Commerce. With the help of Bojan Zivanovic and Damien Tournoud (and a few others throughout the day), we were able to close out a variety of issues and ensure all of our automated tests were passing when we finally packaged the 1.0. In a feat of endurance sure to be remembered for ages to come, Damien and I outlasted Bojan's youthful energy to finalize the release after postponing dinner for a couple hours. That's what experience gets you, folks.

Excited Damien

An excited Damien is never too hungry to celebrate.

Proud father

It's a boy! He weighs 8 lbs. 6 oz. and is 22" long!

Coming to DrupalCon to collaborate with the other Commerce Guys and the various contributors from across Europe was the greatest part for me. Without the community, we wouldn't have the 1.0 that we do, a solid e-commerce framework that is not limited to a particular use case or locality. We're standing on the shoulders of Drupal core, the contributions of Merfago, and the dozens of patch contributors who have helped ensure Commerce can accommodate all those crazy taxes around the world. I also personally wouldn't have known that mushy peas are better with malt vinegar mixed in without John Albin Wilkins.

With the 1.0 out, my attention is now focused on ensuring our essential contributed modules are ready for use. I'm focusing specifically on making product administration simpler, ensuring Commerce Shipping supports calculated shipping quotes, and pushing code upstream from a local project into Commerce Addressbook. I always have a half dozen payment related projects in the works, too.

If you want to hear more about Drupal Commerce in person, I'll be talking about the project as an international community success story at DrupalCamp Atlanta. I'm busy compiling statistics on committers and contributions to share along with my usual hand-waving, mile-a-minute overview of the modules' functionality.

I'll also deliver a show-and-tell style training at this year's Do It With Drupal in NYC. I love DIWD as a more intimate gathering of module authors, core contributors, and web pros from outside the Drupal community. It's a great place for attendees to soak in a wealth of information and run their project needs by the folks writing the code they'll use. Today is the last day for early bird pricing, so if you're on the fence, you may as well make the impulse buy and come hang out in New York with us.

I hope to see many of you at those events and many more minding the queues.

Aug 21 2011
Aug 21

At long last I'm breathing British air and getting psyched for tomorrow's Drupal Commerce training. I lived in the UK for four years as a child but only have vague memories of a nanny and getting AG Bear and My Buddy for Christmas. I didn't come back with a nanny, but I did bring along my wife to help take care of me and my daughter to carry the dolls. We spent a few days in Paris recovering from jetlag, ringing in our fifth year of marriage, and finalizing training arrangements before riding the Eurostar to London with the rest of the team this afternoon.

We'll have a total of fourteen Commerce Guys at DrupalCon London, meaning we'll have plenty of people on hand to talk about Drupal Commerce. In addition to tomorrow's training, we'll be presenting / discussing the Commerce modules and contribs in BoF sessions throughout the week. To see the line-up, check the BoF schedule under Room 334. If we can record or screen capture anything from these, they'll end up on the Commerce Guys Vimeo channel.

I'm looking forward to the Developing with Drupal Commerce session on Thursday, because it will be me first go at leading a panel discussion instead of introducing all things Drupal Commerce in a solo, hand-waving, water-guzzling presentation.

I'll be joined by several other developers and business owners who have been bidding on and building Drupal Commerce sites since the alpha and beta releases. We're now gearing up for a 1.0 release thanks to the hard work and contributions of everyone on the panel. It should be valuable and entertaining to hear them talk about what it's like to develop with Drupal Commerce and how the core modules have evolved since they've been working with them.

Last but not least, for everyone who doesn't care a lick about e-commerce but likes Indian food, I have discovered the best Indian place in Croydon. Look no further than The Spicy Affair for a fair-priced, keenly seasoned meal (with a surprisingly kid friendly wait staff!). That's probably the most controversial statement I made in this blog post, and I can't defend it as though I'm some sort of connoisseur. If you know a better place, feel free to link it in. Otherwise I'll see you there.

Jun 25 2011
Jun 25

As part of the sprint we're holding in Paris right now to introduce new Commerce Guys to Drupal Commerce development, we devised a situation where we wanted a conditionally available message on the checkout form. We decided for a shipping scenario that we wanted to present a message to the user regarding shipping costs inline with the address form if the customer selected a shipping address outside of the free shipping country of the store.

Adding a random text message to a form is trivial. You can just add a markup element to the form, using a div tag to make sure it ends up in a fieldset if necessary:

<?php
$form
['message'] = array(
 
'#markup' => t('What a wonderful message!'),
);
?>

Additionally, adding a #states array that includes the instruction to hide a form element on the basis of a select list's value is trivial:

<?php
$form
['message'] = array(
 
'#markup' => t('What a wonderful message!'),
 
'#states' => array(
   
'invisible' => array(
     
':input[name="select_list_name"]' => array('value' => 'US'),
    ),
  ),
);
?>

Unless I botched my pseudo code, that #states array should instruct the Form API to include JavaScript to hide the element when the select list I specified has a value of US. Unfortunately, that code won't work. Shocked

The problem is that the JavaScript that hides the element depends on the element's ID to target the behavior, and a markup element by default gets no wrapping. This means you can't directly put a #states array on a markup element in general. You do have a few options to work around this, and I'll end with what we went with in our case... you can tell me if we're crazy. Sticking out tongue

  1. You could just hardcode a div wrapper that includes the ID and the form-wrapper class Drupal expects, but I can't say that I'd recommend it. Names change quite frequently during development and can easily be altered.
  2. You can also just put the markup element inside a container element and attach the #states array to the container. Containers are rendered as divs with proper IDs for targeting, so this works just fine.
  3. However, we wanted a compact solution, so what we did is turn the markup element into a container element and set its #children property to the message. This effectively makes the container element function as a markup element, but it actually wraps the markup in the appropriate div on output. Since #children is already set, this does mean that the container element cannot actually contain other elements, so there may be good reasons for you not to try this at home.

The gist of our solution was:

<?php
$form
['message'] = array(
 
'#type' => 'container',
 
'#children' => t('What a wonderful message!'),
 
'#states' => array(
   
'invisible' => array(
     
':input[name="select_list_name"]' => array('value' => 'US'),
    ),
  ),
);
?>

I suppose it would be nice if we didn't have to abuse the #children property name, but this seems like fair game to me unless it's a possibility to change the markup element to include the div and expected ID.

Mar 01 2011
Mar 01

Because we were doing our Commerce module development on GitHub and exporting to CVS, we need to make some changes now that the Git migration on d.o is complete. Obviously the main Git repository for the project is now on d.o instead of GitHub. To clone the latest code, you can follow the helpful Git instructions included on Drupal project pages.

All of my D7 projects now include a 7.x-1.x branch that you should track to get the latest commits. I also updated the various dev releases of Commerce, Address Field, and my Commerce contribs to be snapshots of this branch, essentially deprecating master. I'm trying to decide the best thing to do about those pesky master branches and will likely just git rm everything in them and leave behind a README indexing the various HEADs in the repository.

Many people had forks of both the old Commerce repository and my development repository on GitHub. Additionally, some of you may have pending commits that haven't been pulled yet. If this is the case for you, please generate a patch instead of a new pull request and post it to the issue queue. As of this point I have no plans to rewrite the commit history of the new official repository to match the existing history on GitHub, meaning I cannot cleanly pull from your repositories.

(I have read Ben's blog post, and I'm sure there are some other finer aspects of Git that I'm just ignorant of to accommodate this... but I'm not sure it's worth the hassle when forks will need to be updated across the board anyways.)

This seems a little brute force, but I think it's for the best. The commit graph on d.o is now a nice tidy straight line, whereas the old graph on GitHub was a fractured mess that included several instances of duplicated commits thanks to botched merges and branching. We were still learning an appropriate Git workflow at the time and made several mistakes that not only dirtied up the history but also made it hard to sort out how to pull from various forks. (Accordingly, current contributor statistics on Ohloh are inaccurate anyways.)

This does mean some contributor credit in the commits will be lost, but I'll be updating various project pages to credit beta contributors for their commits. Regardless, I've been crediting contributors in commit messages all along, and merge commits show whose repository the merged commits came from. As of this point, I think the loss of a little meta information is worth the clean slate with the new repositories. Flame away in the comments if this is the stupidest idea you've ever heard... just want to make sure my plans are clear.

While we figure out how to handle pull requests in an environment that doesn't natively support them, in your issue please indicate your repository URL (whether it's a d.o sandbox of GitHub fork) and branch that I should pull from to compare. Bonus points for attaching a patch for quick review on site (or linking to the diff on the appropriate web interface). I'll add your repository as a remote so you don't have to post it every time. Additionally, I'd prefer it if you used a single branch per issue you're addressing with the branch name simply being the nid of the issue - makes it quite easy for me to branch and pull locally.

(I should mention that the good ol' patch process is perfectly fine if you don't want to maintain a public repository for me to pull from. You can just make your commits locally and diff 'em all in one fell swoop to create a patch for review.)

This is essentially what we've been doing on GitHub, so no surprises here for existing contributors. I'll leave the GitHub repos up for a while, but I'm updating their READMEs to point to the new repository on d.o. Once tested and approved, these guidelines will find their way into a handbook page for posterity's sake.

Feb 23 2011
Feb 23

This is a quick call for help before I package up a beta release of Drupal Commerce. The last few weeks I've been working around the clock on blocking issues, dependency issues, Rules based pricing and tax (incl. VAT) support, and last minute database tweaks. My wife has been incredibly supportive of me thus far, but now I need help from my friends with a bit more technical acumen.

Here's the deal: for all intents and purposes, this code is beta ready. Database schema changes have mellowed out. The modules have solidified. The core feature set lets you start selling quickly. The Views and Rules integration provides for some fine standard interfaces and workflows. The last few weeks, pcambra has been our SimpleTest hero, and now he's working with recidive to flesh out the functional tests even further.

What it really needs is eyes. Your eyes. If you have a few spare moments, you could greatly help by testing an installation and ensuring there aren't any crazy bugs that I just don't see because of my development environment or selective blindness. These could take the form of installation bugs, odd default configurations in Views / Rules, typos, broken access control, and more. There are bound to be things I'm missing, and I really need your help to know what they are.

Here's how to get started very quickly:

  1. Download into your sites/all/modules directory the latest dev versions of the following dependencies:
    1. (Note: Getting these from CVS would be better to get their latest commits.)

    2. Download into your sites/all/modules directory my Git dev version of Drupal Commerce (or just git clone git://github.com/rszrama/drupalcommerce.git).
    3. Download into your profiles directory my Commerce Dev installation profile and download into your sites/all/modules directory Admin Menu (a dependency of the installation profile).
    4. Now install Drupal 7 using the Commerce Dev installation profile and see what happens!
    5. If you're feeling adventurous, use the Standard installation profile and then try to enable the Commerce modules manually to make sure the standard install process works. (You'll have to adjust some permissions, enable the cart block, and build a product display node type from scratch - read more about that in the first issue of Drupal Watchdog. )

    Once it's all installed, cruise through the various admin interfaces, settings forms, and front end features and let me know what breaks. Note, I'm not looking for support requests, "How do I...?", or feature requests, "Needs flat rate shipping support." Rather, I want to know what, if anything, of the core feature set just doesn't work.™

    One of the latest features to test will be to configure a tax rate for your country / state. Simply browse to admin/commerce/config/taxes and add the tax rate. If you made it a sales tax, it'll show up once you get to checkout. If you made it a VAT, it'll show up inclusive in product prices. Additionally, if you made it a VAT, you can edit products and enter their prices including VAT. Taxes work through the same Rules event as other product pricing rules, so you can try adding a discount rule and fiddle with its weight to see how it interplays with your tax rules.

    Drupal Commerce comes with an example payment method module that lets you just put a name in on the checkout form to test payment. You can test additional payment methods if you have developer accounts for Authorize.Net, CyberSource, or PayPal.

    Please report any bugs you can turn up (or +1 existing bugs) in our issue tracker. I'll also be hanging out in #drupalcommerce on irc.freenode.net if you're into IRC.

    While you do this, I'll be running tests of my own, reviewing the names and descriptions of all our permissions, and ensuring the customer profile integration with Checkout and Order administration is up to snuff.

    With any luck, we'll all be beta testers tomorrow.

    Jan 28 2011
    Jan 28

    I started to answer this question with a discussion of my own motivations for module development. They are many and varied, but they pretty much all come down to me either having an idea and some time or me getting paid to make time for an idea. However, I realize a person's motivations for writing his or her intangible "Drupal App" don't really matter if a particular motivation can co-exist with the existing model of community module development (whether it's evil or not, ignored or not, mirrored or not)... and ultimately I didn't want to do Robert's problem solving for him on what that could look like.

    I then decided to take the angle of problems with the architecture of Drupal modules vs. an App store model, current support and maintenance channels, and a host of other problems I see with the idea of Drupal apps. Some points were established elsewhere... Yes, we can't really sell modules. Yes, people are selling themes. But no, I don't think selling "Features" would work... or at least I don't think it would be good for the consumer.

    The traditional "App" (I hate that word - really? are we selling full applications?) must encapsulate its functionality, and it can't be effectively supported if its innards are free to be customized and mixed in with (i.e. broken by) other modules. This lack of interoperability between paid plugins on other platforms was actually quite a shock to me at last year's CMS Expo and is a big weakness. It also increases the development burden on the "App developer" making it a net loss for the consumer and provider. (Really, I saw an e-commerce plugin baking in its own Views system.) In fact, the only person I see getting a good deal is the "App distributor."

    But I digress... these are just software / social engineering problems. If distributors really wanted developers and consumers to buy into their distribution models, they just have to provide solutions for these things. Once again, I'm not trying to do anyone's problem solving... unless they want to cut me in on their good deal.

    What an App Store won't solve

    I think other threads of this conversation have been dealt with adequately elsewhere, and overall I think an App store could work if all caveats are accounted for and the store's success is mitigated enough by the strengths of drupal.org to not blast holes in the community development model we currently have. One thing I don't see getting a lot of play in the discussion, though, is whose problems an App store wouldn't solve. I've been thinking about this since taking part in the discussion with ICanLocalize (sorry, can't find the link).

    A paid distribution channel will not provide you with the time or money to code or support your module. You still have to make the initial investment in time or money to get your "App" written, and long before you're turning a profit you'll need to be proving your intent and ability to support your product. If you then rely solely on distribution fees to recover your investment, you're relying on the wroooong license to get 'er done. If you intend to bundle support and maintenance with the distribution, I just need to point out again... this is first and foremost a good deal for the distributor unless he turns your App into Angry Birds.

    Really, though, this is freaking Drupal... all we need is for enough interested people to build an installation profile for paid module support. Does that mean every module's support would go behind a paywall? I sincerely doubt it, as again, developers still have to prove their competence to support their project to non-paying new customers to convert them in the first place. They're also not the only ones who support modules on d.o... every one of their users is a potential support provider.

    I do think that publicizing intentionally scaled back support in the absence of a paid distribution channel is not a good way to win hearts and minds. You don't have to say it, just do what you need to make money and offer premium support for people willing to pay for it. There are also other ways to build support around your module in the community, whether it's a bug squad or a sponsored development sprint.

    Leaving module developers behind

    Finally, something that just hit me... the only "Apps" I see as being viable at present are SaaS plugins and themes (thanks to licensing opportunities). Others see distributions and Features-esque configurations as viable. Perhaps there are still other viable options, but at the end of the day, none of this translates into dollars to fund the module development that any of these products depends on. And isn't that what started the conversation in the first place? Are we trying to figure out how to support module developers, or are we looking for a different way to make money using Drupal + contributed modules beyond professional services?

    About Drupal Sun

    Drupal Sun is an Evolving Web project. It allows you to:

    • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
    • Facet based on tags, author, or feed
    • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
    • View the entire article text inline, or in the context of the site where it was created

    See the blog post at Evolving Web

    Evolving Web