Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 34 min 12 sec ago

Morpht: Creating comments via email in Drupal 7

Wed, 05/10/2017 - 05:36
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpLearn how to create content via email and have it imported into Drupal using Mail Comment./p /div/div/divspan property=schema:name content=Creating comments via email in Drupal 7 class=rdf-meta element-hidden/spanspan rel=schema:url resource=/posts/creating-comments-email-drupal-7 class=rdf-meta element-hidden/span

Palantir: The Lowdown on DrupalCon Baltimore

Tue, 05/09/2017 - 23:33
spanThe Lowdown on DrupalCon Baltimore/span spana title=View user profile. href=https://www.palantir.net/people/alex-brandt lang= about=https://www.palantir.net/people/alex-brandt typeof=schema:Person property=schema:name datatype= xml:lang=brandt/a/span spanTue, 05/09/2017 - 16:33/span Alex Brandt time datetime=2017-05-10T12:00:00ZMay 10, 2017/timeimg src=https://www.palantir.net/files/styles/hero/public/hero/2017-05/socks.jpg?itok=-Q4Lc5bH width=1300 height=731 alt=photo of Palantir swag typeof=foaf:Image /div class=lede pOur favorite parts of DrupalCon Baltimore./p /div In this post we will cover... ulli dir=ltr p dir=ltrOur favorite events from DrupalCon/p /li li dir=ltr p dir=ltrLinks to Palantir sessions/p /li /ulsection class=ctah3 class=cta__title /h3pStay connected with the latest news on web strategy, design, and development./p span class=cta__link a href=http://palantir.net/newsletterSign up for our newsletter./a /span /sectionpDrupalCon is always a positive experience for the Palantir team, largely because of the Drupal community itself. Our week in Baltimore was filled with engaged conversations, thoughtful sessions, and much appreciated down time with friends we don’t get to see often enough./p h3strongDrupalCon by the Numbers /strong/h3 ulliPalantiri in attendance: 14/li liPalantiri sessions: 3/li liClient meetings: 7/li liCoffees consumed: at least 2 dozen/li liNewsletter sign-ups: 240/li liPodcasts recorded: 2/li liLate nights: 2 many/li /ulblockquote p“It was a wonderful first DrupalCon experience because of a great community that is so supportive and accepting of newcomers, regardless of their level of Drupal knowledge.” - a href=https://www.palantir.net/people/annie-schowAnnie Schow/a/p /blockquote h3Highlights by Day/h3 pstrongMonday: We ate all the crabs. /strongbr / Following the opening reception in the exhibit hall, we ate dinner as a team at Riptide by the Bay In historic Fells Point. An impressive amount of crabs were consumed./p pimg alt=photo of Palantiri at dinner data-entity-type=file data-entity-uuid=75728c3a-8bc8-4385-a78b-cf821af2ee4d src=https://www.palantir.net/files/inline-images/groupdinner.jpg //p pimg alt=photo of crabs at dinner data-entity-type=file data-entity-uuid=841a86ab-8365-47e5-93e0-ed7b7c60755d src=https://www.palantir.net/files/inline-images/crabs.jpg //p pstrongTuesday: a href=https://events.drupal.org/baltimore2017/sessions/project-management-musical#PMTheMusical/a! /strongbr / We witnessed another standing ovation for Joe Allen-Black and Allison Manley and their performance of Project Management: The Musical! There were quite a few crowd favorites, and Joe and Allison were both happy to share their final performance of this presentation in front of an energetic DrupalCon crowd./p pimg alt=photo of Joe Allen-Black and Allison Manley data-entity-type=file data-entity-uuid=76ba5635-eae5-401e-b249-2506617a332b src=https://www.palantir.net/files/inline-images/musical.jpg //p pstrongWednesday: Inclusion Initiative /strongbr / We partnered with another Chicago-based agency, a href=http://www.dbridgesolutions.com/Digital Bridge/a, to coordinate a Drupal training session for five students local to Baltimore who were unfamiliar with Drupal. We’re looking forward to expanding the program in the future. Keep an eye out for more details on that later this month!/p pimg alt=photo of students data-entity-type=file data-entity-uuid=e8b162f9-397f-4937-8451-3e274392b73a src=https://www.palantir.net/files/inline-images/students.jpg //p pstrongThursday: a href=https://events.drupal.org/baltimore2017/sessions/content-code-d8-case-study#ContentBeforeCode/a, a href=https://events.drupal.org/baltimore2017/sessions/ins-and-outs-successful-vendor-relationships#DevTeamCollab/a and Trivia Night /strongbr / If you missed them at MidCamp, Megh Plunkett, Michelle Jackson, and Bec White did round two of their sessions on Thursday (recordings linked above). Michelle and Bec’s session will also be available via a webinar later this summer, so stay tuned for your chance to sign up in case you missed it at DrupalCon./p pPalantir also hosted Trivia Night at Baltimore Soundstage. We’re not sure the wait staff knew what was happening as over 400 people were tasked with answering some fairly obtuse and nerdy questions about this mysterious Drupal thing, but they kept everyone hydrated so we could enjoy the fun. Jeff Eaton killed yet again as the emcee for the evening. /p pimg alt=photo of Megh Plunkett data-entity-type=file data-entity-uuid=7dd2e235-5f52-46de-bce1-bb08ae0923db src=https://www.palantir.net/files/inline-images/megh.jpg //p pimg alt=photo of Allison Manley data-entity-type=file data-entity-uuid=6ae67835-602c-4b9c-895a-6c473f3f5b16 src=https://www.palantir.net/files/inline-images/allison.jpg //p pstrongFriday: Exploring Baltimore /strongbr / As people shuffled to the airport, a few Palantiri were able to squeeze in a last minute trip to the Baltimore National Aquarium. Thankfully not one Palantir was lost to sharks./p pimg alt=photo of group at aquarium data-entity-type=file data-entity-uuid=e8d3e89a-5d2a-4144-acab-0aa21d8132c1 src=https://www.palantir.net/files/inline-images/aquarium.jpg //p pThanks for a great week Baltimore. We’ll see you next time, DrupalCon!/p aside class=ctah3 class=cta__title /h3pWe want to make your project a success./p span class=cta__link a href=https://www.palantir.net/contactLet's Chat./a /span /asideul class=list--simpleli class=taga href=https://www.palantir.net/topics/community hreflang=enCommunity/a/li li class=taga href=https://www.palantir.net/topics/culture hreflang=enCulture/a/li li class=taga href=https://www.palantir.net/topics/drupal hreflang=enDrupal/a/li li class=taga href=https://www.palantir.net/topics/events hreflang=enEvents/a/li li class=taga href=https://www.palantir.net/topics/people hreflang=enPeople/a/li /ul

Acquia Developer Center Blog: Managing Drupal Sites with Composer

Tue, 05/09/2017 - 20:56
div class=field field-name-field-blog-image field-type-image field-label-hiddendiv class=field-itemsdiv class=field-item evenimg typeof=foaf:Image class=img-responsive src=https://dev.acquia.com/sites/default/files/styles/blog__190_x110_/public/blog/geerlingguy_0.jpg?itok=8O4ZG3Qy width=140 height=85 alt=Jeff Geerling title=Jeff Geerling //div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedp emstrongTalking through the growing pains of using Drupal with Composer dependency management at DrupalCon Baltimore./strong Drupal gets better when companies, organizations, and individuals build or fix something they need and then share it with the rest of us. Open source technologies become better, stronger, and smarter when others take it upon themselves to make a positive difference contributing their knowledge, time, and energy to it. Acquia is proud to play a part, alongside thousands of others, in making tomorrow’s Drupal better than today’s. strongOne of the people making a difference is Jeff Geerling./strong/em /p /div/div/divdiv class=field field-name-field-blog-tags field-type-taxonomy-term-reference field-label-inline clearfixdiv class=field-labelTags:nbsp;/divdiv class=field-itemsdiv class=field-item evena href=/tags/acquia-drupal-planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=acquia drupal planet/a/divdiv class=field-item odda href=/tags/composer typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Composer/a/divdiv class=field-item evena href=/tags/dependency-management typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=dependency management/a/divdiv class=field-item odda href=/tags/drupalcon typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupalcon/a/div/div/div

Ben's SEO Blog: How to Improve Drupal 8 Website Performance

