Subscribe to feed Planet Drupal - aggregated feeds in category Planet Drupal
Bijgewerkt: 4 uur 54 min geleden

Drupal Association News: Membership Drive 2015 recap

wo, 2016/02/10 - 8:44pm

From October 13 to December 30, 2015, we ran our biggest membership drive campaign ever. We did a lot of experimenting and I want to share some results and learnings with you.

But first, I'll tell you about our program. Drupal Association membership is for anyone who uses Drupal, and anyone who wants to support our community and the project through a donation of membership dues. Membership is one way to contribute to Drupal, but it is by no means the only way.

The biggest accomplishment in this campaign: 10% growth

During the campaign period, we saw 10% overall growth in our membership (3,266 to 3,590 members). For the last two years over this same period of time, we had seen 1% growth in membership. Last year’s growth is a huge win.

Goal vs actual

Our campaign goals were to raise $100,000 and to have 1,000 new members sign up.

The results looked more like this: $50,896 and 480 new members.

We also had 148 lapsed members return and our overall membership grew. Despite not hitting our goals, we are happy to have new and renewing members and some new knowledge about campaign content.

Testing content

When the campaign launched on October 13, we put our first banner ever on to test whether an increased presence on the site would make a difference in membership sales. The answer is a big Yes. There were spikes in membership sales around the times we launched and changed the content of the banners. The biggest day of sales took place on the day after the launch, Oct. 14, when 74 members paid dues.

On December 14, we refreshed the banner to include a photo and quote from a member who gave us a testimonial. We rotated the banners and a separate block on the homepage until the end of the campaign to highlight a few members.

This graph shows the results during our December banner rotation period. There was a trough around the Christmas holiday, so testing this at a non-holiday time of year will be beneficial in a future campaign.

What we learned

A greater presence helps sell memberships, and being mindful about what content to show our active members is important for inspiring people to share the campaign. If members see a banner, they should easily be able to share it or hide it.

We need to keep telling your stories. I saw some of the members who gave testimonials were given kudos in the community. It feels good to see the faces of the community and to see just why you care. We have continued sharing stories, starting with DrupalCon Asia.

On days we launched banners or refreshed content, we saw the biggest sales spikes and flurries of social activity. The time of year when many people step away from their computers could impact campaign performance, so testing at another time of year should be done.

Thanks to everyone who participated in this campaign. From the 27 members who gave testimonials, to everyone who joined or renewed membership or encouraged the community to be a part of the drive, we appreciate your help.

See the full report at

Personal blog tags: Membership

OSTraining: Image Styles and Sizes in Drupal 8

wo, 2016/02/10 - 7:50pm

One thing that all site builders need to think about is image size.

The size of your images can have an enormous impact on your site's speed and it's performance on mobile devices. Fortunately, the Drupal 8 core provides tools for controlling and optimizing the size of your images.

In these two videos, Robert shows you how to use Drupal 8 image styles and image settings.


Affinity Bridge: Ten Pointers for New Drupal 8 Developers

wo, 2016/02/10 - 7:46pm
Ten Pointers for New Drupal 8 Developers 02/10/2016 - 10:46 drush drupal drupal8 twig planet drupal Floyd Mann

We've been experimenting with Drupal 8 for a while now, but this site is the first project we've put into production built on it.

For folks who've worked with Drupal 6 or 7 previously and are just getting started using 8, here are a few tidbits worth being aware of when getting started.

1. Sooo much contrib is bundled in core now.

Those who’ve been in the Drupal community for quite a while remember the "Small Core" initiative. The idea was to strip Drupal core down to a minimalist framework, then use distributions to provide bundles of modules and configuration that would make Drupal a useful application in a particular scenario. Drupal Core itself would not be a useable product.

Small Core lost. Drupal 8 core contains major functionality that previously was provided by contrib modules, including Views, Views Datasource, Services, Entity API, Image Cache, Responsive Images, Breakpoints, Migrate, and WYSIWYG. Drupal 8 is a much more complete product out of the box then any previous version of Drupal.

A few features were removed from Drupal 8, most noticeably the blog module. It is easy to reproduce the blog functionality with the blog contrib module or even just by using the core components to add a custom content type and views to display the content. The latter approach is what we decided to do here.

When Drupal 7 was released many developers got burned by how many contrib modules weren't ready yet. The inclusion of so many essential modules in core has significant mitigated that issue, but there are still a number of "essential" contrib modules that aren't stable yet, notably token, pathauto, rules, and webform. There are prerelease versions of most of these modules in varying degrees of stability, and certainly trying them out, and contributing feedback, patches, and bug reports is the best way to help them get to a stable release. But sitebuilders under tight deadlines should check their requirements carefully and verify that any contrib modules they need are stable enough to use before promising complex functionality in Drupal 8 right now.

2. The authoring environment is massively improved.

The lack of a consistent author environment and authoring tools has, for years, been one of Drupal's biggest weaknesses when compared to other CMSes like WordPress. Developers love Drupal, but authors usually prefer WordPress.

A major effort was put into Drupal 7 to improve the authoring experience (UX), which Drupal 8 builds on. The seven administration theme is responsive now. Dropbuttons have been introduced for more economical use of screen space and to prioritize primary actions.  The CKEditor WYSIWYG editor is tightly integrated with core, providing a huge gain in consistency between one Drupal 8 environment and another.

Quickedit in-page editing is a whiz-bang feature of Drupal 8.  

Using QuickEdit while writing about QuickEdit

Did I mention the improvements to preview? Node previews that actually preview as they will render reduce the guesswork previously required when authoring any content containing layout code or different typefaces from the admin interface.      

3. Drupal 8 is a Symfony application

Drupalcon Denver is where I first heard about the plan to build Drupal 8 with Symfony components. I’m not sure whether my recollection is flawed or if I just didn’t understand what I was hearing, but the move to Symfony didn’t sound like too big a deal: just few minor changes to the plumbing, the inclusion of a Kernel and  HTTPRequest and HTTPResponse classes that’d improve testablity. I recall a neighbour at one of the talks telling me it sounded like ASP to him.  

