Planet Drupal

Syndicate content - aggregated feeds in category Planet Drupal
Updated: 12 min 15 sec ago

Red Crackle: Should you create a Page View or a Block View?

Wed, 07/01/2015 - 21:08
You need to show a list of content on a page. You know that you need to use Views for it. But you are wondering whether to create a Page View or a Block View. Ask yourself this simple question to decide it for yourself.

Another Drop in the Drupal Sea: How Much Will it Cost to Build this Website?

Wed, 07/01/2015 - 20:59
pAs professionals in the web tech sector, we know that there is no one set answer to that question. And yet, we really don't want to be spending our time having to explain over and over to prospects why we can't just answer the question./p pWe could provide an analogy and respond by saying, That's like asking a random custom home builder how much it's going to cost to build a house. We could continue by explaining that the builder will need to know the location of the house, the square footage of the house, the desired finishes on the house, etc./p pa href= target=_blankread more/a/p

Drupal @ Penn State: A Significant Event

Wed, 07/01/2015 - 17:36
pYesterday something significant occurred, a href= target=_blank launched on the new Polaris 2 Drupal platform. And soon the a href= target=_blankAbington Campus/a web site will move to the same platform. And perhaps many more./p

Advomatic: Protecting’s Privacy and Security

Wed, 07/01/2015 - 17:25
Earlier this year, we launched a new site for the ACLU. The project required a migration from Drupal 6, building a library of interchangeable page components, complex responsive theming, and serious attention to accessibility, security and privacy. In this post, I’ll highlight some of the security and privacy-related features we implemented. Privacy As an organization, the... a class=excerpt-read-more href= title=ReadProtecting;s Privacy and SecurityRead more #187;/a

Agaric Collective: Performant bulk-redirection with Apache RewriteMap