Tue, 05/09/2017 - 18:30
div class=field field--name-body field--type-text-with-summary field--label-hiddendiv class=field-itemsdiv class=field-item even property=schema:articleBody content:encodedpGetting faster page load speeds isn’t just about increasing your Google rankings. It’s about improving customer satisfaction and gaining new revenue. Using tools specific to Drupal along with other universal actions, you can reach your marketing goals faster than ever./p pIt’s no secret that page loading speed matters to Google rankings. Speed became a ranking factor in 2010 and since that time, developers and marketers have been looking for ways to increase it. Google cares about page speed because the search engine is focused on delivering the best onsite user experience possible. As a result, Google rewards fast-loading websites with better rankings. (The converse is not always true. Slow page loading times will only negatively impact your site rankings if it is very slow.)/p pAs a marketer, your goal really isn’t better Google rankings. You are looking for the result of those rankings—more website visitors, more leads and more revenue. As a marketer, fast page load times aren’t the goal either; but, a means to improve your users’ experiences. Better website interactions can result in greater satisfaction, more conversions, and higher sales./p h2img alt=Happy business woman at desk title=Faster Drupal Page Speeds Means Higher Revenue height=801 width=1200 style=width: 400px; height: 267px; float: right; margin-left: 20px; margin-right: 20px; class=media-element file-wysiwyg data-delta=1 typeof=foaf:Image src=https://www.volacci.com/sites/default/files/1610_Speed_Revenue_Blog.jpg /Faster Page Load Time Results in Greater Revenue/h2 pFaster page navigation means that users may see more page views each time they visit your site. Having a fast website means that users can quickly understand your offering and purchase your products./p pStudies show that faster page speed results in greater revenue./p ul style=list-style-type:square;liBoth Amazon and Walmart, a href=http://www.globaldots.com/how-website-speed-affects-conversion-rates/in separate studies/a, attribute additional sales revenue from faster page speeds. Their revenue grew by 1% for every 100ms of page speed improvements. For Amazon, slowing down their page load time strongby just one second/strong could result in a loss in revenue of $1.6 billion. That’s a lot of zeroes for a measly second./li liShopzilla increased revenue by 12% and page views by 25% by speeding up their page load time to 1.2 seconds from 6 seconds./li /ulh2Customer Satisfaction Increases with Faster Page Speed/h2 pimg alt=Biker speeding across the landscape at sunset title=Faster Drupal Websites Mean Happier Customers height=801 width=1200 style=width: 400px; height: 267px; margin-right: 20px; float: left; class=media-element file-default data-delta=6 typeof=foaf:Image src=https://www.volacci.com/sites/default/files/1610_Speed_Satisfaction_Blog.jpg /Faster websites mean happier customers. Particularly, studies have shown that:/p ul style=list-style-type:square;liA one-second delay in page-load time leads to a drop in pageviews (11%), conversions (7%), and customer satisfaction (16%), a href=http://www.aberdeen.com/research/5136/ra-performance-web-application/content.aspxaccording to the Aberdeen Group/a./li lia href=https://econsultancy.com/blog/10936-site-speed-case-studies-tips-and-tools-for-improving-your-conversion-rateEconsultancy research/a found that 47% of consumers expect to wait no longer than two seconds for a web page to load. Additionally, 88% of people who experience a dissatisfying visit due to page load times are less likely to shop from that site and more than a third will tell their friends about the bad experience./li lia href=https://blog.kissmetrics.com/loading-time/?wide=1According to KISSmetrics/a, 18% of mobile users will abandon a website if it doesn’t load in less than five seconds. If it takes more than 10 seconds to load, 30% will abandon the site./li /ulh2img alt=Drupal 8 Website Speeding through tunnel title=Is Your Drupal 8 Website This Fast? height=843 width=1200 style=width: 400px; height: 281px; margin-left: 20px; margin-right: 20px; float: right; class=media-element file-wysiwyg data-delta=3 typeof=foaf:Image src=https://www.volacci.com/sites/default/files/1610_Speed_Fast_Blog.jpg /Is Your Website Fast Enough?/h2 pThe evidence shows page speed matters. Is your website fast enough? At a minimum you should aim for under 2 seconds. For e-commerce sites, you should have even faster goals.  Google’s goal is 100ms—faster than the blink of an eye./p pIt’s quite simple to test your website speed.  You can use Google’s a href=https://developers.google.com/speed/pagespeed/insights/PageSpeed Insights tool/a and a href=http://www.webpagetest.org/WebPageTest.org/a to take a benchmark of how your website performs. If your pages load in more than two seconds or if you haven’t met your page loading goals, you should consider taking some of the steps below./p h2Ways to Increase Your Drupal Website Performance/h2 pThere are general ways that every website manager can implement to speed up page loading, but there are also specific Drupal tools and modules to know and implement. I’ll address both of these./p h31. Keep it simple./h3 pPage speed starts with choosing a design that is clean and fast. By reducing the number of components on your page, and keeping widgets and embedded media to a minimum, you are on the way toward a lightning fast website./p h32. Cache your pages./h3 pDrupal 8 enables caching by default for anonymous visitors. That is sufficient for small to medium sized websites with moderate traffic. You can select the maximum age for your page caching based on how quickly your website content changes./p p1 day - good for websites that are only updated a couple of times per week. There is no commenting or other interaction on the site. (lead generation brochure site)/p p1 hour - good for websites that are updated once or twice per day. (ecommerce)/p p15 minutes- good for frequently updated websites. (news sites)/p pIf you use Drupal 8 Views or Panels, you can get more fine-grained in your cache settings. The caching on each individual block can be customized as well./p h3img alt=Women holding mobile phone looking at Drupal 8 website title=Optimize Your Drupal 8 Website for Mobile Devices height=800 width=1200 style=width: 400px; height: 267px; float: left; margin-right: 20px; class=media-element file-wysiwyg data-delta=4 typeof=foaf:Image src=https://www.volacci.com/sites/default/files/1610_Speed_Mobile_Blog.jpg /3. Optimize your website to work with different devices and browsers./h3 pYou can no longer only optimize speed for desktops. With a href=http://www.comscore.com/Insights/Blog/Major-Mobile-Milestones-in-May-Apps-Now-Drive-Half-of-All-Time-Spent-on-Digital60%/a of online traffic coming from mobile devices, a mobile responsive website is critical. All of the things that you do to speed up your website will help, of course. There are also things that you can do specifically to make your website more responsive for mobile devices. You should make sure that your website is optimized to work with popular mobile browsers. One of the most powerful things you can do is to implement the Google AMP module. We talk in detail about it in our article, a href=https://www.volacci.com/blog/how-marketers-use-drupals-amp-module-improve-google-search-rankingsemHow Marketers Use Drupal's AMP Module/em/a to Improve Google Search Rankings./p h34. Compress your images, CSS and Javascript files./h3 pThe Advanced CSS/JS Aggregation module aggregates and compresses CSS and Javascript files to make your site run faster. Google loves fast websites and this module speeds things up with little overhead./p pDrupal 8 Core has the ability to resize images and serve the right image for any situation. It can scale them, crop them, and much more. Consistent image sizes help reduce the bandwidth required to load a particular web page. This can greatly reduce load time./p h35. Use a Content Distribution Network (CDN) with Drupal 8/h3 pThere are a few third party tools that you can use with Drupal to speed up your website. A CDN stores your website on servers across the globe. CDN companies own data centers on every continent and in every region. Think of it as taking your server cache and making copies of it to servers that are a lot closer to your visitors. If the HTML does not need to be recreated by Drupal, then it is served directly from the CDN, greatly reducing the load times involved./p pExample companies include (my personal favorite) CloudFlare, Level3, Amazon, and Akamai. The CDN module for Drupal is located a href=https://www.drupal.org/project/cdnhere/a. There are also service-specific modules for a href=https://www.drupal.org/project/cloudflareCloudFlare/a andbr /a href=https://www.drupal.org/project/akamaiAkamai/a./p h3img alt=Drupal 8 web hosting equipment title=Choose a Drupal 8 Host That Can Offer Greater Speed height=870 width=1200 style=width: 400px; height: 290px; float: right; class=media-element file-wysiwyg data-delta=5 typeof=foaf:Image src=https://www.volacci.com/sites/default/files/1610_Speed_Hosting_Blog.jpg /6. Choose a host that can offer greater speed/h3 pIf, after implementing some of the tips above, you are still not meeting your performance goals, you should consider choosing a faster host. When you look for hosting, you’ll find many options. At Volacci, we have experience with several dozen hosting companies that promise Drupal support and high speeds. In order of most capable to least capable (with considerable overlap in performance and cost), here is a list of the types of hosting you may want to consider:/p h4Managed Dedicated Server(s)/h4 pA managed dedicated server takes care of all your hosting needs for you. Not only do you get the hardware but you get a team of experts to make sure everything is running as it should. They will keep your software up-to-date and alert you if there are any problems – often after they’ve already been fixed. You can deploy multiple servers in many configurations. For example, a firewall, caching server, database server or multiple http servers could all be part of a larger solution. It’s fast and reliable hosting. Adding multiple servers or getting help designing the perfect configuration for you is part of the service. a href=https://www.blackmesh.com/Blackmesh/a (my personal favorite) is the Drupal-specific company for this kind of hosting. Also consider a href=https://www.rackspace.com/Rackspace/a./p h4Dedicated Server(s)/h4 pA dedicated server provides low latency which means a fast response time for most small to medium-sized sites. Consider that you need to provide technical staff to manage the hardware and software stack. Examples include a href=http://www.hostgator.com/dedicated-serverHostGator/a and a href=http://lp.viawest.com/DrupalSolutions.htmlViawest/a./p h4Cloud Hosting/h4 pCloud hosting is scalable. The “cloud” means that there is a data center with lots of dormant servers. As your site’s needs scale up (or down) the servers in the data center respond with more server power. While it may be a panacea for some, latency and cost are critical concerns. Examples include a href=https://www.acquia.com/freeAcquia Cloud/a, a href=https://pantheon.io/Pantheon/a, and a href=https://platform.sh/Platform.sh/a./p h4Virtual Private Server (VPS) / Server Slice/h4 pA VPS offers a good balance between cost and performance. It’s similar to shared hosting in that you share a single server with other tenants. However, you get a guaranteed amount of performance on that server. Maybe 10% (or more) dedicated to you which preserves your performance. Examples include a href=https://www.hotdrupal.com/drupal-vps-plansHotDrupal/a and a href=https://www.orangewebsite.com/vps.phpGreen VPS/a./p h4Shared Hosting/h4 pShared hosting is the rookie league of hosting. Your site sits on a server with many other tenants. It’s slow and not scalable but it’s inexpensive. Examples include a href=https://www.bluehost.com/Bluehost/a and a href=https://www.siteground.com/SiteGround/a./p h2Learn More with Drupal 8 SEO/h2 pIf you would like specific details on how to speed up your Drupal 8 website and optimize it for higher Google rankings, take a look at a href=https://www.drupal8seo.com/emDrupal 8 SEO/em/a. This book is the definitive authority on SEO for Drupal 8 websites. a href=http://www.drupal8seo.comCheck it out./a/p pa href=https://www.volacci.com/contactContact Volacci /aif you would like our Drupal SEO experts to create a plan and implement best practices that will maximize your website performance and a href=https://www.volacci.com/drupal-marketing-solutions/drupal-seoimprove Drupal SEO/a./p /div/div/divdiv class=field field--name-field-image field--type-image field--label-hiddendiv class=field-itemsdiv class=field-item even rel=schema:image resource=https://www.volacci.com/sites/default/files/styles/blog_main_image/public/blog/image/1610_Speed_Feature_FB.jpg?itok=NIYtIg3Nimg typeof=foaf:Image src=https://www.volacci.com/sites/default/files/styles/blog_main_image/public/blog/image/1610_Speed_Feature_FB.jpg?itok=NIYtIg3N width=1024 height=596 alt=Cheetah Racing Across Open Grass title=Faster Drupal 8 Website Brings Big Benefits //div/div/divdiv class=field field--name-field-subtitle field--type-text field--label-hiddendiv class=field-itemsdiv class=field-item even property=schema:alternativeHeadlineSurprising Marketing Benefits of Increased Web Page Loading Speed/div/div/divdiv class=field field--name-field-terms field--type-taxonomy-term-reference field--label-hiddendiv class=field-itemsa href=/drupal-8 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal 8/a, a href=/drupal-websites typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal websites/a, a href=/planet-drupal-teasers typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Planet Drupal/a/div/divspan rel=schema:url resource=/blog/how-improve-drupal-8-website-performance class=rdf-meta element-hidden/spanspan property=schema:name content=How to Improve Drupal 8 Website Performance class=rdf-meta element-hidden/span