The move to Symfony is a very big deal.  Drupal 8 is near total rewrite of Drupal, with almost all core functionality now provided through services and dependency injection and thus overrideable.  Interfaces and routing, classes and annotation, all idioms common in the Symfony world have been adopted in Drupal 8.

What is familiar to a Drupal Developer who hasn't worked with Symfony?  Well, the core business objects like nodes, blocks, taxonomy terms, and fields still exist, though they are implemented quite differently. The hook system isn’t too different either, but be warned that what you receive in an array of parameters is quite different.  And the Form API, though not totally unchanged, is one place where the Symfony solution was rejected, though perhaps not outright: there is an active discussion on right now about whether to integrate the Symfony form component into Drupal 9

4. API Docs and Change records are your friend

The documentation team has worked incredibly hard to keep the documentation up with the changes that have occurred. has fantastic information about the classes and concepts you’ll encounter now.

One big issue is that many things have new names now.  This is where the change records are essential.  Something like “menu_get_object” from Drupal 6 or 7 has been replaced.  Searching for a old command in the change records will often bring up the exact code snippet you need to update your code.

5. Config management

The configuration management inititiative is one of the biggest changes in Drupal 8. All configuration, whether it be a view, a content type, or the site title, can now be managed via importing and exporting yml files, either through a UI or via Drush. The Features module, which was the best method of synchronizing configuration across development and production sites in D6 and D7, is considerably less essential now

All the nitty gritty details of configuration management are beyond the scope of this introduction, but I will share a few useful tips that we learned in development.

  • Start your local dev site with a config export and settings file from your staging site. You need to make sure the hash salt in your settings.php and the UUIDs in your config files are in synch, otherwise you will not be able to synchronize the configuration accross sites.
  •  Move the config directory out of sites/default/files. Not absolutely necessary, but it is becoming a best practice to move the config out of the site directory. It is an easy enough change to make and increases site security considerably.
  • Only commit production config to master, merge dev config in from branches. Config management does not include a method of identifying and merging changes between two different config directories or changes that were made in one branch that are absent in another: it is up to your source control system to handle that. If you start committing development config to your master branch, then expect to export changes from production before importing the dev changes, you will be in trouble!  It doesn't work like that. The better method is commit to your dev branch, then export production config to master and commit. Next merge dev into master, and finally import the merged config into production. Confusing? It is a bit, and the diagram on this Pantheon blog post doesn't make it less so. The short version is just don't commit anything but production config to master and you'll usually be alright.
  • It isn't always obvious what will be considered config and what is content. This has been an on-going problem for Drupal Developers to wrap their head around. For example, block placement is  configuration and thus stored in yml but block content is not.  It mostly makes sense once you get in there, but undeniably there is a bit of a learning curve here. 

As I mentioned, the Features module is still available; it looks like it will come into play for bundles of configuration that need to be pushed live jointly but independent of an entire site's config. Configuration management best practices are still evolving, however, so it remains to be seen exactly how wide Features for D8 adoption is or if other tools emerge.

6. Drush and the Drupal Console

Drush is still around and as essential as ever.  A few key new command in Drush 8:

drush cr - Cache rebuild, the replacement for drush cc all in Drupal 7

drush cim - import config, similar to drush fra in 7

drush cex - export config, similar to drush fu in 7

drush cedit - edit the config yml in your editor. This can be really handy sometimes.

The Drupal Console is a new option for command line users. It is based on the Symfony Console and an extremely exciting new arrow to have in our quivers.

Drupal Console can do many of the things drush can, but the focus of this project is a bit difference than Drush's. Most significantly is the effort in making Drupal Console generate pristine boilerplate code. That may not sound like much, but given the adoption of OO, PSR-4 namespaces, and autoloading, being able in a few keystrokes to generate a block plugin with all of the correct annotation, namespacing, and file placement is a huge timesaver. It also makes becoming productive in Drupal 8 much less daunting: you don't initially need to understand all of the changes that have taken place. Instead, let Drupal Console take care of registering your new plugin so you can focus on just the logic you need to deliver. Later you can come back and learn about what the annotation means, what the parent class does, and so on. 

7. Managing your build

We usually use Drush Make files to manage our builds, including contrib modules, patches, and libraries.

Traditional Drush Makefiles still work in Drupal 8. They have also introduced a makefile in .yml format

Embracing a trend that has spread across the wider PHP work, Composer can also be used to manage your Drupal install, and already is being used by Drupal itself to manage dependencies. There is good documentation on how to use Composer to manage your install on, making use of the Drupal Composer/Drupal Project and Drupal's Packagist host.  

Whether this approach will take off or whether Drupallers will stick with Drush again remains to be seen.

8. The theme layer is now in twig.

Another element that comes to Drupal from Symfony, Twig has been adopted for templating.

Twig is easy to use and significantly more secure than PHPTemplate was. It also introduces a new template extension model to Drupal, which I'm quite excited about. I suspect it is going to take a while for existing Drupal themers to embrace this model, but folks who come to Drupal from Symfony or Django will be pleased to have extendable templates available to them. And there are promising signs that some contrib themes are starting to embrace it

9. Theme debugging tools now in core.

In Drupal 8 in your services.yml file, you can enable theme debugging. Once you do you'll see output like this:

with all the candidate templates listed. The template that was actually used is indicated with the x rather than the *.  

One thing to watch for is that with theme debugging enabled some JSON calls break.  

You know what is extra cool? Theme debugging was backported into Drupal 7 too. Try drush vset theme_debug true some time and you'll similar output there.

More advanced debugging still requires the devel module. {{ kint(var) }} is my favourite twig debugging snippet.  The arrays are much more deeply nested than what you are used to from previous Drupals, so be sure to give php enough memory! Also, enable autoreload and disable template caching in your settings.yml file before debugging front-end code. Otherwise you need to clear cache on every page load.

10. A new approach to release management promises more rapid improvements in the future.