Wed, 07/01/2015 - 15:47
p class=leadWhen continuing development of a web site, big changes occur every so often. One such change that may occur, frequently as a result of another change, is a bulk update of abbr title=uniform resource locatorURL/abbrs. When this is necessary, you can greatly improve the response time experienced by your users—as they are redirected from the old path to the new path—by using a handy directive offered in Apache's mod_rewrite called RewriteMap./p pAt Agaric we regularly turn to Drupal for it's power and flexibility, so one might question why we didn't leverage Drupal's support for handling redirects. When we see an opportunity for our software/system to respond as early as it can, it is worth investigating how that is handled. Apache handles redirects itself, making it entirely unnecessary to hand-off to PHP, never mind Drupal bootstrapping and retrieving up a redirect record in a database, just to tell a browser (or a search engine) to look somewhere else./p pThere were two conditions that existed making use of RewriteMap a great candidate. For one, there will be no changes to the list of redirects once they are set: these are for historical purposes only (the old URLs are no longer exposed anywhere else on the site). Also, because we could make the full set of hundreds of redirects via a single RewriteRule—thanks to the substitution capability afforded by RewriteMap—this solution offered a fitting and concise solution./p pSo, what did we do, and how did we do it?/p pWe started with an existing set of URLs that followed the pattern: code[/tab-name]/code. Subsequently we implemented a module on the site that produced aliases for our user page URLs. The new patten to the page was then (given exceptions for multiple J Smiths, etc via the suffix): code[-suffix#][/tab-name]/code. The mapping of ID to firstname-lastname[-suffix#] was readily available within Drupal, so we used an update_hook to write out the existing mappings to a file (in the Drupal public files folder, since we know that's writable by Drupal) . This file (which I called 'staffmapping.txt') is what we used for a simple text-based rewrite map. Sample output of the update hook looked like this:/p pre # User ID to Name mapping: 1 admin-admin 2 john-smith 3 john-smith-2 4 jane-smith /prep The format of this file is pretty straight-forward: comments can be started on any line with a #, and the mapping lines themselves are composed of code{lookupValue}{whitespace}{replacementValue}/code./p pTo actually consume this mapping somewhere in our rules, we must let Apache know about the mapping file itself. This is done with a a href= directive/a, which can be placed in the Server config or else inside a a href= directive/a. The format of the RewriteMap looks like this: RewriteMap MapName MapType:MapSource. In our case, the file is a simple text file mapping, so the MapType is 'txt'. The resulting string added to our VirtualHost section is then: codeRewriteMap staffremap txt:/path/to/staffmapping.txt/code This directive makes this rewrite mapping file available under the name staffremap in our RewriteRules. There are other MapTypes, including ones that uses random selection for the replacement values from a text file, using a hash map rather than a text file, using an internal function, or even using an external program or script to generate replacement values./p pNow it's time to actually change incoming URLs using this mapping file, providing the 301 redirect we need. The rewrite rule we used, looks like this:/p preRewriteRule ^user-detail/([0-9]+)(.*) /user-detail/${staffremap:$1}$2 [R=301,L]/prep The initial argument to the rewrite rule identifies what incoming URLs this rule applies to. This is the string: ^user-detail/([0-9]+)(.*). This particular rule looks for URLs starting with (signified by the special character ^) the string user-detail/, then followed by one or more numbers: ([0-9]+), and finally, anything else that might appear at the end of the string: (.*). There's a particular feature of regex being used here as well: each of search terms in parenthesis are captured (or tagged) by the regex processor which then provides some references that can be used in the replacement string portion. These are available with code$lt;captured positiongt;/code—so, the first value captured by parenthesis is available in $1—this would be the user ID, and the second in $2—which for this expression would be anything else appearing after the user ID./p pFollowing the whitespace is our new target URL expression: /user-detail/${staffremap:$1}$2. We're keeping the beginning of the URL the same, and then following the expression syntax ${rewritemap:lookupvalue}, which in our case is: ${staffremap:$1} we find the new user-name URL. This section could be read as: take the value from the rewrite map called staffremap, where the lookup value is $1 (the first tagged expression in the search: the numeric value) and return the substitution value from that map in place of this expression. So, if we were attempting to visit the old URL /user-detail/1/about, the staffremap provides the value admin-admin from our table. The final portion of the replacement URL (which is just $2) copies everything else that was passed on the URL through to the redirected URL. So, for example, /user-detail/1/about includes the /about portion of the URL in the ultimate redirect URL: /user-detail/admin-admin/about/p pThe final section of the sample RewriteRule is for applying additional flags. In this case, we are specifying the response status of 301, and the L indicates to mod_rewrite that this is the last rule it should / That's basically it! We've gone from an old URL pattern, to a new one with a redirect mapping file, and only two directives. For an added performance perk, especially if your list of lookup and replacement values is rather lengthy, you can easily change your text table file (type txt) with a HashMap (type dbm) that Apache's mod_rewrite also understands using a quick command and directive adjustment. Following our example, we'll first run:/p pre $gt; httxt2dbm -i staffrepam.txt -o /prepNow that we have a hashmap file, we can adjust our RewriteMap directive accordingly, changing the type to map, and of course updating the file name, which becomes: /p preRewriteMap staffremap dbm:/path/to/ RewriteMap substitutions provide a straight-forward, and high-performance method for pretty extensive enhancement of RewriteRules. If you are not familiar with RewriteRules generally, at some point you should consider reviewing the a href= documentation on mod_rewrite/a—it's worthwhile knowledge to have./p ul class=inline lia href=/tags/drupal-planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype= class=badge badge-infoi class=icon-tag icon-white/i Drupal Planet/a/li lia href=/tags/apache typeof=skos:Concept property=rdfs:label skos:prefLabel datatype= class=badge badge-infoi class=icon-tag icon-white/i Apache/a/li lia href=/tags/performance typeof=skos:Concept property=rdfs:label skos:prefLabel datatype= class=badge badge-infoi class=icon-tag icon-white/i Performance/a/li /ul

Dries Buytaert: One year later: the Acquia Certification Program

Wed, 07/01/2015 - 15:31
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpA little over a year ago a href= launched the Acquia Certification Program for Drupal/a. We ended up the first year with close to 1,000 exams taken, which exceeded our goal of 300-600. Today, I'm pleased to announce that the Acquia Certification Program passed another major milestone with over a href=,000 exams passed/a (not just taken)./p pPeople have debated the pros and cons of software certifications for years (a href= myself/a) so I want to give an update on our certification program and some of the lessons learned./p pAcquia's certification program has been a big success. A lot of Drupal users require Acquia Certification; from the Australian government to Johnson amp; Johnson. We also see many of our agency partners use the program as a tool in the hiring process. While a certification exam can not guarantee someone will be great at their job (e.g. we only test for technical expertise, not for a href=, it does give a frame of reference to work from. The feedback we have heard time and again is how the a href= Certification Program/a is tough, but fair; validating skills and knowledge that are important to both customers and partners. /p pWe also made the a href= Magazine Salary Survey/a as having one of the most desired credentials to obtain. To be a first year program identified among certification leaders like Cisco and Red Hat speaks volumes on the respect our program has established. /p pCreating a global certification program is resource intensive. We've learned that it requires the commitment of a team of Drupal experts to work on each and every exam. We know have four different exams: developer, front-end specialist, backend specialist and site builder. It roughly takes 40 work days for the initial development of one exam, and about 12 to 18 work days for each exam update. We update all four of our exams several times per year. In addition to creating and maintaining the certification programs, there is also the day-to-day operations for running the program, which includes providing support to participants and ensuring the exams are in place for testing around the globe, both on-line and at test centers. However, we believe that effort is worth it, given the overall positive effect on our community./p pWe also learned that benefits are an important part to participants and that we need to raise the profile of someone who achieves these credentials, especially those with the new a href= Certified Grand Master credential/a (those who passed all three developer exams). We have a special a href= Master Registry/a and look to create a platform for these Grand Masters to help share their expertise and thoughts. We do believe that if you have a Grand Master working on a project, you have a tremendous asset working in your favor. /p pAt DrupalCon LA, the Acquia Certification Program offered a test center at the event, and we ended up having 12 new Grand Masters by the end of the conference. We saw several companies stepping up to challenge their best people to achieve Grand Master status. We plan to offer the testing at DrupalCon Barcelona, so take advantage of the convenience of the on-site test center and the opportunity to meet and talk with Peter Manijak, who developed and leads our certification efforts, myself and an Acquia Certified Grand Master or two about Acquia Certification and how it can help you in your career!/p /div/div/div

Jim Birch: Essential Drupal: Stage File Proxy

Wed, 07/01/2015 - 11:20
a href=;utm_medium=drupal-planetamp;utm_campaign=node/39 title=Essential Drupal: Stage File Proxyimg src= width=620 height=465 alt=Lego Uncle Jim in the bushes title=Lego Uncle Jim in the bushes //abr pWe can easily checkout code from our git repositories for our local, development, and staging servers.  We can get a database from the live site through Backup and Migrate, drush, or a number of other ways.  But getting the files of the site, the images, pdfs, and everything else in /sites/default/files is not on the top of the list of most developers.  In recent versions of Backup and Migrate, you can export the files, but often times, this can be a huge archive file.  There is an easier way./p pThe a href= File Proxy/a module saves the day by sending requests for files to the live server if it does not exist yet in your local environment.  This saves you space on your non-production environment since it only grabs files from the pages you visit.  Great for us that have dozens of sites on our local. /p pAs simple as can be, it gets the files you need on your local server, as you need them.  No more navigating broken looking dev sites.  This will get your environment looking as it should so you can concentrate on your task at hand./p pa href=;utm_medium=drupal-planetamp;utm_campaign=node/39 title=Essential Drupal: Stage File ProxyRead more/a/p

Sooper Drupal Themes: YoutTube Video of Drupal Theme integrated Drag and Drop builder

Wed, 07/01/2015 - 10:22
div class=field-body After I posted a case study a href= week/a I had a number of readers ask me if they could try a demo and see how it works. There is no try-out demo yet but in the meanwhile I produced a video that demonstrates the basic controls: style.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }/stylediv class=embed-containeriframe src= allowfullscreen= frameborder=0/iframe/div If you have any questions about integration and the open source library that powers it feel free to contact or comment! /div h3 class=field-label Tags /h3 div class=field-tags a href=/category/tags/planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=planet/a /div div class=field-tags a href=/tags/drag-and-drop typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drag and drop/a /div div class=field-tags a href=/tags/glazed typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=glazed/a /div div class=field-blog-tags a href=/tags/planet-0 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=planet/a /div div class=field-blog-tags a href=/tags/drag-and-drop-0 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drag and drop/a /div div class=field-blog-tags a href=/tags/glazed-0 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=glazed/a /div h3 class=field-label Drupal /h3 div class=field-drupal a href=/category/core-compatibility/7x typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=7.x/a /div

KatteKrab: Comparing D7 and D8 outta the box

Wed, 07/01/2015 - 03:53
div class=field field-name-post-date field-type-ds field-label-hiddendiv class=field-itemsdiv class=field-item evenWednesday, July 1, 2015 - 11:53/div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpI did another video the other day. This time I've got a D7 and D8 install open side by side, and compare the process of adding an article.iframe allowfullscreen= frameborder=0 height=315 src= width=560/iframe/p /div/div/divdiv class=field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-hidden clearfixul class=linksli class=taxonomy-term-reference-0a href=/category/tags/drupalplanetdrupalplanet/a/li/ul/div

Pixelite: Debugging Drupal performance with Cache Debug module

Wed, 07/01/2015 - 02:00
h2 id=prefacePreface/h2 pThis blog post is for developers, not site builders, as the analysis for cache debugging requires knowledge about the runtime stack of Drupal./p h2 id=the-problem-with-caching-in-drupal-7The Problem with Caching in Drupal 7/h2 pTo obtain performance in Drupal 7, Drupal relies heavily on caching. That is, to process something and cache the end result so that same work doesn’t need to be repeated. Conditions also have to be created for when that cache expires or is invalidated. Drupal has a caching layer to help with this. When you want to store something in cache, you use a href=, to retrieve it, you use a href= and to wipe the cache bin clean, you can use a href= pOften, modules can implicitly clear or set cache unintentionally. This can lead to more caching overhead than you need. For example, theme registry clearing, use of the variable_set function or calls to other modules that call cache_clear_all. The problem is, how do you track down culprits to fix the issue?/p h2 id=enter-cache-debugEnter Cache Debug/h2 pa href= Debug/a is a module that wraps around the caching layer and adds logging. Including stacktrace information. It means when a cache_set or cache_clear_all is called, you can trace back to what called it - understand the problem and fix it. Very quickly./p pIt comes with three logging options:/p ul listrongwatchdog/strong - good if you’re using syslog module but deadly if you’re using dblog./li listrongerror_log/strong - logs to your php error log/li listrongarbitrary file/strong - specify your own log file to log to/li /ul h2 id=configuring-cache-debugConfiguring Cache Debug/h2 pBecause the caching system is so highly utilized, cache logging can be incredibly verbose. Perhaps this is why there is no logging around this in Drupal core. Fortunately, Cache Debug is highly configurable to control what to log./p pstrongNOTE:/strong Because the caching system is loaded and used before Drupal’s variable system which manages configuration, it is best to set configuration in settings.php rather than in the database. However, there is a web UI that does set configuration in the database for ease of use./p h3 id=basic-configurationBasic configuration/h3 pIf you’ve used the memcache module before, this should feel familiar. In order to use Cache Debug, you need to set it as the cache handler:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_backends#39;/spanspan class=p][]/span span class=o=/span span class=s1#39;sites/all/modules/cache_debug/;/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_default_class#39;/spanspan class=p]/span span class=o=/span span class=s1#39;DrupalDebugCache#39;/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div pThis tells Drupal that there is a cache backend located in the path provided (make sure its correct for your Drupal site!) and that the default class for all cache bins is the DrupalDebugCache class. If you only want to monitor a single bin you may want to omit this option./p pSince Cache Debug is a logger and not an actual caching system, it needs to pass cache requests onto a real cache system. By default, Debug Cache will use Drupal core’s Database Cache system for cache storage, but if you’re using memcache, redis or similar, you may want to set that as the handler for Cache Debug:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_class#39;/spanspan class=p]/span span class=o=/span span class=s1#39;MemCacheDrupal#39;/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_cache_debug_form#39;/spanspan class=p]/span span class=o=/span span class=s1#39;DrupalDatabaseCache#39;/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div pYou need to also configure those modules accordingly./p pAt this point, you’ll be logging all cache calls and stack traces to set and clear calls to the php error log./p h3 id=configure-the-logging-locationConfigure the logging location/h3 pYou may want to choose your own logging location. For example, if you use dblog, then you won’t want to log to watchdog because it will bloat your database. Likewise, if you don’t want to bloat our php error log, then you may want to log to an arbitrary file. You can choose your logging location by setting codecache_debug_logging_destination/code to error_log (default), watchdog or file. For file you will also need to provide the location:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_logging_destination#39;/spanspan class=p]/span span class=o=/span span class=s1#39;file#39;/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_filepath#39;/spanspan class=p]/span span class=o=/span span class=s1#39;/tmp/cachedebug.log#39;/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div h3 id=configuring-logging-optionsConfiguring logging options/h3 pYou can choose to log calls to cache get, getMulti, set and clear. You can also choose to log a stacktrace of these calls to show the stack that triggered the call. This is most useful for calls to SET and CLEAR. For a minimal logging option with the most about of insight, you might want to try this:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_get#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_getMulti#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_set#39;/spanspan class=p]/span span class=o=/span span class=kTRUE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_clear#39;/spanspan class=p]/span span class=o=/span span class=kTRUE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_stacktrace_set#39;/spanspan class=p]/span span class=o=/span span class=kTRUE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_stacktrace_clear#39;/spanspan class=p]/span span class=o=/span span class=kTRUE/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div h3 id=logging-per-cache-binLogging per cache bin/h3 pYou don’t have to log the entire caching layer if you know which bin to look at for the caching issue you’re observing. For example, if you’re looking for misuse of variable_set, you only need to log the cache_bootstrap bin. In which case you could do this:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=c1# Do not log to all cache bins so ensure this line is removed (from above):/span span class=c1# $conf[#39;cache_default_class#39;] = #39;DrupalDebugCache#39;;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_bootstrap_class#39;/spanspan class=p]/span span class=o=/span span class=s1#39;DrupalDebugCache#39;/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div h3 id=configure-for-common-issuesConfigure for common issues/h3 pVariable set calls and theme registry rebuilds are the two most common issues and so Cache Debug has use cases for these issues built in. So long as Cache Debug is the cache handler for the bin, you can turn off logging and turn on these features and Cache Debug will only log when these issues occur:/p div class=highlightprecode class=language-php data-lang=phpspan class=cplt;?php/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_default_class#39;/spanspan class=p]/span span class=o=/span span class=s1#39;DrupalDebugCache#39;/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_common_settings#39;/spanspan class=p]/span span class=o=/span span class=karray/spanspan class=p(/span span class=s1#39;variables#39;/span span class=o=gt;/span span class=kTRUE/spanspan class=p,/span span class=s1#39;theme_registry#39;/span span class=o=gt;/span span class=kTRUE/spanspan class=p,/span span class=p);/span span class=c1// Turn off logging/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_get#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_getMulti#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_set#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=nv$conf/spanspan class=p[/spanspan class=s1#39;cache_debug_log_clear#39;/spanspan class=p]/span span class=o=/span span class=kFALSE/spanspan class=p;/span span class=cp?gt;/spanspan class=x/span/code/pre/div h2 id=analysing-the-logged-dataAnalysing the logged data/h2 pCache debug logs to a log file like the example below: img src= alt=Example output of cache debug logging class=img-responsive img-thumbnail //p pIn this snapshot of log output you can see both how cache debug logs cache calls and the stacktracing in action./p h3 id=log-format-structureLog format structure/h3 pA log line starts with a value that describes the cache bin, the cache command and the cache id. E.g. codecache_bootstrap-gt;set-gt;variables/code would bet a cache_set call to the cache_bootstrap cache bin to set the variables cache key. Some calls also log additional data, for example, cache clear also indicates if the call was a wildcard clear. Set calls also log how much data (length) was set./p h3 id=stack-trace-logsStack trace logs/h3 pWhen stack tracing is enabled for specific commands, a stack trace will be logged immediately after the log event that triggered it. The trace rolls back through each function that led to the current cache command being triggered. In the example above you can see that cache_clear_all was called by drupal_theme_rebuild which was called by an include from phptemplate_init. If you look at the source code in phptemplate_init, you’ll see that this means a cache rebuild was triggered from including template.php. In this case it was that Zen base theme had the theme registry rebuild left on./p

Open Source Training: Using Administration Menu and Shortcuts in Drupal

Tue, 06/30/2015 - 19:26
pAn OSTraining members took our recommendation and installed the Administration Menu module, which makes it much easier to navigate through your Drupal site./p pHowever, after enabling Administration Menu, they found that they lost their Shortcuts menu. This is normally the grey bar under Drupal's default admin toolbar./p pHere's how to use Administration Menu and Shortcuts together./p pFirst, make sure that Administration menu is enabled, but also make sure that the Administration menu Toolbar style module is enabled:/p div id=step_1 class=lessonStep top div class=StepImageimg src= alt= width=700 height=102 //div div class=instructions pNow go to Configuration gt; Administration Menu and you'll now be able to check the Shortcuts box, as in the image below. This will re-enable the Shortcuts menu./p /div /div div class=clearnbsp;/div div id=step_2 class=lessonStep top div class=StepImageimg src= alt= width=482 height=369 title= //div div class=instructions pIf you don't see the Shortcuts menu immediately, try clicking the down arrow in the top-right corner:/p /div /div div class=clearnbsp;/div div id=step_3 class=lessonStep top div class=StepImageimg src= alt= width=700 height=154 //div /divimg src= height=1 width=1 alt=/

Pantheon Blog: An Example Repository to Build Drupal with Composer on Travis

Tue, 06/30/2015 - 18:59
A robust Continuous Integration system with good test coverage is the best way to ensure that your project remains maintainable; it is also a great opportunity to enhance your development workflow with Composer. Composer is a dependency management system that collects and organizes all of the software that your project needs in order to run. 

Acquia: Caching to Improve Drupal Performance: The Three Levels You Should Know

Tue, 06/30/2015 - 18:07
figure class=field-item even rel= resource= class=field-item even div id=styles-2 class=styles styles-field-image styles-style-scale_width_280 styles-container-image styles-preset-scale_width_280 img typeof=foaf:Image src= alt= title= //div !-- render the title tag as caption -- /figure div class=field field-name-body field-type-text-with-summary field-label-hidden div class=field-items div property=content:encoded class=field-item evenpimg src=/sites/default/files/performance_round_0.jpg alt=image that illustrates how caching to improve drupal performance //p pIn our continuing mission (well, not a mission; it’s actually a href=/blog/drupal-website-performance target=_blanka blog series/a) to help you improve your Drupal website, let’s look at the power of caching./p pIn our previous post, we debunked some too common a href=/blog/improve-your-drupal-web-site-performance-without-coding target=_blankDrupal performance advice/a. This time we're going positive, with a simple, rock-solid strategy to get you started: caching is the single best way to improve Drupal performance without having to fiddle with code. /p pAt the basic level, it is easy enough for a non-technical user to implement. Advanced caching techniques might require some coding experience, but for most users, basic caching alone will bring about drastic performance improvements./p pCaching in Drupal happens at three separate levels: application, component, and page. Let’s review each level in detail./p h2Application-level caching/h2 pThis is the caching capability baked right into Drupal. You won't see it in action unless you dig deep into Drupal's internal code. It is enabled by default and won't ever show older, cached pages./p pWith application-level caching, Drupal essentially stores cached pages separately from the site content (which goes into the database). You can't really configure this, except for telling Drupal where to save cached pages explicitly. You might see improved performance if you use Memcached on cached pages, but the effect is not big enough to warrant the effort./p pDrupal stores many of its internal data and structures in efficient ways to improve frequent access when application-level caching. This isn’t information that a site visitor will see per se, but it is critical for constructing any page. Basically, the only enhancements that can be made at this level are improving where this cached information is stored, like using Memcached instead of the database./p pYou just need to install Drupal and let the software take care of caching at the application-level./p h2Component-level caching/h2 pThis works on user-facing components such as blocks, panels, and views. For example, you might have a website with constantly changing content but a single block remains the same. In fact, you may have the same block spread across dozens of pages. Caching it can result in big performance improvements./p pComponent-level caching is usually disabled by default, though you can turn it on with some simple configuration changes. For the best results, identify blocks, panels, and views that remain the same across your site, and then cache them aggressively. You will see strong speedups for authenticated users./p h2Page-level caching/h2 pThis is exactly what it sounds like: The entire page is cached, stored and delivered to a user. This is the most efficient type of caching. Instead of generating pages dynamically with Drupal bootstrap, your server can show static HTML pages to users instead. Site performance will improve almost immeasurably./p pPage-level caching gives you a lot of room to customize. You can use any number of caching servers, including Varnish, which we use at Acquia Cloud. You can also use CDNs like Akamai, Fastly, or CloudFlare to deliver cached pages from servers close to the user's location. With CDNs, you are literally bringing your site closer to your users./p pKeep in mind that forced, page-level caching works only for anonymous users by default. Fortunately, this forms the bulk of traffic to any website./p pIt bears repeating: Caching should be your top priority for boosting Drupal performance. By identifying and caching commonly repeated components and using a CDN at page-level, you’ll see site speed improvements that you can write home about./p pemNext time: How to Evaluate Drupal Modules for Performance Optimization. /em/p /div /div /div div class=field field-name-field-tags field-type-taxonomy-term-reference field-label-inline clearfix div class=field-labelTags:nbsp;/div div class=field-items div rel= class=field-item evena href=/resources/acquia-drupal-planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=acquia drupal planet/a/div /div /div span property=dc:title content=Caching to Improve Drupal Performance: The Three Levels You Should Know class=rdf-meta element-hidden/span

Acquia: Seamless Migration to Drupal 8: Make it Yours

Tue, 06/30/2015 - 17:26
figure class=field-item even rel= resource= class=field-item even div id=styles-3 class=styles styles-field-image styles-style-scale_width_280 styles-container-image styles-preset-scale_width_280 img typeof=foaf:Image src= alt= title= //div !-- render the title tag as caption -- /figure div class=field field-name-body field-type-text-with-summary field-label-hidden div class=field-items div property=content:encoded class=field-item evenpimg src=/sites/default/files/wildebeests.jpg alt=wildebeests migrating //p pHi there. I’m Adam from Acquia. And I want YOU to adopt Drupal 8!/p pI’ve been working on this for months. Last year, as an Acquia intern, I wrote the a href= target=_blankDrupal Module Upgrader/a to help people upgrade their code from Drupal 7 (D7) to Drupal 8 (D8). And now, again as an Acquia intern, I’m working to provide Drupal core with a robust migration path for your content and configuration from D6 and D7 to Drupal 8. I’m a full-service intern!/p pThe good news is that Drupal core already includes the migration path from D6 to D8. The bad news is that the (arguably more important) migration path from D7 to D8 is quite incomplete, and a href= target=_blankDrupal 8 inches closer with each passing day/a. That’s why I want -- nay, need -- your help./p pstrongWe need to get this upgrade path done./strong /p pIf you want core commits with your name on them (and why wouldn’t you?), this a great way to get some, regardless of your experience level. Noob, greybeard, or somewhere in between, there is a way for you to help. (Besides, the greybeards are busy fixing critical issues.)/p h2What’s this about?/h2 pHave you ever tried to make major changes to a Drupal site using update.php and a few update_N hooks? If you haven’t, consider yourself lucky; it’s a rapid descent into hell. Update hooks are hard to test, and any number of things can go wrong while running them. They’re not adaptable or flexible. There’s no configurability -- you just run update.php and hope for the best. And if you’ve got an enormous site with hundreds of thousands of nodes or users, you’ll be staring anxiously at that progress bar all night. So if the idea of upgrading an entire Drupal site in a single function terrifies you, congratulations: you’re sane./p pNo, when it comes to upgrading a full Drupal site, hook_update_N() is the wrong tool for the job. It’s only meant for making relatively minor modifications to the database. Greater complexity demands something a lot more powerful./p pThe Migrate API is that something. This a href= target=_blankwell-known contrib module/a has everything you need to perform complex migrations. It can migrate content from virtually anything (WordPress, XML, CSV, or even a Drupal site) into Drupal. It’s flexible. It’s emextensible/em. And it’s in Drupal 8 core. Okay, not quite -- the API layer has been ported into core, but the UI and extras provided by the Drupal 7 Migrate module are in a (currently sandboxed) a href= target=_blankcontrib module called Migrate Plus/a. /p pAlso in core is a new module called Migrate Drupal, which uses the Migrate API to provide upgrade paths from Drupal 6 and 7. This is the module that new Drupal 8 users will use to move their old content and configuration into Drupal 8./p pAt the time of this writing, Migrate Drupal contains a migration path for Drupal 6 to Drupal 8, and it’s robust and solid thanks to the hard work of many contributors. It was built before the Drupal 7 migration path because Drupal 6 security support will be dropped not long after Drupal 8 is released. It covers just about all bases -- it migrates your content into Drupal 8, along with your CCK fields (and their values). It also migrates your site’s configuration into Drupal 8, right down to configuration variables, field widget and formatter settings, and many other useful tidbits that together comprise a complete Drupal 6 site./p pHere’s a (rather old) demo video by @benjy, one of the main developers of the Drupal 6 migration path:/p iframe width=420 height=315 src= frameborder=0 allowfullscreen=/iframep Awesome, yes? I think so. Which brings me to what Migrate Drupal emdoesn’t/em yet have -- a complete upgrade path from Drupal 7 to Drupal 8. We’re absolutely going to need one. It’s critical if we’re going to get people onto Drupal 8!/p pThis is where you come in. The Drupal 7 migration path is one of the best places to contribute to Drupal core, even at this late stage of the game. The D7 upgrade path has been mapped out in a a href= target=_blankmeta-issue on, and stronga large chunk of it is appropriate for novice contributors!/strong/p pWorking on the Migrate API involves writing migrations, which are a href= target=_blankYAML/a files (if you’re not familiar with YAML, the smart money says that you will pick it up in, honestly, thirty seconds flat). You’ll also write a href= target=_blankautomated tests/a, and maybe a a href= target=_blankplugin/a or two -- a crucial skill when it comes to programming Drupal 8! If you’re a developer, contributing migrations is a gentle, very useful way to prepare for D8./p h2A very, very quick overview of how this works/h2 pMigrations are a lot simpler than they look. A migration is a piece of configuration, like a View or a site slogan. It lives in a YAML file./p pMigrations have three parts: the source plugin, the processing pipeline, and the destination plugin. The source plugin is responsible for reading rows from some source, like a Drupal 7 database or a CSV file. The processing pipeline defines how each field in each row will be massaged, tweaked, and transformed into a value that is appropriate for the destination. Then the destination plugin takes the processed row and saves it somewhere -- for example, as a node or a user./p pThere’s more to it, of course, but that’s the gist. All migrations follow this source-process-destination flow./p precode style=white-space: pre !important; id: d6_url_alias label: Drupal 6 URL aliases migration_tags: - Drupal 6 # The source plugin is an object which will read the Drupal 6 # database directly and return an iterator over the rows of the # {url_alias} table. source: plugin: d6_url_alias # Define how each field in the source row is mapped into the destination. # Each field can go through a “pipeline”, which is just a chain of plugins # that transform the original value into the destination value, one step at # a time. Source values can go through any number of transformations # before being added to the destination row. In this case, there are no # transformations -- it's just direct mapping. process: source: src alias: dst langcode: language # The destination row will be saved by the url_alias destination plugin, which # knows how to create URL aliases. There are many other destination plugins, # including ones to create content entities (nodes, users, terms, etc.) and # configuration (fields, display settings, etc.) destination: plugin: url_alias # Migrations can depend on specific modules, configuration entities, or even # other migrations. dependencies: module: - migrate_drupal /code/preh2I lt;3 this, how can I help?/h2 pThe first thing to look at is a href= target=_blankthe Drupal 7 meta-issue./a It divvies up the Drupal 7 upgrade path by module, and divides them further by priority. The low-priority ones are reasonably easy, so if you’re new, you should grab one of those and start hacking on it. (Hint: migrating variables to configuration is the easiest kind of migration to write, and there are plenty of examples.) The core Migrate API is a href= target=_blankwell-documented/a too./p pIf you need help, we’ve got a dedicated IRC channel (#drupal-migrate). I’m phenaproxima, and I’m one of several nice people who will be happy to help you with any questions you’ve got./p pIf you’re not a developer, you can still contribute. Do you have a Drupal 6 site? Migrate it to Drupal 8, and see what happens! Then tell us how it went, and include any unexpected weirdness so we can bust bugs. As the Drupal 7 upgrade path shapes up, you can do the same thing on your Drupal 7 site./p pIf you want to learn about meatier, more complicated issues, the core Migrate team meets every week in a Google Hangout-on-air, to talk about larger problems and overarching goals. But if you’d rather focus on simpler things, don’t worry about it. :)/p pAnd with that, my fellow Drupalist(a)s, I invite you to step up to the plate. Drupal 8 is an amazing release, and everyone deserves it. Let’s make its adoption widespread. Upgrading has always been one of the major barriers to adopting a new version of Drupal, but the door is open for us to fix that for good. I know you can help./p pBesides, core commits look really good with a href= target=_blankyour name/a tattooed on ‘em. Join us!/p /div /div /div div class=field field-name-field-tags field-type-taxonomy-term-reference field-label-inline clearfix div class=field-labelTags:nbsp;/div div class=field-items div rel= class=field-item evena href=/resources/acquia-drupal-planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=acquia drupal planet/a/div /div /div span property=dc:title content=Seamless Migration to Drupal 8: Make it Yours class=rdf-meta element-hidden/span

Drupal Watchdog: Testing 1.2.3...

Tue, 06/30/2015 - 16:15
div class=field field--article-edit-printtype field-type-list-text field-label-hidden field--rss Column /div div class=field field--article-body field-type-text-long field-label-hidden field--rss pimg src=/sites/default/files/images/web/DW5.01-Stencil.jpg alt= Alphabet Stencil width=50% align=right class=img-responsive img-thumbnail margin-left / The introduction of Behat 3, and the subsequent release of the Behat Drupal Extension 3, opened up several new features with regards to testing Drupal sites. The concept of test suites, combined with the fact that all contexts are now treated equally, means that a site can have different suites of tests that focus on specific areas of need./p h3Background/h3 p Behat is a PHP framework for implementing emBehavior Driven Development/em (BDD). The aim is to use ubiquitous language to describe value for everybody involved, from the stake-holders to the developers. A quick example:/p pre In order to encourage visitors to become more engaged in the forums Visitors who choose to post a topic or comment Will earn a 'Communicator' badge /prep This is a Behat emfeature/em, there need be no magic or structure to this. The goal is to simply and concisely describe a feature of the site that provides true value. In Behat, features are backed up with emscenarios/em. Scenarios are written in Gherkin and are mapped directly to emstep-definitions/em which execute against a site, and determine if, indeed, a given scenario is working./p pContinuing with the above example:/p pre Scenario: A user posts a comment to an existing topic and earns the communicator badge Given a user is viewing a forum topic Getting started with Behat When they post a comment They should immediately see the Communicator badge /prep Each of the span class=geshifiltercode class=php geshifilter-phpGiven/code/span, span class=geshifiltercode class=php geshifilter-phpWhen/code/span, and span class=geshifiltercode class=php geshifilter-phpThen/code/span steps are mapped to code using either regex, or newly in Behat 3, emTurnip/em syntax:/p /div

Amazee Labs: Debug Solr queries

Tue, 06/30/2015 - 13:00
spanDebug Solr queries/span spana href=/en/vasi-chindris title=View user profile. href=/en/vasi-chindris lang= about=/en/vasi-chindris typeof=schema:Person property=schema:name datatype= class=usernameVasi Chindris/a/span spanTue, 06/30/2015 - 13:00/span div class=clearfix field field-node--field-lead field-name-field-lead field-type-text-long field-label-hidden div class=field-items div class=field-itempSolr is great! When you have a site even with not so much content and you want to have a full text search, then using Solr as a search engine will improve a lot the speed of the search itself and the accuracy of the results. But, as most of the times happen, all the good things also come with a drawback too. In this case, we talk about a new system which our web application will communicate to. This means that, even if the system is pretty good by default, you have to be able in some cases to understand more deeply how the system works.This means that, besides being able to configure the system, you have to know how you can debug it. We'll see in the following how we can debug the Solr queries which our applications use for searching, but first let’s think of a concrete example when we need to debug a query./p/div /div /div div class=clearfix field field-node--body field-name-body field-type-text-with-summary field-label-hidden div class=field-items div class=field-itempstrongAn example use case/strong/p pLet’s suppose we have 2 items which both contain in the title a specific word (let’s say ‘building’). And we have a list where we show search results ordered by their score first, and when they have equal scores by the creation date, desceding. At a first sight, you would say that, because both of them have the word in the title, they have the same score, so you should see the newest item first. Well, it could be that this is not true, and even if they have the word in the title, the scores are not the same./p pstrongPreliminaries/strong/p pLet’s suppose we have a system which uses Solr as a search server. In order to be able to debug a query, we first have to be able to run it directly on Solr. The easiest is when Solr is accessible via http from your browser. If not, the Solr must be reached from the same server where your application sits, so you call it from there. I will not insist on this thing, if you managed to get the Solr running for you application you should be able to call it./p pstrongGetting your results/strong/p pThe next thing you do is to try to make a query with the exact same parameters as your application is doing. To have a concrete example, we will consider here that we have a Drupal site which uses the Search API module with the Apache Solr as the search server. One of the possibilities to get the exact query which is made is to check the SearchApiSolrConnection::makeHttpRequest() method which makes a call to drupal_http_request() using an URL. You could also use the Solr logs to check the query if it is easier. Let's say we search for the word “building”. An example query should look like this:/p blockquote phttp://localhost:8983/solr/select?fl=item_id%2Cscoreamp;qf=tm_body%24value%5E5.0amp;qf=tm_title%5E13.0amp;fq=index_id%3A%22articles%22amp;fq=hash%3Ao47rodamp;start=0amp;rows=10amp;sort=score%20desc%2C%20ds_created%20descamp;wt=jsonamp;;q=%22building%22/p /blockquote pIf you take that one and run it in the browser, you should see a JSON output with the results, something like:/p pimg alt=solr json output data-entity-type=file data-entity-uuid=79ff3806-557c-4da5-a913-193f87e9532b src= //p pTo make it look nicer, you can just remove the “wt=json” (and optionally “”) from your URL, so it becomes something like:/p blockquote phttp://localhost:8983/solr/select?fl=item_id%2Cscoreamp;qf=tm_body%24value^5.0amp;qf=tm_title^13.0amp;fq=index_id%3Aarticlesamp;fq=hash%3Ao47rodamp;start=0amp;rows=10amp;sort=score desc%2C ds_created descamp;q=building/p /blockquote pwhich should result in a much nicer, xml output:/p pimg alt=solr xml output data-entity-type=file data-entity-uuid=3cee30d4-0448-4e0a-8b00-bdb47120de14 src= //p pstrongList some additional fields/strong/p pSo now we have the results from Solr, but all they are containing are the internal item id and the score. Let's add some fields which will help us to see exactly what texts do the items contain. The fields you are probably more interested in are the ones which are in the “qf” variable, in your URL. In this case we have:/p blockquote pqf=tm_body%24value^5.0amp;qf=tm_title^13.0/p /blockquote pwhich means we are probably interested in the “tm_body%24value” and the “ tm_title” fields. To make them appear in the results, we add them to the “fl” variable, so the URL becomes something like:/p blockquote phttp://localhost:8983/solr/select?fl=item_id%2Cscore%2Ctm_body%24value%2Ctm_titleamp;qf=tm_body%24value^5.0amp;qf=tm_title^13.0amp;fq=index_id%3A%22articles%22amp;fq=hash%3Ao47rodamp;start=0amp;rows=10amp;sort=score%20desc%2C%20ds_created%20descamp;q=%22building%22/p /blockquote pAnd the result should look something like:/p pimg alt=solr full xml output data-entity-type=file data-entity-uuid=40721acf-1c37-417a-b54a-74dfa0b0ef71 src= //p pstrongDebug the query/strong/p pNow everything is ready for the final step in getting the debug information: adding the debug flag. It is very easy to do that, all you have to do is to add the “debugQuery=true” to your URL, which means it will look like this:/p blockquote phttp://localhost:8983/solr/select?fl=item_id%2Cscore%2Ctm_body%24value%2Ctm_titleamp;qf=tm_body%24value^5.0amp;qf=tm_title^13.0amp;fq=index_id%3A%22articles%22amp;fq=hash%3Ao47rodamp;start=0amp;rows=10amp;sort=score%20desc%2C%20ds_created%20descamp;q=%22building%22amp;debugQuery=true/p /blockquote pYou should see now more debug information, like how the query is parsed, how much time does it take to run, and probably the most important one, how the score of each result is computed. If your browser does not display the formula in an easy-readable way, you can copy and paste it into a text editor, it should look something like:/p pimg alt=solr debug output data-entity-type=file data-entity-uuid=e75ffb93-a38f-4663-8800-d26bff3361c6 src= //p pAs you can see, computing the score of an item is done using a pretty complex formula, with many variables as inputs. A few more details about these variables you can find here: a href= target=_blankSolr Search Relevancy/a/p pstrongFurther reading and useful links/strong/p ulliTo visualize the explaination of your Solr queries, you could use this: a href= target=_blank liIf you want to dig deeper into how the score is computed: a href= target=_blank /ul/div /div /div

ERPAL: How we’re building our SaaS business with Drupal

Tue, 06/30/2015 - 11:00
div class=field field-name-field-blog-intro-image field-type-image field-label-hiddendiv class=field-itemsdiv class=field-item evenimg src= width=700 height=180 alt= //div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpHave you ever thought about building your own Software-as-a-Service (SaaS) business based on Drupal? I don't mean selling Drupal as a service but selling your Drupal-based software under a subscription model and using Drupal as the basis for your accounting, administration, deployment and the tool that serves and controls all the business processes of your SaaS business. Yes, you have? That's great! We’ve done the same thing over the last 12 months, and in this blog post I want to share my experiences with you (and we’d be delighted if you shared your experiences in the comments). I’ll show you the components we used to build Drop Guard – a Drupal-auto-updater-as-a-service (DAUaaS ;-)) that includes content delivery and administration, subscription handling, CRM and accounting, all based on ERPAL Platform./p pI’m not talking about a full-featured, mature SaaS business yet, but about a start-up in which expense control matters a lot and where agility is one of the most important parameters for driving growth. Of course, there are many services out there for CRM, payment, content, mailings, accounting, etc. But have you added up all the expenses for those individual services, as well as the time and money you need to integrate them properly? And are you sure you’ve made a solid choice for the future? I want to show you how Drupal, as a highly flexible open source application framework, brings (almost) all those features, saves you money in the early stages of your SaaS business and keeps you flexible and agile in the future. Below you’ll find a list of the tools we used to build the components of the Drop Guard service./p h3img alt= src=/blog/sites/default/files/build_saas_process.png style=height:95px; line-height:20.7999992370605px; width:701px width=701 height=95 //h3 h3Components of a SaaS business application/h3 pstrongimg alt= src=/blog/sites/default/files/content.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Content/strong: This is the page where you present all benefits of your service to potential clients. This page is mostly content-driven and provides a list of plans your customers can subscribe to. There’s nothing special about this as Drupal provides you with all the features right out of the box. The strength of Drupal is that it integrates with all the other features listed below, in one system. With the flexible entity structure of Drupal and the Rules module, you can automate your content and mailings to keep users on board during the trail period and convince them of your service to purchase a full subscription./p pstrongimg alt= src=/blog/sites/default/files/freetrial.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Trial registration/strong: Once your user has signed up using just her email address, she’ll want to start and test using your service for free during the trial period. Drupal provides this registration feature right out of the box. To deploy your application (if you run single instances for every user), you could trigger the deployment with a href= With the commerce_license module you can create an x-day trial license entity and replace it with the commercial entity once the user has bought and paid for a license./p pstrongimg alt= src=/blog/sites/default/files/buy.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Checkout/strong: After the trial period is over, your user needs to either buy the service or quit using it. The process can be just like the checkout process in an online store. This step includes a subscription to a recurring payment provider and the completion of a contact form (to create a complete CRM entry for this subscriber). We used Drupal commerce to build a custom checkout process and commerce products to model the subscription plans. To notify the user about the expiration of her trial period, you can send her one or more emails and encourage her to get in touch. Again, Rules and the flexible entity structure of Drupal work perfectly for this purpose./p pstrongimg alt= src=/blog/sites/default/files/crm.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Accounting/strong: Your customer data need to be managed in a CRM as they're one of the most valuable information in your SaaS business. If you’ve just started your SaaS business, you don't need a full-featured and expensive CRM system, but one that scales with your business as it grows and can be extended later with additional features, if needed. The first and only required feature is a list of customers (your subscribers) and a list of their orders and related invoices (paid or unpaid). As we use a href= Core/a to build the CRM, we can extend the contact entities with fields, build filterable lists with views, reference subscriptions (commerce orders) to contacts and create invoices (a bundle of the commerce order entity pre-configured as the a href= invoice/a module)./p pstrongimg alt= src=/blog/sites/default/files/recurring-payment.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Recurring payment/strong: If you run your SaaS business on a subscription-based model where your clients pay for the service periodically, you have two options to process recurring payments. Handling payments by yourself is not worth trying as it’s too risky, insecure and expensive. So, either you use a href=https://stripe.comStripe/a to handle recurring payments for you or you can use any payment provider to process one time payments and implement the recurring feature in Drupal. There are a href= other SaaS payment services worth looking at/a. We've chosen the second option using a href=http://paymill.comPaymill/a to process payments in combination with a href= and a href= to implement the recurring feature. For every client with an active subscription, an invoice is created every month and the amount is charged via the payment provider. Then the invoice is set to paid and the service continues. The invoice can be downloaded in the portal and is accessible for both the SaaS operator and the client as a dataset and/or a PDF file./p pstrongimg alt= src=/blog/sites/default/files/deployment.png style=float:left; height:50px; margin-right:5px; width:51px width=51 height=50 /Deployment/strong: Without going into deep details of application deployment, Docker is a powerful tool for deploying single-instance apps for your clients. You may also want to have a look at different API-based Drupal hosting platforms, such as a href= or a href=http://pantheon.ioPantheon/a or a href= Cloud/a if you want to sell Drupal-based applications via a SaaS model. They will make your deployment very comfortable and easy to integrate. You can use Drupal multi-site instances or the Drupal access system to separate user-related content (the last one can be very tricky and exert performance impacts on big data!). If your app produces a huge amount of data (entities or nodes) I recommend single instances with Docker or a Drupal hosting platform. As Drop Guard automates deployment and therefore doesn’t produce that much data, we manage all our subscribers in one Drupal instance but keep the decoupled update server horizontally scalable./p h3img alt= src=/blog/sites/default/files/build_saas_with_erpal.png style=height:180px; line-height:20.7999992370605px; width:700px width=700 height=180 //h3 h3Start building your own SaaS business/h3 pIf you’re considering building your own SaaS business, there’s no need to start from scratch. a href= Platform/a is freely available, easy-to-customize and uses Drupal contrib modules such as Commerce, CRM Core and Rules to connect all the components necessary to operate a SaaS business process. With ERPAL Platform you have a tool for developing your SaaS business in an agile way, and you can adapt it to whatever comes in the near future. ERPAL Platform includes all the components for CRM and accounting and integrates nicely with Stripe (and many others, thanks to Drupal Commerce) as well as your (recurring) payment provider. We can modify the default behavior with entities, fields, rules and views to extend the SaaS business platform. We used several contrib modules to extend ERPAL Platform to manage licensed products (a href= license/a and a href= license billing/a). If you want more information about the core concepts of ERPAL Platform, there’s a previous blog post about how to a href= flexible business applications with ERPAL Platform/a./p pThis is how we built a href=http://dropguard.netDrop Guard, a service for automating Drupal updates/a with integration into development and deployment workflows. As we’ve just started our SaaS business, we’ll keep you posted with updates along our way to becoming a full-fledged, Drupal-based SaaS business. For instance, we plan to add metrics and marketing automation features to drive traffic. We’ll share our experiences with you here and we’d be happy if you’d share yours in the comments!/p /div/div/div

Cocomore: MySQL - Query optimization

Tue, 06/30/2015 - 10:02
pQueries are the centerpiece of MySQL and they have high optimization potential (in conjunction with indexes). This is specially true for big databases (whatever big means). Modern a class=glossary-term href= title=PHP is the scripting language behind Drupal and is commonly used for web application development. Drupal core, as well as contributed modules and themes, are mostly PHP code. “PHP” is now said to a recursive acronym for “PHP: Hypertext Preprocessor”, but in the early days of PHP, it stood for “Personal Home Page”.PHP/dfn/a frameworks tend to execute dozens of queries. Thus, as a first step, it is required to know what the slow queries are. A built-in solution for that is thea href= MySQL slow query log/a. This can either be activated in my.cnf or dynamically with the --slow_query_log option. In both cases, long_query_time should be reduced to an appropriate value. /ppa href= target=_blankread more/a/p Building a Slack Chatbot Powered by Drupal!

Tue, 06/30/2015 - 06:45
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evendiv id=contents style type=text/css !--/*--![CDATA[/* !--*/ ol{margin:0;padding:0}.c0{widows:2;orphans:2;text-align:justify;direction:ltr}.c3{color:#1155cc;text-decoration:underline;font-weight:bold}.c5{max-width:468pt;background-color:#ffffff;padding:72pt 72pt 72pt 72pt}.c1{color:inherit;text-decoration:inherit}.c2{height:11pt}.c6{font-style:italic}.c4{font-weight:bold}.title{widows:2;padding-top:0pt;line-height:1.15;orphans:2;text-align:left;color:#000000;font-size:21pt;font-family:Trebuchet MS;padding-bottom:0pt;page-break-after:avoid}.subtitle{widows:2;padding-top:0pt;line-height:1.15;orphans:2;text-align:left;color:#666666;font-style:italic;font-size:13pt;font-family:Trebuchet MS;padding-bottom:10pt;page-break-after:avoid}li{color:#000000;font-size:11pt;font-family:Arial}p{color:#000000;font-size:11pt;margin:0;font-family:Arial}h1{widows:2;padding-top:10pt;line-height:1.15;orphans:2;text-align:left;color:#000000;font-size:16pt;font-family:Trebuchet MS;padding-bottom:0pt;page-break-after:avoid}h2{widows:2;padding-top:10pt;line-height:1.15;orphans:2;text-align:left;color:#000000;font-size:13pt;font-family:Trebuchet MS;font-weight:bold;padding-bottom:0pt;page-break-after:avoid}h3{widows:2;padding-top:8pt;line-height:1.15;orphans:2;text-align:left;color:#666666;font-size:12pt;font-family:Trebuchet MS;font-weight:bold;padding-bottom:0pt;page-break-after:avoid}h4{widows:2;padding-top:8pt;line-height:1.15;orphans:2;text-align:left;color:#666666;font-size:11pt;text-decoration:underline;font-family:Trebuchet MS;padding-bottom:0pt;page-break-after:avoid}h5{widows:2;padding-top:8pt;line-height:1.15;orphans:2;text-align:left;color:#666666;font-size:11pt;font-family:Trebuchet MS;padding-bottom:0pt;page-break-after:avoid}h6{widows:2;padding-top:8pt;line-height:1.15;orphans:2;text-align:left;color:#666666;font-style:italic;font-size:11pt;font-family:Trebuchet MS;padding-bottom:0pt;page-break-after:avoid} /*--!]]*/ /stylep class=c0spanEver Since we moved to /spanspan class=c3a class=c1 href=;sa=Damp;sntz=1amp;usg=AFQjCNGoZiRT6XmESIX-zZyJlKijE02fnQSlack/a/spanspan for our team’s instant messaging needs, what excited me the most is the nice set of APIs that Slack offers to seamlessly integrate your apps into Slack chat./span/p p class=c0 c2span/span/p p class=c0spanWhat we needed immediately was a basic bot that handled Karma functionality allowing people to say ‘Thanks’ to others using the usual ‘++’ annotation. /span/p p class=c0 c2span/span/p p class=c0spanWe were looking at options for various technologies. Node.js is the usual one that you hear a lot when people talk of chatbots these days. /span/p p class=c0 c2span/span/p p class=c0spanDrupal was an option. We were skeptical at first. Having Drupal intercept and analyze almost 3- 4 messages every second at its peak hours sounded like trouble. And there would be no levels of caching involved here as each message is unique from a different user and should be processed uniquely./span/p p class=c0 c2span/span/p p class=c0spanBut one clear advantage I could see and wanted to have, was to interface the rest of the team from the various complexities of Slack APIs and configuration, interfacing all of that through Drupal APIs. So if anyone needed to extend this bot further, they should not really worry about Slack API and they should be building very simple Drupal Modules. /span/p p class=c0 c2span/span/p p class=c0spanOver a weekend, a couple of us teamed to build a chatbot for our Acquia India slack chatrooms, using what we knew best - /spanspan class=c4Drupal/spanspan. And we launched it on March 1st 2015. Our bot was christened /spanspan class=c4 c6Regina Cassandra/spanspan. And the bot has been up and running ever since with no downtime or any issues so far. /span/p p class=c0 c2span/span/p p class=c0spanThe Karma Handling../span/p p class=c0span style=overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 553.00px; height: 117.00px;img alt= src= style=width: 553.00px; height: 117.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); title= //span/p p class=c0 c2span/span/p p class=c0spanRarely used, but it can text people../span/p p class=c0span style=overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 364.00px; height: 110.00px;img alt= src= style=width: 364.00px; height: 110.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); title= //span/p p class=c0 c2span/span/p p class=c0span style=overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 429.00px; height: 212.00px;img alt= src= style=width: 429.00px; height: 212.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); title= //span/p p class=c0 c2span/span/p p class=c0spanAnd when the Cricket World cup was happening, Regina was busy serving us scores whenever requested../span/p p class=c0span style=overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 352.00px; height: 162.00px;img alt= src= style=width: 352.00px; height: 162.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); title= //span/p p class=c0 c2span/span/p p class=c0spanRegina also used to give everyone a daily fortune cookie. She doesn’t seem to do that anymore for the API that the fortune cookie module was using seems to be dead now./span/p p class=c0 c2span/span/p p class=c0spanThe bot uses /spanspan class=c3a class=c1 href=;sa=Damp;sntz=1amp;usg=AFQjCNHVr86diY6vkqp701yR_XrAIzMrkgSlack’s Outgoing Webhooks/a/spanspan to intercept each message posted to the chatrooms, and allows all modules on the chatbot site to intercept the message and respond to it. /span/p p class=c0span style=overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 624.00px; height: 316.00px;img alt= src= style=width: 624.00px; height: 316.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); title= //span/p p class=c0 c2span/span/p p class=c0spanThe bot (a Headless Drupal Site) has been hosted on a free-tier Acquia Cloud Subscription. With the decent performance it has had so far and less-than-a-second response times we currently see with the slackbot, we never saw a need to upgrade so far. /span/p /div /div/div/div

Commerce Guys: Comparing Drupal Commerce Magento

Tue, 06/30/2015 - 03:53
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpMuch ink has been spilled about which open-source ecommerce platform is the “best.” Most comparisons perpetuate what is typically an easy (but usually incorrect) way of understanding these two platforms and whether they are a fit for your business. They are often compared like word processors based on line item comparisons of features instead of powerful business growth engines and visible brand extensions that they are. To limit them to nothing more than published feature sets or architectural comparisons is foolish, unhelpful, and often leads companies down the wrong path. A better approach is to fully understand current and future business requirements and make a decision based on which solution can serve those needs the best./p pAt a high level, the most important thing to ask is “do you know what you want and how you want it done?” If you don’t know what you want, then you will likely consider a tool with lots of features out of the box. The tradeoff is that those features come with assumptions that are set in stone. While lots of prepackaged features may feel good now, you risk not being able to adapt as quickly as your competitors or the possibility that modifying those features will lead to incompatibilities down the road. The alternative is a framework where you get a larger feature set and with fewer assumptions. The tradeoff here is that you have more work to do to get off the ground—planning and implementing the exact features and experience you want—but with endless flexibility to mold a solution that exactly meets current and future business requirements. Trying to frame these solutions by purely quantitative just won’t do./p pLet’s take a step back from the deeply rooted (and borderline religious) discussion of frameworks and function sets, and examine at a higher level both Drupal Commerce and Magento. For business owners who are trying to figure out what’s best for them and anyone who has any experience with either technology, let’s talk about what really makes Drupal Commerce different from Magento.  Let’s get away from discussions about classes, architecture, benchmarks, features, etc. and instead, talk about each solution and objectively what problems they solve and which they do not./p pTo start off, I’d like to restate a quote (attribute to Adobe SE leads) from a href= House’s “Competing with Giants” presentation/a from DrupalCon Denver:/p blockquotepIf you are looking at both (Adobe) CQ5 and Drupal, then one of us is in the wrong place./p/blockquote pThis quote struck me. It sank deep into my soul. In a way, once I let the weight of these words really take hold, it completely changed my way of thinking. To help, consider this slight rewording:/p blockquotepIf you are looking at both Magento and Drupal Commerce, then one of us is in the wrong place./p/blockquote pThe obvious implication of this statement is that both Magento and Drupal Commerce have unique roles in the online commerce ecosystem. They are each geared towards certain types of projects and use cases. Instead of pitting each platform against each other to have a winner based on some arbitrary set of features or architecture, a better approach would be to first establish a clear understanding of customer needs. When the needs of a client are properly applied to the strengths of each platform, one will clearly meet those needs in a way that the other does not. Thus removing the need for a feature comparison./p h2Framing the solutions/h2 pWhat I’d like to endeavor here is (as much as possible) an unbiased and systematic approach to discussing Drupal + Drupal Commerce and Magento as unique solutions to the question of “which commerce platform should I choose?” Keeping the internals aside, here are the particular use-cases that make a lot of sense for a given project. This isn’t a comprehensive list, but if you’re trying to figure out which platform you should be looking at, then take a look. If you find one column aligning with your particular needs—chances are that’s the one that will be a better fit for your business./p tabletbodytrth/th thDrupal Commerce/th thMagento/th /trtrthContent strategy/th tdvarious types of content with rich relationships, taxonomies, and categories/td tdcatalog and product content with basic site content or blog/td /trtrthCatalog complexity/th tdunrestrained catalog creation and product presentation options/td tdconventional catalog format and product presentation/td /trtrthProduct offering/th tdnon-traditional and mixed-product offerings/td tdtraditional physical and/or digital product offerings/td /trtrthPlatform functionality/th tdopen, flexible feature set and custom application foundation/td tdcommerce-focused feature set/td /trtrthAdmin interface/th tdbasic yet, customizable admin interface/td tdrobust, rigid admin interface/td /trtrthUser experience/th tdstrong, defined vision for bespoke user experience/td tdbest practice, industry standard user experience/td /trtrthBusiness strategy/th tdcommerce is a part of larger offering or experience/td tdcommerce is the strategy/td /trtrthDevelopment skill level/th tdbasic PHP knowledge required/td tdadvanced PHP knowledge required/td /tr/tbody/tablepNow that we’ve drawn some lines, let’s discuss./p h3Content Strategy/h3 pDrupal Commerce (by way of Drupal) has an extremely powerful content system which allows for boundless creation of content types all with their own custom fields and attributes, editing experience, and a set of rich media tools. Content can be related to each other and those relationships can be harnessed to generate lists of related products and blog posts on product pages, or customized landing pages with unique product listings and content. It’s a breeze to set this up and you can do all of this without touching a line of code. If providing content and information to your customers is vital to your business and how you differentiate yourself from others, Drupal is what you want./p pMagento, on the other hand, has a very basic content system. You can add pages, add some content to category pages, and adding attributes to products is painless. There are even some great built-in blog modules. But once you step outside of this, you’re in custom territory. You’ll either need two systems (like a blog or a CMS) or you’ll end up building it all custom into Magento increasing cost and ongoing support. Again, it’s not that Magento can’t do content at all, just that Magento’s content features are pretty basic. Enterprise does expand on this, but you still have a very limited tool set and code changes (requiring a developer) are usually required to expand on it./p h3Catalog Complexity/h3 pMagento offers what any reasonable person might consider to be a wholly conventional approach to catalog management. You have a catalog root, and from there you can create tiers of categories. Products fall into one or more of those categories. In fact, it’s pretty common for a product to exist within multiple groups based on how visitors will look for and try to find those particular products. But Magento is also pretty strict that products really can’t be displayed outside of this hierarchy. Aside from some of the product blocks for up-sells and cross-sells, your ability to display products is completely centered around this. Also, product listings are limited to lists and grids views without additional extensions or modifications./p pDrupal Commerce releases you from this constraint. Products can be organized, tagged, and dynamically added to or removed from product lists automatically. A traditional catalog-like user experience can be built. But the catalog automatically follows how you already organize your product and can use virtually any attribute that exists on a product. And when you want to display your products, you can choose from a number of pluggable styles from tables, grids, lists, and each product can have it’s own customized look and feel in a product list, too. This can make a huge difference as you try to differentiate, promote, and get your visitors engaged in what you have to offer—no matter how many products you have or how complicated they are./p h3Product Offering/h3 pIf you’re selling physical and/or digital products, both platforms are fairly good at that. In fact, Magento again has a lot of features that don’t require individual setup. Want simple and no-fuss sales of traditional products? Magento can tackle that easily. With Drupal Commerce, you start with a basic product structure and are then free to build exactly what you want no matter how complex it might be./p pWhen it comes to non-traditional offerings—event registrations, donations, recurring billing, licensing, and subscription service models—Drupal Commerce provides tools to configure or build what you need without having to reinvent the wheel. And best of all, you can mix any and all of these product types pretty easily. So if you want to do registrations, t-shirt sales, and a recurring monthly donation, you can easily support that in a single site and in a single transaction./p h3Platform Functionality/h3 pMagento has a well implemented and cohesive commerce feature set. And frankly, if you’re judging a product solely on the published feature set, Magento looks good. That’s not because Drupal Commerce doesn’t have a great feature set—in fact it’s much more expansive than Magento’s—but Drupal Commerce’s flexibility is in the expansive and ever-growing list of modules. It’s hard to quantify. If you’re only looking for a shopping cart and you’re happy with what Magento provides, it may very well be the right choice./p pHowever, if you are wanting to integrate features that go beyond commerce—you want to define and build your own custom application or create a totally unique customer experience—then Drupal Commerce will be a much better platform enabling you to adapt quickly to business and market changes.  Entire new areas of functionality can be configured and enabled just  like a new feature.  Whether you’re adding customer portals, forums, web services, an LMS, or even back office functionality, Drupal can give you the agility and freedom to change and grow as you need to./p h3Admin Interface/h3 pWhile Drupal’s administrative interface can be endlessly customized and tailored to your specific needs (in many cases without even touching the code), it generally tends to be pretty basic. It is trivial to create new screens, targeted to specific users, that gives specific information and actions that can be performed on that information. In short, you can get what you want, but you’ll have to spend the time configuring it./p pMagento’s administrative interface is comprehensive and gives users a structured, well-defined way to manage the entire store. If you’re willing to use what’s out of the box, then it will serve you well. The pain will come if you ever decide to deviate from the out of the box experience. Customizations require code modification and even “small changes” could require considerable effort to complete./p h3User Experience/h3 pWhen it comes to user experience, Magento delivers a best-practices, industry standard implementation of a traditional shopping cart: you get a catalog, a cart with a one-page checkout, account pages, etc. It’s designed to be a finished product, so you can pretty much trust it will all be there and that it will work well./p pDrupal Commerce provides all of that same functionality, but expects you to expend some effort to make it look good. At a minimum, you’ll need to theme it. That’s not much to ask since you’re likely already doing that for the rest of your site. Drupal’s theme system is extremely powerful and adding unique or advanced features can be really easy. In some cases, little to no theme work is required. In addition, the user experience for path to purchase can be more easily integrated with the content experience, giving the merchant far more content marketing and merchandizing avenues./p h3Business Strategy/h3 pDrupal is a powerful platform. If you don’t know what I’m talking about, it is something that can’t be explained in a single paragraph. Drupal can be a community form, a wiki, an LMS, a translatable content management platform, a web services platform, and an online store. In fact, it could be all of these things at one time. If your vision calls for a platform that can do more than one thing, Drupal can rise to the challenge and integrate several business platforms under a single (software and hardware) roof./p pMagento, no surprise here, is a shopping cart. That’s what it does. It does it well, but if you are wanting to integrate Magento with another part of your business (e.g. magazine subscriptions, forum membership, etc.) you’ll have to deal with two independent systems talking with each other. You’ll be synchronizing your data between multiple systems and having to keep everything up to date with custom or 3rd party solutions./p h3Development Skills/h3 pIf you’re wondering how easy it’ll be to integrate your team with either Drupal Commerce or Magento, here’s what you need to know./p pMagento is a very powerful and complex system. It’s makes heavy use of objects, inheritance, and programming concepts that are confusing to basic and even some moderately experienced PHP developers. Getting acclimated to Magento as a back-end or front-end developer could take weeks or months, depending on the experience level. Also, architecturally, Magento does have a href= profound gotchas/a when it comes to adding and developing many extensions on a site. Documentation is so-so but there is a very active community of bloggers, training is available, and Magento support is pretty widely available./p pDrupal Commerce is much simpler and even people with minimal to no PHP experience can customize and pick it up within a few days. While parts of Drupal use objects (such as Views and the entity system) much of it is procedural. Drupal is designed to be much more accessible to individuals without coding experience. This flexibility is made available to non-coders through the various modules (such as Views, Rules, features, VBO, etc.) that offer powerful UIs to manage it. However, when code is necessary, bespoke modules can often be very simple. Documentation is generally very good for things like Drupal and Drupal Commerce, while contributed modules can vary from having non-existent to excellent documentation. Again, a very active and friendly community exists to support Drupal developers and users, and a wide range of training and support is available./p h2Conclusion/h2 pWhen deciding on an open source ecommerce solution, it is important to first look at the fundamentals of your business and identify your priorities. By doing this you will avoid the needless exercise of features comparisons and checklists and quickly conclude that one of these solutions is in the wrong place.  If content is important to how you engage with customers and sell your product and if you want to control and choose how the solution supports your business needs, Drupal + Drupal Commerce is generally the right choice./p/div/div/div