Aten Design Group: Testing for the Brave and True: Part One

Tue, 05/09/2017 - 17:16
img src=https://atendesigngroup.com/sites/default/files/drupal-8-php-testing-for-brave-true-one.png width=1000 height=600 alt= /pThis is the second part of a series of blog posts about automated testing for Drupal. Its mission is to take you from zero testing experience to confidence in testing your custom Drupal work, from the ground up. Last time, in ema href=https://atendesigngroup.com/blog/testing-brave-and-true-part-zeroTesting for the Brave and True: Part Zero/a/em we defined exactly what automated testing is and discussed some of the common vocabulary of testing. It also introduced the two primary tools used by the Drupal community to test their work, PHPUnit and Behat./p h2Why Automated Testing Will Save You Time and Treasure/h2 pNow that we know a little about what automated testing is, I'm going to make the case that it can be a net positive to your everyday workflow and actually make you a better programmer./p h3Everybody Tests/h3 pIf you came to this blog post with the idea that you've never done any testing or that you've tried to test and didn't succeed, you'd be wrong. Every developer tests their code. Some developers just throw that work away./p pConsider what you're doing every time you clear cache and go refresh your browser. You're testing your work. You've made some change to your code and now you're asserting that your work functions as you expect. Perhaps you put a span class=geshifiltercode class=text geshifilter-textdpm()/code/span or span class=geshifiltercode class=text geshifilter-textkint()/code/span in your new code to inspect some part of your code or a variable, or maybe you're using XDebug (if not, I'd encourage you to start) to step through your code. This process emis/em testing./p pWhile these eminformal/em tests can be incredibly valuable, you can't commit them; you can't run them the next day and you cannot run all the tests you've ever written with just one command. Writing automated tests is simply writing code that can do some of that testing for you. It's making those informal tests you already do, explicit and emformalized/em./p h3Context, context, context/h3 pWhenever you write code to do specific things, you make assumptions. Assumptions are the foundation of abstraction and abstraction is the foundation of progress. You can't write code that does anything useful without making assumptions. Especially in Drupal. Entities themselves are an abstraction writ large. But, wrong or hidden assumptions are also the root of most bugs./p pTherefore, when we write code, we ought to be very aware of the assumptions we make. We ought to record those assumptions in some way, for future maintainers or simply to help us remember that we made them in the first place. Unfortunately, when we only do informal testing, we bake our wrong assumptions into our code without leaving a record of them. We can't re-assert our assumptions later without digging through code or comments or taking the time to figure out what something was actually supposed to do./p pThis is the first place where formal tests can be a boon to you, future you, and your successors. The act of writing formal, automated tests by its very nature is recording your assumptions for posterity. When you return to your code an hour, day, week, or year later, all the assumptions you made can be tested again. If you have a strange if/else in your code because of some edge case you discovered when you were doing your initial development, a test can ensure that that code isn't deleted when you're cleaning up or refactoring later (at least without explicitly deleting the test)./p pIn short, you make your assumptions explicit. This reduces the cognitive burden of getting back up to speed whenever you need to come back to some piece of code./p h3Confidence/h3 pThis is where I first really fell in love with testing. Having formal tests for the code I was working with gave me confidence as I made changes. That can sound strange to someone who's never tested before. It sounded strange to me, too./p pThe confidence I'm talking about is not the confidence I have in my abilities (Lord knows I could learn a little more about being humble), it's my confidence in the codebase itself and the relative safety I have when I incorporate a change./p pIf you've ever been in an old, large, legacy codebase, you might recognize that feeling of mild anxiety when you've made a change and there's just no feasible way to know if you've broken something else in some obscure place of the beast. The only thing you can do is click around and cross your fingers. This is where a well-tested codebase can create real confidence. Having a suite of automated tests means I can isolate my changes and then run emall/em the tests ever written for that codebase and ensure that my changes haven't broken emsomething/em, emsomewhere/em./p h3Better tests, better code/h3 pIf you've been interested in the art of programming itself (and I think you must be to be reading this), then you might have heard of the SOLID design principles. Or, at least, things like write small functions and do one thing and one thing well. Maybe you've heard about dependency injection, separation of concerns, or encapsulation. All these words are names for the concepts that, when applied to the way we write code, make the likelihood of our code being robust, flexible, extensible, and maintainable (all good things, right?) go up./p pThe art and practice of testing itself can help you apply all of these concepts to your code. If you recall the term unit testing a href=/blog/testing-brave-and-true-part-zerofrom the last post in this series/a, I said, [unit] tests isolate very small bits of functionality. The process of identifying the one small thing that your code achieves in order to test it, helps you apply the Single Responsibility Principle. Put another way, when your tests become large and unwieldy, they're saying to you, this code does too much and it should be refactored./p pWhen you're testing code that has dependencies on other code or configuration, like access to the database, another service, or some credentials, it can become difficult to write useful tests. For example, if you're writing code that runs an entity query and you'd like to test how the code works when there are no results, five results or 500 results, you would have a hard time doing so with a real entity query and database connection. This is where inversion of dependencies or dependency injection come into play. Instead of running an entity query and doing processing on the results all in one function or within a single class, pass the entity query or its results eminto/em the function, method or class. This allows you to test the function with fake results, which you can then set up in your test (we'll go over the methods for doing exactly that in a later part of this series)./p pThat inability to test code with implicit dependencies is a good thingtrade;mdash;it emforces/em you to do dependency injection, whereas it's simply a ritual that you have to practice without tests (I should note, the reason inversion of dependencies is a good thingtrade; is because it makes your code modular and helps ensure it only does one thing well)./p h3What's next?/h3 pI hope I've made a convincing case that writing automated tests for Drupal can save you time and treasure. In the next part of this series, we're going to begin our descent into the art of testing itself. We'll go over writing our first unit test and getting it running on the command line. Until then, feel free to comment or tweet @gabesullice if you've got questions!/p