No longer will we have to wait five years for any significant changes in core functionality!  As is explained in the release cycle overview on, "Starting with Drupal 8.0.0, Drupal core releases will move to a new release cycle schedule" with the intent being for minor releases to come out twice a year. Drupal 8.0 has been out since October, thus we are only about two months from the release of 8.1.0. A beta release of 8.1 will be available in less than a month!

8.1 is going to add, among other things, improvement to migration support from Drupal 7 and the migration UI. It appears BigPipe will also make it into 8.1. Will there be upgrade issues for site builders or compatibility issues for contrib modules moving from one minor release to the next? Will poorly maintained sites end up stranded on minor releases? Again, time will tell, but it is exciting to think there will be significant improvements to core available to us a couple of times a year.


Janez Urevc: A lot of exciting Drupal 8 media news!

wo, 2016/02/10 - 5:10pm
A lot of exciting Drupal 8 media news!

Media made a big leap towards a first major milestone. It's time to test what we have and help stabilise it.

At the beginning of November 2015 MD Systems announced the Media initiative program that they initiated in cooperation with Ringier, Gassmann media and Südostschweiz. Initiative was kicked off with a week long sprint, which happened at first week of December in Zurich. Work didn't end when sprint was over. Together with the team at MD Systems I continued to work on most important tasks to achieve a major milestone.

Photo by Stefanie Gupta

Note nr. 1: MD Systems are funding part of my time to work on Drupal 8 media. They are constantly investing in Drupal core and many contrib modules. They are one of the greatest Drupal service providers and number 1 Drupal organizational contributor taking their size into consideration. You need a site built? You should definitely get in touch with them.

Note nr. 2: (my employer and very well know enterprise Drupal 7 site) gives every developer a so-called "Drupal day" every other week. This allows me to work on Drupal 8 media components. We have been working on a Drupal 8 project for a while now, which also allowed me to do a lot of contrib work during my work hours. Thank you! You are great!

Since my last post we did a ton of work in many areas. Let me quickly list most important ones:

  1. Image cropping: We added few more features to Crop API. Image widget crop used those to provide new features such as soft and hard crop size limits, handling of default crops and ability to use cropper tool outside of field widget context. This allowed us to add cropper tool to the file edit form that File entity provides. Image widget crop was also promoted to a full project on We also started working on Crop API integration for Focal point module, which is very close to be committed. This will bring even more standardization in this area, which is something we are very excited about.

  2. File entity: we managed to bring this important module to the level where we can confidently say that it has reached feature parity with Drupal 7 version. This allowed us to bring it back home (to and make -dev version available on the project page.

  3. Entity browser: we continued our work on the configuration UI. Patch is almost ready. We need few more people to help us with testing and reviews. I hope that we will be able to commit it in the next week or so. We also added new selection display plugin which supports multi-step workflow (upload few images, select few more from media library, import some more from a 3rd parts service, save everything in one step). This allows us to build content creation experiences that we never saw in Drupal core or contrib before. Plugin could use some visual improvements. This is great introductionary task for any themers and/or frontend develpers that would like to join us. Get in touch!

  4. Image effects: together with @mondrake we started new project that will become home for majority of image effects that didn't find it's way into core. We already ported most of effects from ImageCache actions and added few more that lived in other Drupal 7 modules. Effects that are currently available in Image effects module are: watermark, auto orientation, brightness, color shift, contrast, set canvas and strip metadata. There is also text overlay effect that is waiting to be reviewed and tested.

There are many other things in different areas of the ecosystem. We fixed bugs and added features in Media entity, Field formatter, Inline entity form, Entity embed, ...

What is next

In the course of the next few weeks we need to review and commit remaining patches. After that we'd like to tag new releases for most of the modules in the ecosystem. This will encourage people to start actively using and testing them.

Media ecosystem for Drupal 8 is not perfect yet, but we are able to support more and more use cases. Testing, finding bugs and fixing them in a timely manner should be our priority at this point. We want to stabilize the ecosystem to allow our users to rely on our components.

How to help?

Start contributing. You can write documentation, test modules in the ecosystem and report bugs, fixing bugs or work on new features, design UX, write automated tests, share ideas and much, much more. You have a skill, we have a task for you.

We are available on IRC. Join us on #drupal-media channel on and get involved. We always publish general announcements on

If you prefer more personal communication you can always ping me on Twitter (@slashrsm) or use the contact form on my blog to get in touch.

About me

I (Janez Urevc - @slashrsm) am one of the architects and maintainers of the media ecosystem for Drupal 8. If you like what I am doing please consider donating to my Bitcoin address: 1Xqe6gYWEbF1iKsy3Mr5SbAyebNyucj5t.

Together with some colleagues I'm building a small team of professionals that will be providing top-level consulting, training and development related to media in Drupal 8. If you're interested or you'd like to work with us please get in touch.

slashrsm Wed, 10.02.2016 - 17:10 Tags Drupal Media Enjoyed this post? There is more! Zurich Drupal 8 media sprint was a success! When will media be ready for Drupal 8?

View the discussion thread.


Mediacurrent: Drupal Bits and Bytes: How to Add Content in an Update Hook

wo, 2016/02/10 - 4:22pm
Why would I want to add content in an update hook?

Lullabot: The Uncomplicated Firewall

wo, 2016/02/10 - 2:37pm

Firewalls are a tool that most web developers only deal with when sites are down or something is broken. Firewalls aren’t fun, and it’s easy to ignore them entirely on smaller projects.

Part of why firewalls are complicated is that what we think of as a "firewall" on a typical Linux or BSD server is responsible for much more than just blocking access to services. Firewalls (like iptables, nftables, or pf) manage filtering inbound and outbound traffic, network address translation (NAT), Quality of Service (QoS), and more. Most firewalls have an understandably complex configuration to support all of this functionality. Since firewalls are dealing with network traffic, it’s relatively easy to lock yourself out of a server by blocking SSH by mistake.

In the desktop operating system world, there has been great success in the "application" firewall paradigm. When I load a multiplayer game, I don’t care about the minutiae of ports and protocols - just that I want to allow that game to host a server. Windows, OS X, and Ubuntu all support application firewalls where applications describe what ports and protocols they need open. The user can then block access to those applications if they want.

Uncomplicated Firewall (ufw) is shipped by default with Ubuntu, but like OS X (and unlike Windows) it is not turned on automatically. With a few simple commands we can get it running, allow access to services like Apache, and even add custom services like MariaDB that don’t ship with a ufw profile. UFW is also available for other Linux distributions, though they may have their own preferred firewall tool.

Before you start

Locking yourself out of a system is a pain to deal with, whether it’s lugging a keyboard and monitor to your closet or opening a support ticket. Before testing out a firewall, make sure you have some way to get into the server should you lock yourself out. In my case, I’m using a LAMP vagrant box, so I can either attach the Virtualbox GUI with a console, or use vagrant destroy / vagrant up to start clean. With remote servers, console access is often available through a management web interface or a "recovery" SSH server like Linode’s Lish.

It’s good to run a scan on a server before you set up a firewall, so you know what is initially being exposed. Many services will bind to ‘localhost’ by default, so even though they are listening on a network port they can’t be accessed from external systems. I like to use nmap (which is available in every package manager) to run port scans.

$ nmap Starting Nmap 6.40 ( ) at 2015-09-02 13:16 EDT Nmap scan report for trusty-lamp.lan ( Host is up (0.0045s latency). Not shown: 996 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 111/tcp open rpcbind 3306/tcp open mysql Nmap done: 1 IP address (1 host up) scanned in 0.23 seconds

Listening on for SSH and HTTP connections makes sense, but we probably don’t need rpcbind (for NFS) or MySQL to be exposed.

Turning on the firewall

The first step is to tell UFW to allow SSH access:

$ sudo ufw app list Available applications: Apache Apache Full Apache Secure OpenSSH $ sudo ufw allow openssh Rules updated Rules updated (v6) $ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup $ sudo ufw status Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)

Test to make sure the SSH rule is working by opening a new terminal window and ssh’ing to your server. If it doesn’t work, run sudo ufw disable and see if you have some other firewall configuration that’s conflicting with UFW. Let’s scan our server again now that the firewall is up:

$ nmap Starting Nmap 6.40 ( ) at 2015-09-02 13:31 EDT Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.07 seconds

UFW is blocking pings by default. We need to run nmap with -Pn so it blindly checks ports.

$ nmap -Pn Starting Nmap 6.40 ( ) at 2015-09-02 13:32 EDT Nmap scan report for trusty-lamp.lan ( Host is up (0.00070s latency). Not shown: 999 filtered ports PORT STATE SERVICE 22/tcp open ssh Nmap done: 1 IP address (1 host up) scanned in 6.59 seconds

Excellent! We’ve blocked access to everything but SSH. Now, let’s open up Apache.

$ sudo ufw allow apache Rule added Rule added (v6)

You should now be able to access Apache on port 80. If you need SSL, allow "apache secure" as well, or just use the “apache full” profile. You’ll need quotes around the application name because of the space.

To remove a rule, prefix the entire rule you created with "delete". To remove the Apache rule we just created, run sudo ufw delete allow apache.

Blocking services

UFW operates in a "default deny" mode, where incoming traffic is denied and outgoing traffic is allowed. To operate in a “default allow” mode, run sudo ufw default allow. After running this, perhaps you don’t want Apache to be able to listen for requests, and only want to allow access from localhost. Using ufw, we can deny access to the service:

$ sudo ufw deny apache Rule updated Rule updated (v6)

You can also use "reject" rules, which tell a client that the service is blocked. Deny forces the connection to timeout, not telling an attacker that a service exists. In general, you should always use deny rules over reject rules, and default deny over default allow.

Address and interface rules

UFW lets you add conditions to the application profiles it ships with. For example, say you are running Apache for an intranet, and have OpenVPN setup for employees to securely connect to the office network. If your office network is connected on eth1, and the VPN on tun0, you can grant access to both of those interfaces while denying access to the general public connected on eth0:

$ sudo ufw allow in on eth1 to any app apache $ sudo ufw allow in on tun0 to any app apache

Replace from <interface> with on <address> to use IP address ranges instead of interface names.

Custom applications

While UFW lets you work directly with ports and protocols, this can be complicated to read over time. Is it Varnish, Apache, or Nginx that’s running on port 8443? With custom application profiles, you can easily specify ports and protocols for your own custom applications, or those that don’t ship with UFW profiles.

Remember up above when we saw MySQL (well, MariaDB in this case) listening on port 3306? Let’s open that up for remote access.

Pull up a terminal and browse to /etc/ufw/applications.d. This directory contains simple INI files. For example, openssh-server contains:

[OpenSSH] title=Secure shell server, an rshd replacement description=OpenSSH is a free implementation of the Secure Shell protocol. ports=22/tcp

We can create a mariadb profile ourselves to work with the database port.

[MariaDB] title=MariaDB database server description=MariaDB is a MySQL-compatible database server. ports=3306/tcp $ sudo ufw app list Available applications: Apache Apache Full Apache Secure MariaDB OpenSSH $ sudo ufw allow from to any app mariadb

You should now be able to access the database from any address on your local network.

Debugging and backup

Debugging firewall problems can be very difficult, but UFW has a simple logging framework that makes it easy to see why traffic is blocked. To turn on logging, start with sudo ufw logging medium. Logs will be written to /var/log/ufw.log. Here’s a UFW BLOCK line where Apache has not been allowed through the firewall:

Jan 5 18:14:50 trusty-lamp kernel: [ 3165.091697] [UFW BLOCK] IN=eth2 OUT= MAC=08:00:27:a1:a3:c5:00:1e:8c:e3:b6:38:08:00 SRC= DST= LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=65499 DF PROTO=TCP SPT=41557 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0

From this, we can see all of the information about the source of the request as well as the destination. When you can’t access a service, this logging makes it easy to see if it’s the firewall or something else causing problems. High logging can use a large amount of disk space and IO, so when not debugging it’s recommended to set it to low or off.

Once you have everything configured to your liking, you might discover that there isn’t anything in /etc with your rules configured. That’s because ufw actually stores its rules in /lib/ufw. If you look at /lib/ufw/user.rules, you’ll see iptables configurations for everything you’ve set. In fact, UFW supports custom iptables rules too if you have one or two rules that are just too complex for UFW.

For server backups, make sure to include the /lib/ufw directory. I like to create a symlink from /etc/ufw/user-rules to /lib/ufw. That way, it’s easy to remember where on disk the rules are stored.

Next steps

Controlling inbound traffic is a great first step, but controlling outbound traffic is better. For example, if your server doesn’t send email, you could prevent some hacks from being able to reach mail servers on port 25. If your server has many shell users, you can prevent them from running servers without being approved first. What other security tools are good for individual and small server deployments? Let me know in the comments!


OpenLucius: 18 Drupal SEO modules - and tools for better findability in Google

wo, 2016/02/10 - 2:32pm

Search engine optimization (SEO) has always been important, but in recent years its importance seems to have increased significantly. We were more often dealing with Drupal SEO implementations than in previous years. Many of the implementations contained overlapping components. Below we will discuss the most important ones:


Dries Buytaert: Turning Drupal outside-in

wo, 2016/02/10 - 11:49am

There has been a lot of discussion around the future of the Drupal front end both on (#2645250, #2645666, #2651660, #2655556) and on my blog posts about the future of decoupled Drupal, why a standard framework in core is a good idea, and the process of evaluating frameworks. These all relate to my concept of "progressive decoupling", in which some portions of the page are handed over to client-side logic after Drupal renders the initial page (not to be confused with "full decoupling").

My blog posts have drawn a variety of reactions. Members of the Drupal community, including Lewis Nyman, Théodore Biadala and Campbell Vertesi, have written blog posts with their opinions, as well as Ed Faulkner of the Ember community. Last but not least, in response to my last blog post, Google changed Angular 2's license from Apache to MIT for better compatibility with Drupal. I read all the posts and comments with great interest and wanted to thank everyone for all the feedback; the open discussion around this is nothing short of amazing. This is exactly what I hoped for: community members from around the world brainstorming about the proposal based on their experience, because only with the combined constructive criticism will we arrive at the best solution possible.

Based on the discussion, rather than selecting a client-side JavaScript framework for progressive decoupling right now, I believe the overarching question the community wants to answer first is: How do we keep Drupal relevant and widen Drupal's adoption by improving the user experience (UX)?

Improving Drupal's user experience is a topic near and dear to my heart. Drupal's user experience challenges led to my invitation to Mark Boulton to redesign Drupal 7, the creation of the Spark initiative to improve the authoring experience for Drupal 8, and continued support for usability-related initiatives. In fact, the impetus behind progressive decoupling and adopting a client-side framework is the need to improve Drupal's user experience.

It took me a bit longer than planned, but I wanted to take the time to address some of the concerns and share more of my thoughts about improving Drupal's UX (and JavaScript frameworks).

To iterate or to disrupt?

In his post, Lewis writes that the issues facing Drupal's UX "go far deeper than code" and that many of the biggest problems found during the Drupal 8 usability study last year are not resolved with a JavaScript framework. This is true; the results of the Drupal 8 usability study show that Drupal can confuse users with its complex mental models and terminology, but it also shows how modern features like real-time previews and in-page block insertion are increasingly assumed to be available.

To date, much of our UX improvements have been based on an iterative process, meaning it converges on a more refined end state by removing problems in the current state. However, we also require disruptive thinking, which is about introducing entirely new ideas, for true innovation to happen. It's essentially removing all constraints and imagining what an ideal result would look like.

I think we need to recognize that while some of the documented usability problems coming out of the Drupal 8 usability study can be addressed by making incremental changes to Drupal's user experience (e.g. our terminology), other well-known usability problems most likely require a more disruptive approach (e.g. our complex mental model). I also believe that we must acknowledge that disruptive improvements are possibly more impactful in keeping Drupal relevant and widening Drupal's adoption.

At this point, to get ahead and lead, I believe we have to do both. We have to iterate and disrupt.

From inside-out to outside-in

Let's forget about Drupal for a second and observe the world around us. Think of all the web applications you use on a regular basis, and consider the interaction patterns you find in them. In popular applications like Slack, the user can perform any number of operations to edit preferences (such as color scheme) and modify content (such as in-place editing) without incurring a single full page refresh. Many elements of the page can be changed without the user's flow being interrupted. Another example is Trello, in which users can create new lists on the fly and then add cards to them without ever having to wait for a server response.

Contrast this with Drupal's approach, where any complex operation requires the user to have detailed prior knowledge about the system. In our current mental model, everything begins in the administration layer at the most granular level and requires an unmapped process of bottom-up assembly. A user has to make a content type, add fields, create some content, configure a view mode, build a view, and possibly make the view the front page. If each individual step is already this involved, consider how much more difficult it becomes to traverse them in the right order to finally see an end result. While very powerful, the problem is that Drupal's current model is "inside-out". This is why it would be disruptive to move Drupal towards an "outside-in" mental model. In this model, I should be able to start entering content, click anything on the page, seamlessly edit any aspect of its configuration in-place, and see the change take effect immediately.

Drupal 8's in-place editing feature is actually a good start at this; it enables the user to edit what they see without an interrupted workflow, with faster previews and without needing to find what thing it is before they can start editing.

Making it real with content modeling

Eight years ago in 2007, I wrote about a database product called DabbleDB. I shared my belief that it was important to move CCK and Views into Drupal's core and learn from DabbleDB's integrated approach. DabbleDB was acquired by Twitter in 2010 but you can still find an eight-year-old demo video on YouTube. While the focus of DabbleDB is different, and the UX is obsolete, there is still a lot we can learn from it today: (1) it shows a more integrated experience between content creation, content modeling, and creating views of content, (2) it takes more of an outside-in approach, (3) it uses a lot less intimidating terminology while offering very powerful capabilities, and (4) it uses a lot of in-place editing. At a minimum, DabbleDB could give us some inspiration for what a better, integrated content modeling experience could look like, with the caveat that the UX should be as effortless as possible to match modern standards.

Other new data modeling approaches with compelling user experiences have recently entered the landscape. These include back end-as-a-service (BEaaS) solutions such as Backand, which provides a visually clean drag-and-drop interface for data modeling and helpful features for JavaScript application developers. Our use cases are not quite the same, but Drupal would benefit immensely from a holistic experience for content modeling and content views that incorporates both the rich feature set of DabbleDB and the intuitive UX of Backand.

This sort of vision was not possible in 2007 when CCK was a contributed module for Drupal 6. It still wasn't possible in Drupal 7 when Views existed as a separate contributed module. But now that both CCK and Views are in Drupal 8 core, we can finally start to think about how we can more deeply integrate the two. This kind of integration would be nontrivial but could dramatically simplify Drupal's UX. This should be really exciting because so many people are attracted to Drupal exactly because of features like CCK and Views. Taking an integrated approach like DabbleDB, paired with a seamless and easy-to-use experience like Slack, Trello and Backand, is exactly the kind of disruptive thinking we should do.

What most of the examples above have in common are in-place editing, immediate previews, no page refreshes, and non-blocking workflows. The implications on our form and render systems of providing configuration changes directly on the rendered page are significant. To achieve this requires us to have robust state management and rendering on the client side as well as the server side. In my vision, Twig will provide structure for the overall page and non-interactive portions, but more JavaScript will more than likely be necessary for certain parts of the page in order to achieve the UX that all users of the web have come to expect.

We shouldn't limit ourselves to this one example, as there are a multitude of Drupal interfaces that could all benefit from both big and small changes. We all want to improve Drupal's user experience — and we have to. To do so, we have to constantly iterate and disrupt. I hope we can all collaborate on figuring out what that looks like.

Special thanks to Preston So and Kevin O'Leary for contributions to this blog post and to Wim Leers for feedback.


Valuebound: Newly introduced mobile first Menu management in Drupal 8

wo, 2016/02/10 - 9:16am

In this tutorial, we'll continue site building by adding menu items. We will create custom menus which'll be used to display links, then assigning these links to a page and add a menu link to specific region within the theme.

Managing Drupal 8 menu happens at the administrator area. To begin, login as an administrator in your Drupal 8 website.

Although there are several default menus available in core, we have ability to create own custom menu using admin interface. This has to be done in two parts. first part is to create structure of the menu and the second is to add links. Below are the steps for creating a general menu structure in Drupal 8.

Step 1: Create a Menu
To create a menu, visit Manage >> Structure >> Menus…


DrupalCon News: Help Make the Site Building Track Memorable

wo, 2016/02/10 - 8:52am

Session Submissions for DrupalCon New Orleans are open, and we need you to send in sessions related to site building. A site building session was one of my best DrupalCon memories:


Valuebound: Creating Home page and basic pages

wo, 2016/02/10 - 8:31am

Creating a Home page in Drupal 8 is quite similar to Drupal 7.  just we need to create a page and assigning that page to display on <front> page or prompted other node to be display on home page. However, you may wish to have a custom static page on your site instead. This article will guide you through the process of changing the front page of your Drupal 8 website.

Step 1 :  Log into your Drupal 8    
Step 2 : select “manage”  menu from the toolbar.  the main menu across the top, select the Menu option.

under manage you will find “


Modules Unraveled: 155 Using the Block Visibility Groups Module as a Lightweight Replacement for Context and Panels in Drupal 8 with Ted Bowman - Modules Unraveled Podcast

wo, 2016/02/10 - 7:00am
Published: Wed, 02/10/16Download this episodeScheduled Updates
  • What is the Scheduled Updates module?
  • How does it differ from the Scheduler module?
  • What are some of the use cases? What types of updates can be scheduled?
  • Is it ready to be used?
Block Visibility Groups
  • What is Block Visibility Groups?
  • How does it differ from Context and Panels?
  • Do you intend it to be a replacement for context?
  • When would you use it instead Panels
  • What are some example use cases?
  • How does it work with other D8 block-related modules?
  • Is it ready to be used?
Episode Links: Ted on drupal.orgTed on TwitterTed on GithubSix Mile TechScheduled UpdatesBlock Visibility GroupsField as BlockSimple BlockTags: Drupal 8Scheduled UpdatesBlock Visibility Groupsplanet-drupal

Darryl Norris's Blog: Rebuilding Using Drupal 8

wo, 2016/02/10 - 1:28am

I have been experimenting with Drupal 8 for about a year and half trying to be ready to use it in my projects. Currently Drupal 8 is interesting stage where some Drupal 7 project have been doing a straight port, some of them are been re-architecture and some project have die. For this reason I have decide to try it out some of those new contrib projects with Drupal 8 version on a production site There few things that I took consider before I started working on rebuilding my website. I wanted to have my website with a decent front page load time under 2 seconds. I did not wanted to do a migration because my website is very small so I thought it will be better to rebuild the entire website instead of migrating. Also, I wanted to make it into a blog, because my previous website I had lot other things plan for the website and I never did; as results, I ended up with some a lot unnecessary contrib modules. Finally, my website should SEO friendly. What theme ? Casper Be


Acquia Developer Center Blog: Around the Drupal World in 120 Days with Enzo

di, 2016/02/09 - 9:41pm

Listen to Drupal developer, contributor and businessperson, Enzo Garcia talk about how he is traveling around the world for 120 days in 2016, spreading the word in India, Asia and Australasia about building community and identity, the importance of Drupal 8 in the developing world, and the Drupal Console.

"As Larry Garfield said, Drupal 7 was an island. In real life, we have islands in communities, because we don’t know what boats we need to take to get to that island."

Keeping promises, fostering communities

During the election for the Drupal Association Community Board seat in 2015, Enzo made a promise: "I promised I will try to help local communities in developing countries to increase their presence in Drupal worldwide community, and the only way I found is to visit them and teach them how to use Drupal, the Drupal Console, to promote them writing documentation for Drupal 8 in their mother language ... And maybe to try to grow out the community in that way."

"I am going to New York first, Singapore, Vietnam, Korea - South Korea, Japan, five cities in China, Thailand, Cambodia, Hong Kong, Philippines, maybe Australia and New Zealand. I am trying to put my money where my mouth is. I said that it’s possible and I am trying to do it. I’m having a sponsor recently, a Chinese person. He wants to invite me to do a session in Beijing, and he paid my flight to go to Beijing."

Q: So you’re going to meet-ups; you’re going to companies; you’re talking with these local communities. What is it that you’re promoting? What is your mission with these communities in the developing world?

My mission is to save them – okay, you can do more for yourself. You need to try to believe in yourself. You’re now to start to write documentation in your language, in [Chinese] and they - in Thai, in any language, because [Unintelligible] you solve your problems, right? Obviously, the idea is Drupal 8 is coming out, so it’s the learning curve. Everybody, they still worry about that, so I want to try to show them it’s not that – it’s difficult, but it’s not impossible; and try to put a seed in there to – in the - in many things, like they need to be more participate – they need to participate more in DrupalCons or near Drupal Camps to try to create a better Asian community around Drupal.

So my idea is we’ll be really – I will be really happy if we start to see more contributions from China and maybe pushing the Drupal Association to try to have some multilingual information in their homepage, because the main complaint, they say, for instance, I talk with people from Korea and Japan and China, it’s like when they try to sell or find something, is not the best source of information for them. This is something they really want.

They are working as an island. For instance, they have a website, and they publish a lot of information. Nobody knows about that. They don’t use their GDOs, because they don’t feel this is a good way to communicate in their community. So I think the challenge is for Drupal organization around the world is to try to find the proper channels to communicate with them. So what I did, I do some research and I discovered they used QQ, which is a clone of ICQ, and then I create my account and it was in Chinese. It was a nightmare at the beginning, but now finally, I found the groups and they are totally open. If you follow this group, this is like 4,000 people talking about Drupal problems, issues, documents; and they really love when some people overseas tried to share something with them.

As Larry Garfield said, Drupal 7 was an island. In real life, we have islands in communities, because we don’t know what boats we need to take to get to that island.

Q: So are you doing this trip to build some bridges between those islands and start to connect us better?

That is the point. It is one of the ideas. I have to learn about them. As I say, we need to learn what is doing for them, because maybe IRC, as you’ve said in the beginning in the session, is popular for Drupalers, but that doesn’t mean it’s the unique way to reach people. So I think in any country or any region, we need to find the options we have to communicate with them.

Interview video - 28 min.

120 days, 3 missions

Q: You've got three themes you're highlighting during your 120 trip. What are they?

Enzo: "The first thing is convincing local communities to believe in themselves and to grow themselves to produce documentation, to produce – to help each other in their own languages."

Q: Second. What is it that makes Drupal 8 an especially good fit for people in the developing world that you’re visiting?

Enzo: "Okay, because I grew up in a developing country, I am Colombian by birth, sometimes we don’t use first class software because we believe it’s expensive and will be really hard to find resources to do that. So for the reason in developing countries, you see some government sites that are really bad. So I think if we can provide the tools to teach them, you can create first class product for yourself; not to sell in USA, for America or Europe. So you can create first class products for your government, for universities. So the quality of life will be elevated. Because for instance, in Africa they have more mobiles and they don’t have mobile or responsive government websites, because all the solutions they have are really expensive. So this is my point of view. So giving them the tools to do a first class product, will we change their societies. The Drupal community is providing the best possible enterprise professional government quality software to anyone who wants to solve a problem in their own country. So they don’t need to look solutions out there. They just need to learn the first class product to do first class stuff for your citizens.

Q: Third. Now, your third message. The Drupal Console that run with Jesus Olivas and some other great people. What is the Drupal Console is and why people should be using it? What does it do?

Enzo: Drupal Console is a tool built using Symfony Console in the same way the Drupal 8 used Symfony components to create Drupal 8. We do the same to try to bring the awesomeness that Symfony Console provides in the Drupal work, and the main feature is to generate Drupal 8 code. You can generate controllers, models, forms, or in the basic stuff you need to be as a Drupal developer. In that way...

Q: So it saves me writing a lot of boilerplate code, for one.

Enzo: "Exactly. So you don't need to worry about that at the beginning. You could be productive in five minutes, and then just be concentrate in the business logic of the company. The second thing is we can create content that is good. In terms of local community, Drupal Console provides a special addition to local communities. We have right now 12 languages supported. Hindi, for example. That is good for DrupalCon India, and it’s translated in more than 80% to Hungarian, Romanian, Chinese, and Vietnamese.

It’s like Nelson Mandela said, "If you speak to someone in their mother language, you touch their heart." So we are trying to do that. So you can do two [Unintelligible] stuff fast and quickly, and if you speak Chinese, that is like that opened your mind totally.

Guest dossier
  • Name: Enzo
  • Work affiliation: CTO, Anexus
  • enzo
  • Twitter: @enzolutions
  • LinkedIn: Eduardo Garcia
  • Website:
  • Current projects: Drupal Console
  • 1st version of Drupal/PHP: Drupal 6. Enzo read Pro Drupal Development in 48 hours before a job interview, got the job, trained two others in Drupal and delivered his first project in three months!
Podcast series: Drupal 8Skill Level: Beginner

Palantir: The Secret Sauce podcast, Ep. 04

di, 2016/02/09 - 7:04pm

Wouldn't it be nice to have a butler on hand to help streamline things? Well, in this case we're not talking about a person who comes to your house and waits on you, but rather an impressive and integral front-end development tool developed internally at to help automate some of our work.

iTunes | RSS Feed | Download

Butler does a lot of things and has plenty of features, which our Front-End Developer Lauren Byrwa talks about in this week's short-form podcast called The Secret Sauce. Things like:

  • Gulp integration
  • Compiles your Sass and rebuilds your prototype
  • Moves your prototype into Drupal 7 or Drupal 8
  • Refreshes your browser so you can see updates simultaneously in multiple places
  • Plenty of optimization options, too, so you know where exactly the performance issues are coming from

Thanks for listening, and look for our long-form podcast On the Air With Palantir this Thursday!

Want to talk about how to streamline and test your front-end work to ensure you have the absolute best performance on your site? Let's schedule a time to talk.


Cryptic.Zone: Drupal 8 Cheatsheet for Developers

di, 2016/02/09 - 5:02pm

It has been a few months since Drupal 8 was released and sites built with it are starting to crop up. I myself have had the pleasure of working with it, and more Drupal 8 projects are certainly on the horizon. From a developer's perspective, this version is substantially different from the previous one, and we will need to learn a handful of new ways of doing things. To ease the process, I have put together this list of how-tos with tasks that I commonly encounter during development. I hope you will find it helpful.


Commerce Guys: Commerce Guys Refocusing on Drupal Commerce as Becomes an Independent Company

di, 2016/02/09 - 12:26pm

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, With thousands of customers and an ever expanding list of supported technologies, 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, 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 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.


Microserve: Caching beyond the norm in Drupal 7

di, 2016/02/09 - 10:19am
Caching beyond the norm in Drupal 7Feb 9th 2016

When developing in a drupal centric environment there are two general methods used to cache information on the system in modules, these can be used to persist while a page is loading using drupal static or for a longer periods using cache set and cache get.

I have used some other simple and alternative methods, and from reading notes before the drupal_static function declaration in; ways of getting even more efficient caching.

First I’ll address drupal static; it’s explained very neatly on this Lullabot article.

This is not necessarily always required. If you have a simple function in your code that you want to remember, a setting and speed is a must, you can just use a static variable.

function get_a_value($value_name) { static $function_settings = array(); if (!isset($function_settings[$value_name])) { //get variable from database and set it to $fetched_value $function_settings['$value_name'] = $fetched_value; } else { return $function_settings[$value_name]; } }

The static variable $function_settings stays persistent throughout the execution of your page, and the caching stays localised to your function / module.

Another way to do something similar to above, but to include the drupal_static function, would be to do an advanced drupal_static pattern (this is mentioned in the drupal_static notes).

function user_access($string, $account = NULL) { // Use the advanced drupal_static() pattern, since this is called very often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__); } $perm = &$drupal_static_fast['perm']; //... }

This is taken directly from the notes. Here we assign a local static variable as in the previous example but if the local static variable is not set, we assign the local static variable to drupal_static. Now other functions and code outside of the function can call on drupal_static_reset and reset the locally declared static variable, but will still retain the efficiency of having the static variable locally as in the previous example.

The last method I would like to approach is by using a cache in an object:

class SomeClass { /** * * @var array */ protected $localCache = array(); public function getData($cid) { if ($data = $this->getCache($cid)) { return $data; } //nothing set //do time intensive task here and set to data $this->cache($cid, $data); return $data; } /** * * @param type $cid * @param type $data */ protected function cache($cid, $data) { $this->setLocalCache($cid, $data); cache_set($cid, $data, 'cache', strtotime('+7 days', time())); } protected function getCache($cid) { if ($data = $this->getLocalCache($cid)) { return $data; } if ($cache = cache_get($cid)) { return $cache->data; } return FALSE; } /** * * @param any $cid * @param any $data */ protected function setLocalCache($cid, $data) { $this->localCache[$cid] = $data; } /** * * @param any $cid * @return any */ protected function getLocalCache($cid) { return isset($this->localCache[$cid]) ? $this->localCache[$cid] : FALSE; } }

In this example, I do all the local caching within the object but if needs be, I will retrieve and save to the system cache if the required data is not saved locally. One thing I have omitted is methods to clear the local cache. This caching this essentially using a local property.

If you wanted to clear the cache externally, you could create a public method or a static method.

So that about wraps this one up. Have you used any different methods? Can it be done better? Tell me what you think in the comment section below.

Written by: Darren Whittington, Senior Developer

Microserve is a Drupal Agency based in Bristol, UK. We specialise in Drupal Development, Drupal Site Audits and Health Checks, and Drupal Support and Maintenance. Contact us for for further information.


Deeson: Drupal Focal Point Module: Making the most of your images

di, 2016/02/09 - 10:15am

Focal point is a Drupal module that allows site administrators to select an important portion of an image to focus on.

It’s similar in many ways to the Image field focus module. But rather than giving a square box with crosshairs for focusing and another for cropping (which you can only do inside the focus area and can be quite confusing), focal point allows you to select a single point on the image to focus on. It is also fully compatible with the Media module.

User experience

Let's take a look at focal point from an administrator's perspective. The user can click on the image at any point which adds an icon over that particular area, representing the chosen focal point (see below).

From this, the administrator can then select the “Image preview” link below the image which will display a page with both the original image and how the image will look with the different image styles.

As you can see below, the image has now been focused upon the parrot on the right.

Setup and configuration

Firstly, you need to download and enable the focal point module (

Upon enabling the module you will find a new image style called “Focal Point Preview”. This is used for the admin page and is the default preview style for setting the focal point. It rescales the image width to 250px with upscaling allowed.

You will also have two new image effects available for cropping “Focal Point Crop” and “Focal Point Scale And Crop” within the drupal image styles at admin/config/media/image-styles.

These both crop down to the point to which the user has selected on the image, and ensure that the chosen focal point will not be cropped out of the image.

Now you can create a new image style with one of these image effects, and then apply this image style to an image field within the manage display page of your content type. The images will then crop to the selection the user has chosen.


To enable the compatibility with the media module, you should ensure that the “Media module image fields” setting at admin/config/media/focal_point is enabled.

Then, after adding an image via a field using the media browser widget, another step is provided in the media browser overlay. You can now add a focal point as you would in a standard image field.

You can also edit previously uploaded images to set an individual focal point.


DrupalCon News: You are the Coding & Development Track

ma, 2016/02/08 - 6:40pm

With core Drupal 8 now in full swing and the contrib space rapidly maturing, now is an excellent time to get more deeply involved with one of the world’s largest open-source development communities. The Coding and Development track is focused on educating developers on the latest techniques and tools for increasing the quality and efficacy of their projects.