Code Positive: Atomic Design

Tue, 05/09/2017 - 14:00
a href=http://www.codepositive.com/articles/atomic-designimg src=http://www.codepositive.com/sites/default/files/styles/rss_banner/public/2017-05/building-blocks-1563961_1920.jpg?itok=9SQoSWsn width=940 height=230 alt=Atomic Design building blocks title=Atomic Design typeof=Image class=image-style-rss-banner //a pThe main idea behind Atomic Design is to think about components in their smallest, simplest elements (such as a menu item or a search button) first and building up from there - to design from element upwards rather than starting with page level wireframes./p pa href=http://www.codepositive.com/articles/atomic-designREAD MORE/a/p p /p

Agiledrop.com Blog: AGILEDROP: Case Studies on DrupalCon Baltimore

Tue, 05/09/2017 - 07:44
a href=http://www.agiledrop.com/blog/case-studies-drupalcon-baltimoreimg src=https://www.agiledrop.com/sites/default/files/2017-05/books-2241635_640.jpg //a There was an enormous amount of sessions in the past DrupalCon. They are available online. But to make things easier for you, we'll simply group them together and add a little overview, so you'll easily pick the ones that you like. We'll start with case studies on DrupalCon Baltimore.   Building NBA.com on Drupal 8 by Tobby Hagler from Phase2 and Josh Mullikin from Turner A session gives an overview of NBA.com, the reasons why Drupal 8 was chosen for the 2016-2017 season and how Drupal 8 interacts with other systems and stack components. Attendees learned what worked, what they should… a href=http://www.agiledrop.com/blog/case-studies-drupalcon-baltimoreREAD MORE/a

Dries Buytaert: 7-Eleven using Drupal

Tue, 05/09/2017 - 03:23
p7-Eleven is the largest convenience store chain in the world with 60,000 locations around the globe. That is more than any other retailer or food service provider. In conjunction with the release of its updated a href=https://www.7-eleven.com/7rewards/7-Rewards program/a, 7-Eleven also relaunched its website and mobile application using Drupal 8! Check it out at a href=https://www.7-eleven.comhttps://www.7-eleven.com/a, and grab a Slurpee while you're at it!/p figure class=figurediv class=img style=border: 1px solid #ccc; display: inline-block img src=http://buytaert.net/files/cache/drupal/7-eleven-742x1114.jpg style=display:block alt= //div /figure

Cocomore: Recap: Drupal Camp 2017 in Frankfurt

Tue, 05/09/2017 - 00:00
pAt this year's DrupalCamp in Frankfurt, we have not only been excited participants, but as part of the organization team we have also been responsible for the smooth running of the event, the coordination on site and the planning before the actual event took place. In this blog article our colleague Ela summarized which tasks we have undertaken and which topics have been on this weekend's Drupal agenda./p

Promet Source: Drupal Training Course Announcement: Drupal 8 Developer Immersion, Learn Drupal 7 Confirmed for May, June

Mon, 05/08/2017 - 23:18
If your development team is ready to dive into Drupal 8 or Drupal 7 best practices, take note!  Promet Training has confirmed course dates coming up in May and June for our Drupal 8 Developer Immersion and Learn Drupal 7 courses, both in person and live online.

Mike Crittenden: Grav CMS for Drupal developers

Mon, 05/08/2017 - 23:13
span property=schema:nameGrav CMS for Drupal developers/span div property=schema:textpIf you've never heard of it, Grav is a pretty neat little flat-file CMS. If you're a Drupal developer, words like flat-file and neat and little are probably foreign to you. This post is an attempt to explain what Grav is, why it's neat, and how to use it, in terms that you'll understand./p h2First of all, where is the database?/h2 pAs a Drupal developer, you live and die by the database. You've probably worked on sites that have had many hundreds of database tables. You might even remember the first time you realized that each field gets 2 database tables of its own./p pThe first thing you should understand about Grav is that there is no database. In place of it, there are 2 types of things:/p p- YAML files which hold configuration/p p- Markdown files which hold content/p pThat's it. If you want to make a change to config, you change it in the relevant YAML file. If you want to update a page, you change it in the relevant Markdown file./p h2Oh, so it's a static site generator like Jekyll? No!/h2 pSo far it may sound like a static site generator, but it's not. It's a CMS. This means that it can still do all the same types of things other CMS'es can do, that aren't available to static site generators./p pFor example, there's a really nice admin plugin that lets editors edit content via a UI, and upon saving, the content is instantly updated on the site (rather than the site needing to be re-built). Some static site generators have UI's, but they still require the intermediary site-generation step after making an edit./p pYou can also still have dynamic content listings, send emails, redirect users, integrate with web services, display user-facing forms, etc., since Grav is built with PHP and is super duper alterable via custom plugins. You'd need to handle that stuff client-side with a static site generator./p h2Content types in Drupal = Page Types in Grav/h2 pLet's start with the basics - the age old content type. In Drupal, creating a content type happens in the UI./p pIn Grav, to create a content type, you just create a “whatever.html.twig” file in the templates/ directory of your theme. Doing that automatically tells Grav that “Whatever” should be a new Page type./p pThis means that when creating a page in the UI, you can choose the “Whatever” page type. Or, if you’re creating content via adding a Markdown file directly, just name the file whatever.md which tells Grav that it’s a “Whatever” type of page./p pa href=https://learn.getgrav.org/themes/theme-basics#content-pages-twig-templatesRead the docs on this/a./p h2Custom fields in Drupal = Blueprints in Grav/h2 pIn Drupal, creating custom fields happens in the UI./p pIn Grav, to create custom fields for a given page type, you’ll do it in a YAML file. Grav calls this a “Blueprint”. Just create a file in /user/blueprints/pages/PAGETYPE.yaml and throw in something like this:/p pre title: PAGETYPE '@extends': type: default context: blueprints://pages form: fields: tabs: fields: content: fields: header.heading: type: text label: Heading header.subheading: type: text label: Subheading /pre pBasically, that will add two new text fields (“Heading” and “Subheading”) to the “Content” tab of the form for that page type./p pWhen you save that form, it’ll throw that data into a little YAML block at the top of the Markdown file that stores the content of that page. This is called a href=https://learn.getgrav.org/content/headersFrontmatter or Headers/a and is actually really really cool because it means that the sky is basically the limit in terms of how to store structured data. You can store it in any way that YAML supports./p pThen, in the Twig template (we’ll get to templates later), you can output the data for those custom fields using code{{ header.heading }}/code or code{{ header.subheading }}/code./p pa href=https://learn.getgrav.org/forms/blueprints/example-page-blueprintRead the docs on this./a/p h2Views in Drupal = Page Collections in Grav/h2 pIn Drupal, creating a content listing happens (usually) in the Views UI./p pIn Grav, there’s the concept of a “Collection” which allows you to loop through and list arbitrary content. Here’s an example:/p pre content: items: @self.children order: by: date dir: desc limit: 10 pagination: true /pre pAnd then in the Twig template, you’d just loop through them like so:/p pre {% for p in page.collection %} h2{{ p.title }}/h2 {{ p.summary }} {% endfor %} /pre pCollections support lots of the same filtering/sorting/pagination concepts that Views supports. Some of the more complex stuff (such as fields from relationships or exposed filters) would have to be custom built via a plugin, but this should handle most of the things you’d typically use Views for pretty well./p pa href=https://learn.getgrav.org/content/collectionsRead the docs on this/a./p h2Taxonomy in Drupal = Taxonomy in Grav/h2 pYep, it’s even named the same thing for you./p pIn Drupal, creating a Taxonomy happens in the blah blah blah you get the idea. All of this stuff is done in the UI in Drupal./p pIn Grav, creating a Taxonomy just means adding it to your site.yaml config file, like so:/p pre taxonomies: [category,tag]/pre pJust add it to that array and you’ve created a new taxonomy. Then, you can reference it from any given page like this, in the YAML Frontmatter:/p pre title: Post title taxonomy: tag: [animal, dog] category: pets /pre pAnd that’s it. Taxonomies are MUCH simpler in Grav than in Drupal. They aren’t fieldable, for example (without some customization). They’re basically just a way to group content together, so that you can create listings (“Collections”) out of them./p pa href=https://learn.getgrav.org/content/taxonomyRead the docs on this/a./p h2Configuration/CMI/Features in Drupal = YAML files in Grav/h2 pIn Drupal, configuration is stored in the database. Drupal 8 provides core with the ability to sync this configuration with YAML in the filesystem, but the source of truth is the database./p pThis means that if you want to push some new configuration some site A to site B, you have to make the change in the UI, export it to YAML, move that YAML to the other site (via a git push or some other mechanism), and import it on the other site to make it live. People usually use Drush or Features to help with this process./p pIn Grav, the source of truth for configuration is the YAML itself, since there’s no database. To change configuration, just change the YAML file, and Grav will immediately recognize that. To move that change to another site, just git push/pull it and it’s live./p pa href=https://learn.getgrav.org/basics/grav-configurationRead the docs on this/a./p h2Install profiles/distributions in Drupal = Skeletons in Grav/h2 pThis is one area where Grav really shines./p pIn Drupal, shipping a distribution mostly involves doing work to make sure that a site has everything it need in code and exported configuration, and installs correctly using the installer. This is a result of Drupal relying on a database, but not wanting to ship an exported copy of that database with the distribution./p pIn Grav, since there’s no database, a “distribution” (or a Skeleton in Grav-speak) is basically just a copy of the codebase. Grav has no notion of installation like Drupal's installer. Just copy the codebase to another web root somewhere and it’s ready to run. This means that it’s really easy to ship open source Skeletons, many of which are a href=https://getgrav.org/downloads/skeletonsavailable here/a./p p(It’s a tiny bit more nuanced than that since all you really need is the /user directory of the codebase which is where all the custom code is stored, but you get the idea)./p pa href=https://learn.getgrav.org/advanced/grav-development#grav-skeletonsRead the docs on this/a./p h2Drush in Drupal = CLI tools in Grav/h2 pDrush has saved the butt of many a Drupal developer. These days, Drupal Console is doing pretty well for itself too, but it’s the same basic idea. Talking to your site via the CLI is useful./p pGrav has a couple built in CLI tools for many of the same purposes:/p ullia href=https://learn.getgrav.org/cli-console/grav-clibin/grav/a: performs basic site tasks such as clearing cache, making backups, installing dependencies, or creating new projects/li lia href=https://learn.getgrav.org/cli-console/grav-cli-pluginbin/plugin/a: performans commands provided by plugins (instead of Grav core), such as creating new users via the admin plugin/li lia href=https://learn.getgrav.org/cli-console/grav-cli-gpmbin/gpm/a: (“Grav Package Manager”) - performs tasks you would expect of a package manager, such as listing, downloading, and updating plugins/li /ulh2Other random stuff/h2 pHere’s some other stuff that didn’t really deserve its own section. Feel free to read up on the docs on these if you’re curious./p ulliCSS/JS aggregation in Drupal = a href=https://learn.getgrav.org/themes/asset-managerAsset Manager (“Pipelining”) in Grav/a/li liImage styles in Drupal = a href=https://learn.getgrav.org/content/media#image-actionsImage Actions in Grav/a/li liWebform in Drupal = a href=https://learn.getgrav.org/forms/formsform.md files in Grav/a/li liCaching in Drupal = a href=https://learn.getgrav.org/advanced/performance-and-cachingCaching in Grav/a/li liBase Themes in Drupal = a href=https://learn.getgrav.org/themes/customization#theme-inheritanceBase Themes in Grav/a/li liPer-environment settings in Drupal = a href=https://learn.getgrav.org/advanced/environment-configEnvironment Configuration in Grav/a/li liMultisite in Drupal = a href=https://learn.getgrav.org/advanced/multisite-setupMultisite in Grav/a/li /ulh2Shortcomings and Downsides/h2 pThere are a few things to keep in mind if you’re looking at using Grav for a project instead of Drupal./p pOne is that Grav doesn’t scale nearly as well. Many Drupal sites have many millions of nodes, thanks to the usage of a database. In general, I probably wouldn’t suggest using Grav once you start getting into the thousands with page count. Performance will likely start to suffer./p pDrupal also really shines in creating complex content models, where there are many types of nodes/entities which reference each other or embed each other or reuse each other's fields, etc. Grav is perhaps more page focused than data focused, which makes it much easier to work with for many sites, but not a great fit for some sites that need those complex relationships./p pGrav also doesn’t really have the notion of an editorial workflow or moderation system. It does support published vs. unpublished, and there are things like a href=https://getgrav.org/blog/git-sync-pluginGit Sync/a to auto-deploy from a staging environment (or your local site) to a production environment if you set it up to do so, but there’s no approval process along the lines of what Drupal and some modules can provide./p pAlso, Grav doesn’t have anything to match the Paragraphs module, which allows you to build content by placing arbitrary “slices” in an arbitrary order. It does have a “List” field type which allows you to add as many “field groups” as you want, but each group must have the same set of fields. So you can’t, for example, add a text slice, then a video slice, then an image slice, then another text slice, etc./p pObviously, Grav also isn’t going to have anywhere near the amount of 3rd party plugins (modules) that Drupal has. Things like integration with web services or commonly used libraries will have to be hooked up yourself, more often than not. That said, the API is solid and the a href=https://learn.getgrav.org/api/documentation for it/a is legit./p pThat’s by no means an exhaustive list, but it's about all I’ve found so far. For your typical small to medium sized sites, Grav can be a really great solution that cuts out some of the overhead of a typical Drupal site. Recommended!/p /div span rel=schema:authorspan lang= about=http://mikecr.it/user/1 typeof=schema:Person property=schema:name datatype= xml:lang=mcrittenden/span/span span property=schema:dateCreated content=2017-05-08T21:13:28+00:00Mon, 05/08/2017 - 17:13/span

Drupal Modules: The One Percent: Drupal Modules: The One Percent — A Simple Timeline (video tutorial)

Mon, 05/08/2017 - 20:02
span class=field field--name-title field--type-string field--label-hiddenDrupal Modules: The One Percent — A Simple Timeline (video tutorial)/span div class=field field--name-field-screenshot field--type-image field--label-hidden field__item img src=http://gogrow.org/sites/default/files/styles/large/public/2017-05/simple_timeline.png?itok=lWnKQvWH width=480 height=227 alt=Project page screenshot typeof=foaf:Image class=image-style-large //div span class=field field--name-uid field--type-entity-reference field--label-hiddenspan lang= about=http://gogrow.org/user/24 typeof=schema:Person property=schema:name datatype= xml:lang=NonProfit/span/span span class=field field--name-created field--type-created field--label-hiddenMon, 05/08/2017 - 13:02/span div class=field field--name-field-episode field--type-integer field--label-inline div class=field__labelEpisode/div div class=field__item27/div /div div class=clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__itempHere is where we bring awareness to Drupal modules running on less than 1% of reporting sites. Today we'll consider A Simple Timeline, a module which renders the results of a View in a vertical timeline./p/div

Agaric Collective: Avoid sending emails while doing a migration on Drupal 8

Mon, 05/08/2017 - 18:34
pOn a migration, Drupal read from an external source the data and create content in our new Drupal Site, and while do that Drupal execute any hook/event related to the new content. So any hook_entity_insert is triggered for every new entity saved on our new site./p pThis can be a problem if we have some features in our new site which are executed when a new content is created (like send a tweet or send an email) when we run the migration we will have a ton of emails or tweets of the old content and usually, that is not the expected behavior. /p pFortunately, in Drupal 8 the migrations are Events and we can create an EventSubscriber (a href=https://www.chapterthree.com/blog/how-to-register-event-subscriber-drupal8more about EventSubscribers here/a) which will allow us to create a flag before the migration run so we can determine in our code if the entity has been created in a migration or not./p pThe main idea was taken from this a href=https://www.drupal.org/u/moshe-weitzmanMoshe Weitzman gist/a (Thanks!) I will add just the missing parts./p pFirst, we generate all the event subscriber related files using this Drupal Console command:/p pre class=brush: bash drupal generate:event:subscriber /prep The console will ask some question (in which module we want to generate the EventSubscriber and the name of the service)/p pre class=brush: bash Enter the module name [config_log]: gt; your_module Enter the service name [simple_faq.default]: gt; migration_events.subscriber Class name [DefaultSubscriber]: gt; MigrationEvents Enter event name [ ]: gt; Do you want to load services from the container (yes/no) [no]: gt; no Do you confirm generation? (yes/no) [yes]: gt;yes /prep This will generate two files:/p pre modules/custom/your_module/your_module.services.yml /prep Which basically let drupal know that we have a Subscriber there which needs to be executed and:/p pre modules/custom/your_module/src/EventSubscriber/MigrationEvents.php /prep With this content:/p pre class=brush: php namespace Drupal\simple_faq\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\Event; /** * Class MigrationEvents. * * @package Drupal\simple_faq */ class MigrationEvents implements EventSubscriberInterface { /** * Constructs a new MigrationEvents object. */ public function __construct() { } /** * {@inheritdoc} */ static function getSubscribedEvents() { return $events; } } /prep On this file we need to add our flag which will indicate drupal that we are running the migration. First, we need to import the Migrate events:/p pre class=brush: php use Drupal\migrate\Event\MigrateImportEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Drupal\migrate\Event\MigrateEvents; /prep and After add our methods: /p pre class=brush: php protected $staticCache; public function __construct() { $this-gt;staticCache = amp;drupal_static(your_migration); } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ MigrateEvents::PRE_IMPORT =gt; 'onMigratePreImport', MigrateEvents::POST_IMPORT =gt; 'onMigratePostImport', ]; } /** * @param \Drupal\migrate\Event\MigrateImportEvent $event * Import Event. */ public function onMigratePostImport(MigrateImportEvent $event) { if ($event-gt;getMigration()-gt;getBaseId() == your_migration) { $this-gt;staticCache = FALSE; } } /** * @param \Drupal\migrate\Event\MigrateImportEvent $event * Import Event. */ public function onMigratePreImport(MigrateImportEvent $event) { if ($event-gt;getMigration()-gt;getBaseId() == your_migration) { $this-gt;staticCache = TRUE; } } /prep And that's it, now we have a flag which we can use to determine if we are running the migration or not, the complete class look like this:/p pre class=brush: php namespace Drupal\your_module\EventSubscriber; use Drupal\migrate\Event\MigrateImportEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Drupal\migrate\Event\MigrateEvents; /** * Event subscriber to avoid sending emails/tweets/facebook posts on migrations. */ class MigrationEvents implements EventSubscriberInterface { /** * The drupal_static cache. * * @var array */ protected $staticCache; /** * CommentEventSubscriber constructor. */ public function __construct() { $this-gt;staticCache = amp;drupal_static(your_migration); } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ MigrateEvents::PRE_IMPORT =gt; 'onMigratePreImport', MigrateEvents::POST_IMPORT =gt; 'onMigratePostImport', ]; } /** * @param \Drupal\migrate\Event\MigrateImportEvent $event * Import Event. */ public function onMigratePostImport(MigrateImportEvent $event) { if ($event-gt;getMigration()-gt;getBaseId() == your_migration) { $this-gt;staticCache = FALSE; } } /** * @param \Drupal\migrate\Event\MigrateImportEvent $event * Import Event. */ public function onMigratePreImport(MigrateImportEvent $event) { if ($event-gt;getMigration()-gt;getBaseId() == your_migration) { $this-gt;staticCache = TRUE; } } } /prep And finally, We now can use this variable to determine if we should send that email when creating a new entity, for instance:/p pre class=brush: php /** * Implements hook_node_insert(). */ function yourmodule_node_insert($entity) { // If the migration is running, just return without doing anything. if (drupal_static('your_migration', FALSE)) { return; } // All your code for send emails/tweets here. // . . . } /prepAnd that's it. /p pHere we used drupal_static to preserve the value through the execution of the migration if you want to read more about it check a href=https://api.drupal.org/api/drupal/core%21includes%21bootstrap.inc/function/drupal_static/8.2.xhere/a/p

Dale McGladdery: H5P - Portable Interactive Content in Drupal

Mon, 05/08/2017 - 18:24
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpimg alt=H5P class=feature-right src=http://www.group42.ca/files/h5p-logo.jpeg style=width: 295px; height: 137px; /H5P is an open source platform-independent authoring and display system for interactive content. Presentations, quizzes, and other interactive content can be created and displayed using building blocks known as H5P content types (different from Drupal content types). Once a piece of content is created it's easily exported to another H5P system. The development environment is open and well documented, allowing the creation of custom H5P content types./p !--break-- pH5P attributes include:/p ulliAvailable in Drupal 7, WordPress, and Moodle/li liOpen Source/li liContent is exportable to any other H5P system/li liUses JavaScript and HTML 5/li liResults tracking for content types such as quizzes/li lia href=https://en.wikipedia.org/wiki/Experience_API target=_blankxAPI (Tin Can)/a integration/li liDrupal 7 hook system integration/li liDrupal development environment/li /ulpUnfortunately there is no Drupal 8 version yet./p pThere are a variety of H5P content types, including containers such as accordions and sliders which can nest other content types. Some examples are:/p ulliArithmetic Quiz/li liCourse Presentation/li liDialog Cards/li liDrag the Words/li liFill in the Blanks/li liTimeline/li liInteractive Video/li /ulpThe complete list is at a href=https://h5p.org/content-types-and-applications target=_blankhttps://h5p.org/content-types-and-applications/a/p pH5P defines a file packaging format named the .h5p specification, or simply, H5P file. An H5P file is a zip archive bundling HTML, JSON, JavaScript, and media files. It can contain one or more of a content type, content export, API implementation, application, or JavaScript library./p h3Drupal Integration/h3 pH5P is installed in Drupal in two steps./p olliDrupal H5P modulebr / The H5P module is installed using the standard module installation process. It handles the Drupal integration./li liH5P Content Types and support filesbr / H5P content types and the files to support them are installed into a H5P Library manager provided by the H5P module. An H5P archive file of the content types and other support libraries is downloaded from the H5P site and uploaded into the Drupal H5P library./li /olp style=text-align: center;img alt=H5P Content Library src=http://www.group42.ca/files/H5P-Library.png style=width: 500px; height: 357px; /br /br /strongScreenshot of H5P Content Library in Drupal/strong/p h3Content Creation/h3 pThe Drupal integration contains a H5P node type named, “Interactive content”. When a H5P node is created there is a selector for the H5P content type. For example, quiz, presentation, or dialog card. When a H5P content type is selected the editor for the content type is loaded interactively. The author then creates the desired content./p p style=text-align: center;img alt=H5P Content Selector src=http://www.group42.ca/files/H5P-content-selector.png style=width: 500px; height: 501px; /br /br /strongScreenshot of H5P content type selector/strongbr /br /  /p p style=text-align: center;img alt=H5P Flashcards content editor src=http://www.group42.ca/files/Flashcard-content-editor.png style=width: 500px; height: 363px; /br /br /strongScreenshot of editor for H5P Flashcards content type/strong/p pOnce saved the content is presented when the node is viewed./p h3H5P Development/h3 pThe H5P project provides a Drupal development environment (including a developer mode), online documentation, and a forum./p pThe various specifications and basics for getting started are well documented, and include a “hello world” example. H5P at its heart is JavaScript with a PHP wrapper for integrating with a website. Someone's ability to learn the framework will depend on their comfort with JavaScript./p pCoding the editor component that creates and edits the content type typically requires as much work as coding the display for the content type. Custom editor widgets can be written. Existing H5P editor widgets can also be used though they are not documented./p pThe H5P Drupal hooks provide a clean method of adding CSS stylesheets and modifying H5P behaviour without modifying the base H5P code. Some tasks are complicated by the asynchronous nature of JavaScript loading and the use of iFrames./p h3Pros and Cons/h3 pH5P is continuously changing and improving. These pros and cons are a snapshot of my experience as of May 2017./p pstrongPros:/strong/p ulliPlug and play interactive content/li liEasy to share content/li liOption for turning off content sharing feature/li liLarge variety of content types/li liOpen source/li liThe H5P team is approachable/li liThere is a good content development environment for Drupal/li liThe content creators I worked with were able to quickly and easily generate content using H5P/li liDrupal hooks available/li /ulpstrongCons:/strong/p ulliDocumentation on some content types is lacking/li liTrial and error is often required to figure out options for some of the sophisticated content types/li liThough some of the content type editors are excellent, some are obtuse or confusing/li liThere is no Drupal 8 version/li liContent creators are endlessly creative, you will have to deal with content types being “close but not exactly what I want”/li liThere isn't a lot of good guidance on developer workflow if you want to contribute back to the project/li liStaff focused on content creation will probably have favoured tools -- for example, Articulate Storyline -- and push back on an unknown tool such as H5P/li /ulh3Further Reading/h3 ulliH5P Project Page: a href=https://h5p.org target=_blankhttps://h5p.org/a/li liDrupal H5P Module: a href=https://www.drupal.org/project/h5p target=_blankhttps://www.drupal.org/project/h5p/a/li liH5P on Twitter: a href=https://twitter.com/h5ptechnology target=_blank@H5PTechnology/a/li liWikipedia: a href=https://en.wikipedia.org/wiki/H5P target=_blankhttps://en.wikipedia.org/wiki/H5P/a/li liArticle on xAPI Integration: a href=https://drupal.psu.edu/blog/post/drupal-xapi-h5p-track-user-feedback target=_blankDrupal + xAPI + H5P to track user feedback/a/li liCase Study of H5P project I worked on: a href=https://h5p.org/node/32651 target=_blankAged Out - Teaching Life Skills to Youth with H5P/a/li /ul/div/div/divdiv class=taxonomy field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-hidden clearfixTagged: ul class=links inlineli class=taxonomy-term-reference-0a href=/topics/drupal_7 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Drupal 7/a/lili class=taxonomy-term-reference-1a href=/topics/h5p typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=H5P/a/lili class=taxonomy-term-reference-2a href=/topics/drupal_planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Planet Drupal/a/li/ul/div

Evolving Web: Drupal 8 Modules You Can't Live Without

Mon, 05/08/2017 - 15:29
a href=https://evolvingweb.ca/blog/drupal-8-modules-you-cant-live-without?utm_source=feedutm_medium=feed_image img src=https://evolvingweb.ca/sites/default/files/styles/ewsite8_blog_image/public/2017-05/iStock-678114614-duplo-compressed.jpg?itok=oxU8WiGl width=720 height=480 alt=Duplo pieces to illustrate modules needed to build a website typeof=Image class=img-responsive //apDrupal 8 does way more out-of-the-box than previous versions of Drupal. If you're migrating your site from Drupal 6 or Drupal 7, you'll be amazed how many contributed modules you can now do without. /p pThat being said, there are still a set of handy contrib modules you'll probably use for most of your projects. This isn't a complete list, just a starting point for anyone new to Drupal 8 looking for a useful set of modules to try. /p h2Admin Toolbar/h2 pThe a href=http://drupal.org/project/admin_toolbarAdmin Toolbar/a gives you a dropdown menu to access the sub-items in the toolbar quickly. This is probably the first module to add to your Drupal 8 site./p pimg alt=Admin toolbar dropdown menu data-entity-type=file data-entity-uuid=ac3e2194-c730-40c6-8cc3-1961d18745d0 src=https://evolvingweb.ca/sites/default/files/inline-images/GUJCGFXM-2017.05.05-14-27-41.png //p h2Pathauto/h2 pa href=http://drupal.org/project/pathautoPathauto/a is the go-to module for automatically generating nice aliases for all your URLs. You get to define the path patterns for any content on your site that has a path (nodes, users, taxonomy terms...) Works in multiple languages. You need to add a href=http://drupal.org/project/tokenToken/a and a href=http://drupal.org/project/ctoolsChaos Tools/a as dependencies./p h2img alt=Screenshot of pathauto pattern editing interface data-entity-type=file data-entity-uuid=dccd50ff-2235-4147-b361-ad165b95f722 src=https://evolvingweb.ca/sites/default/files/inline-images/IABNPIGZ-2017.05.05-14-52-35.png //h2 h2Redirect/h2 pAlong with the Pathauto module, most websites benefit from using a href=http://drupal.org/project/redirectRedirect/a to take users to pages if and when the paths change. /p pimg alt=Screenshot of redirect interface data-entity-type=file data-entity-uuid=d7cefa45-9652-4857-afd5-c491fdc586af src=https://evolvingweb.ca/sites/default/files/inline-images/WLLEQFVY-2017.05.05-14-51-12.png //p h2Paragraphs/h2 pThe a href=http://drupal.org/project/paragraphsParagraphs/a module is a favourite for site builders who want to be able to create flexible content types that use compound fields. Want to add a set of calls to action to a landing page? Or mix together some videos, marketing text, and linked images? Or perhaps you need to add a set of time-slots to an event, or a set of editions to a book? Paragraphs to the rescue. Suddenly adding chunks of content within your content is really easy. You need to add a href=http://drupal.org/project/entity_reference_revisionsEntity Reference Revisions/a as a dependency./p pimg alt=Screenshot of paragraphs editing interface data-entity-type=file data-entity-uuid=8d4a6e88-8ab2-4b64-a511-bcc90f6a4e5d src=https://evolvingweb.ca/sites/default/files/inline-images/JSCDEJBP-2017.05.05-15-29-43.png //p h2Honeypot/h2 pIf your website has spam, a href=http://drupal.org/project/honeypotHoneypot/a is an easy solution that might just fix your spamming issues. It inserts an invisible form element that catches bots that will unknowingly fill it in. /p h2Add to Any/h2 pa href=http://drupal.org/project/addtoanyAdd to any/a is one of a number of options for adding social media links to your content. /p h2Metatag/h2 pNot just for your basic page title and description. a href=http://drupal.org/project/metatagMetatag/a makes sure that your content is going to look good when you share it on Facebook and Twitter too./p pimg alt=Screenshot of Metatag configuration for Drupal 8 data-entity-type=file data-entity-uuid=888912da-62b5-478b-b2b6-bc230b148af4 src=https://evolvingweb.ca/sites/default/files/inline-images/DSTBENBK-2017.05.05-15-10-41_0.png //p h2Menu Trail by Path/h2 pUse a href=http://drupal.org/project/menu_trail_by_pathMenu Trail by Path/a to set the active menu trail for your content based on the URL. For example, when you're looking at a blog post, and you want the blog post menu item to be active./p h2Entity Browser/h2 pOne of the questions I get most often when I show off Drupal 8's shiny new content authoring features is how to re-use images or files across different pieces of content. Start with the a href=http://drupal.org/project/entity_browserEntity Browser/a module (entity is a fancy Drupal word for content and this case usually refers to images, videos, and files). You'll want to try this out with the a href=http://drupal.org/project/file_browserFile Entity Browser/a module. Configure it using the 'Manage Form Display' settings. (Hint: make sure you have all the required libraries installed to get this working.)/p pimg alt=Screenshot of entity browser interface data-entity-type=file data-entity-uuid=83565262-a6c6-4988-8d0f-1e57809ee799 src=https://evolvingweb.ca/sites/default/files/inline-images/LSCSXSSK-2017.05.05-14-37-54.png //p h2Block Visibility Groups/h2 pa href=http://drupal.org/project/block_visibility_groupsBlock Visibility Groups/a allows you to control which blocks are displayed on certain types of pages. For example, you can create a set of blocks that will show up on the homepage, and a different set of blocks on the contact page./p h2img alt=Screenshot of block layout with visibility groups settings data-entity-type=file data-entity-uuid=d66eb8db-ebbe-429a-b659-011319674b7d src=https://evolvingweb.ca/sites/default/files/inline-images/block-visibility-groups.png //h2 h2Diff/h2 pDrupal allows you to track the revisions (or versions) of content each time a user makes an update. The a href=http://drupal.org/project/diffDiff/a module is a tiny module that allows you to see what's changed. /p h2Contact storage/h2 pIf you decide to use the core Contact module, you might notice that contact form submissions get emailed and not saved in the admin UI of the site. If that's something you need, try out the a href=http://drupal.org/project/contact_storageContact Storage/a module. For fancier forms, check out a href=https://www.drupal.org/project/webformWebform/a./p pIf you liked this blog post and want some guidance on how to use these modules, we have a href=https://evolvingweb.ca/training/allDrupal trainings coming up/a online and in-person that you might like./p pThis is the fun part. Now you get to comment and tell me the essential modules I missed. I promise to try them all and do a follow-up blog post with the highlights./p a href=https://evolvingweb.ca/blog/drupal-8-modules-you-cant-live-without?utm_source=feedutm_medium=more target=_blank+ more awesome articles by Evolving Web/a

Web Omelette: Loading taxonomy terms in a tree in Drupal 8

Mon, 05/08/2017 - 08:59
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpOne of the great things about the taxonomy terms in Drupal has always been their hierarchical readiness. That is, how they can easily be organised in a parent-child relationship via a simple drag-and-drop interface. This feature becomes even more important in Drupal 8 where creating entities for anything you want has become easy so we no longer have to (ab)use taxonomy term entities for everything. Unless, of course, we need this kind of behaviour./p pHowever, I recently noticed a shortcoming in the way we are able to load taxonomy terms programatically. I needed to load a tree of terms as represented by their hierarchy. But there is no API (for the moment) that allows me to do so. At least none that I could find./p pWhat I needed was similar to the menu system where if you load a tree, you get an array of codeMenuLinkTreeElement/code objects that wrap the links and which can each contain an array of codeMenuLinkTreeElement/code objects that represent the children (subtree) of that link. So one big multidimensional array of objects./p pFor terms, I imaged there would be something similar, but I was wrong. The codeDrupal\taxonomy\TermStorage::loadTree()/code method basically does half the job I want. It returns all the terms in the vocabulary, each represented as a codestdClass/code object (why?) that contains some basic info. And in this object we get a codeparents/code array that contains the IDs of the terms which are its parents (as you know, terms can have multiple parents)./p pThis may be enough in certain cases. However, I wanted to go one step further. So I created a simple service that loads the tree of a vocabulary in a multidimensional array, similar to what the menu system does:/p pre class=brush: php lt;?php namespace Drupal\taxonomy_tree; use Drupal\Core\Entity\EntityTypeManager; /** * Loads taxonomy terms in a tree */ class TaxonomyTermTree { /** * @var \Drupal\Core\Entity\EntityTypeManager */ protected $entityTypeManager; /** * TaxonomyTermTree constructor. * * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager */ public function __construct(EntityTypeManager $entityTypeManager) { $this-gt;entityTypeManager = $entityTypeManager; } /** * Loads the tree of a vocabulary. * * @param string $vocabulary * Machine name * * @return array */ public function load($vocabulary) { $terms = $this-gt;entityTypeManager-gt;getStorage('taxonomy_term')-gt;loadTree($vocabulary); $tree = []; foreach ($terms as $tree_object) { $this-gt;buildTree($tree, $tree_object, $vocabulary); } return $tree; } /** * Populates a tree array given a taxonomy term tree object. * * @param $tree * @param $object * @param $vocabulary */ protected function buildTree(amp;$tree, $object, $vocabulary) { if ($object-gt;depth != 0) { return; } $tree[$object-gt;tid] = $object; $tree[$object-gt;tid]-gt;children = []; $object_children = amp;$tree[$object-gt;tid]-gt;children; $children = $this-gt;entityTypeManager-gt;getStorage('taxonomy_term')-gt;loadChildren($object-gt;tid); if (!$children) { return; } $child_tree_objects = $this-gt;entityTypeManager-gt;getStorage('taxonomy_term')-gt;loadTree($vocabulary, $object-gt;tid); foreach ($children as $child) { foreach ($child_tree_objects as $child_tree_object) { if ($child_tree_object-gt;tid == $child-gt;id()) { $this-gt;buildTree($object_children, $child_tree_object, $vocabulary); } } } } } /prepNo need to copy it from here, you can find it in a href=https://github.com/upchuk/taxonomy_treethis repository/a inside a simple module called codetaxonomy_tree/code./p pSo what I basically do here is load the default tree and iterate through all the objects. If any of them are not already at the bottom of the tree, I populate a codechildren/code key with their children. This happens by using the codeTermStorage::loadChildren()/code method and recursing through that list as well./p pSo let me know what you think and if this helps you out./p /div/div/div

Promet Source: How to use SOAP to communicate with the ICC API

Fri, 05/05/2017 - 23:02
Promet Source recently worked with a national media provider to develop a website from the ground up that was both a highly optimized web property for converting prospective subscribers and a customer portal that would deliver a flawless user experience for existing customers, customer service representatives (CSRs) and retailers. In this post, we’ll walk through how the Promet Source development team used SOAP (Simple Object Access Protocol) to communicate with the ICC API built for this project. Client Backend Documentation

Chocolate Lily: Authoritarian structure in Drupal: a case study

Fri, 05/05/2017 - 21:37
div class=field field-name-body field-type-text-with-summary field-label-hidden view-mode-rssdiv class=field-itemsdiv class=field-item even property=content:encodedpIn the current context of a Drupal leadership crisis and debate about project governance, it's important to reflect on ways the dictatorship structure has shaped and continues to shape the culture of the project. In this vein, response to a a href=https://www.drupal.org/node/2026382007 post by Drupal contributor Gus Geraghty/a makes for a fascinating, if disturbing, case study./p pI recommend reading (or rereading) that thread before continuing here. I've deliberately chosen an example from earlier days to emphasize how tensions in the project, and patterns of response, have persisted and shaped the project at key junctures. I also hope that some distance may help to set those events in a reflective light, where the focus is not on who did what but on what we can learn about the overall organizational culture./p pThose who raise critical questions are making a valuable contribution. Particularly in an authoritarian structure, speaking up is risky./p pIn his post and followup comments, Geraghty directly questioned the dictatorship power structure of Drupal, focusing on the then-new commercial interests of Drupal founder and dictator for life, Dries Buytaert, and his company, Acquia. Geraghty proposed a concrete alternative: reorganizing the project along cooperative lines. In follow-up comments, he pointed to the a href=https://www.linuxfoundation.orgLinux Foundation/a as a possible model, structured to ensure no one company could attain dominance in the software project:/p blockquotep it fosters the growth of Linux by focusing on protection, standardisation and providing a neutral forum for collaboration and promotion. It also sponsors the work of Linus Torvalds, as opposed to a commercial interest paying Linus. /p/blockquote pThe response was immediate, pointed, and overwhelming./p /div/div/div

Drupal Association blog: The Process for Evolving Community Governance

Fri, 05/05/2017 - 20:59
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenh2 id=docs-internal-guid-eb5401bc-d9fa-d160-0087-aaa1a1eeb4cdstrongDiscover gt; Plan gt; Build gt; Iterate/strong/h2 pThere comes a time when we must all recognize that what got us here won't get us there. Now is that time for Drupal. The governance models that were put in place to support the needs of the community years ago are no longer working as well as they should. The Drupal community has reached a level of maturity that requires greater clarity, integrity, and resilience./p pAn effort is underway to evolve Drupal’s a href=https://www.drupal.org/blog/supporting-the-next-evolution-of-drupals-community-governance rel=nofollowcommunity governance/a. The Drupal community is in the driver’s seat. The Drupal Association is helping navigate and get the community where it wants to go by providing the structure, support, and resources that are desperately needed to make progress. I, Whitney Hess, have been engaged to be a neutral facilitator of this process./p pWe are proposing a multi-phase approach to redesign Drupal’s community governance models, management, and decision-making practices: Discover gt; Plan gt; Build gt; Iterate. In this first phase, our goal is to gain a deeper understanding of the needs of the Drupal community. We are conducting this research through a variety of methods: one-on-one interviews with select individuals; mediated group discussions; surveys and feedback forms./p pWe held seven hour-long Community Discussions over three days of DrupalCon. There were 6-10 participants per session. Though every session had its own energy and topics varied, all discussions were fruitful and impactful. Many participants said they left feeling better than when they arrived./p pWhile there was some discussion about recent events in the sessions, the focus quickly shifted to brainstorming ideas for how to improve Drupal’s community governance. As mediator, it is my role to help people articulate their needs, and to support the community in devising strategies to better get those needs met. Please read the a href=https://www.drupal.org/community/discussions rel=nofollowmeeting summaries/a if you would like to get a sense of what was discussed./p pThere are currently a href=https://events.drupal.org/virtual/community-discussions rel=nofollowseven online sessions/a scheduled over the next two weeks at a variety of times for the global community to participate in these facilitated discussions, and more will be scheduled if needed. If you want your voice heard, I strongly encourage you to join us. If you have questions or concerns about the sessions, you’re welcome to contact me directly at a href=mailto:whitney@whitneyhess.com rel=nofollowwhitney@whitneyhess.com/a./p pOnce these sessions are completed, we will be conducting a short survey and other types of feedback forms to have the widest possible reach. We want to ensure that people have a variety of ways to constructively contribute to making Drupal the best it can be. We expect to launch these in late-May./p pAt the conclusion of the Discovery phase, we will move into Planning. We are at the earliest stages of conceiving a Governance Summit over 1-2 days in June to take all of the learnings from Discovery, and craft a strategy for specifically how to change Drupal’s community management and governance. As of today, we do not yet have dates, location, or participant information. We are waiting to see what comes out of Discovery before we devise any framework for how this can be achieved effectively and equitably. Again, the Drupal Association’s role here is to be a support, and to create space for the community to decide how it wants its governance to change./p pI have very clearly heard a need for greater transparency into this process and how decisions are being made. I take that responsibility seriously, and will continue to share our progress along the way. Next up, please look out for a summary of our Discovery findings, to be shared in late-May/early-June./p pWith gratitude,/p pWhitney/p/div/div/div

Hook 42: Baltimore DrupalCon - Favorites From Charm City

Fri, 05/05/2017 - 20:50
div class=image div class=field-items class=field-items div class=field-item even rel=og:image rdfs:seeAlso resource=http://www.hook42.com/sites/default/files/styles/image_style_blog_list/public/field/image/hook-42-girls-drupalcon-baltimore.jpg?itok=CgwbgJ96 class=field-item evenimg typeof=foaf:Image src=http://www.hook42.com/sites/default/files/styles/image_style_blog_list/public/field/image/hook-42-girls-drupalcon-baltimore.jpg?itok=CgwbgJ96 width=220 height=220 alt=The girls from Hook 42 at DrupalCon Baltimore title=The girls from Hook 42 at DrupalCon Baltimore //div /div /div div class=field field-name-body field-type-text-with-summary field-label-hidden field-wrapper body field div class=field-items class=field-items div class=field-item even property=content:encoded class=field-item evenpEvery year DrupalCon brings the community together. This year we were fortunate enough to have eleven of our team come together in Baltimore! We had a ton of fun while Drupaling and want to share a few of our favorite moments!/p /div /div /div