emGee Software Solutions Custom Database Applications

Share this

Drupal CMS

Issue 420

TheWeeklyDrop - Thu, 01/16/2020 - 01:01
Issue 420 - January, 16th 2020
Categories: Drupal CMS

ADCI Solutions: Why migrate from Drupal 7 to Drupal 8

Drupal.org aggregator - Mon, 01/13/2020 - 18:58

This is the final educational article on Drupal 8 migration

Here we will tackle the topic of migrating from Drupal 7. The love is not gone, but we cannot neglect the fact that Drupal 8 can provide many more benefits for business.

Read Why migrate from Drupal 7 to Drupal 8

 

Categories: Drupal CMS

Dries Buytaert: Acquia retrospective 2019

Drupal.org aggregator - Mon, 01/13/2020 - 18:24

Wow, what a year 2019 was for Acquia!

At the beginning of every year, I like to publish a retrospective to look back and take stock of how far Acquia has come over the past 12 months. I take the time to write these retrospectives because I want to keep a record of the changes we've gone through as a company and how my personal thinking is evolving from year to year.

If you'd like to read my previous retrospectives, they can be found here: 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011, 2010, 2009. This year marks the publishing of my eleventh retrospective. When read together, these posts provide a comprehensive overview of Acquia's growth and trajectory.

Our product strategy remained steady in 2019. We continued to invest heavily in (1) our Web Content Management solutions, while (2) accelerating our move into the broader Digital Experience Platform market. Let's talk about both.

Acquia's continued focus on Web Content Management

In 2019, for the sixth year in a row, Acquia was recognized as a Leader in the Gartner Magic Quadrant for Web Content Management. Our tenure as a top vendor is a strong endorsement for the "Web Content Management in the Cloud" part of our strategy.

We continued to invest heavily in Acquia Cloud in 2019. As a result, Acquia Cloud remains the most secure, scalable and compliant cloud for Drupal. An example and highlight was the successful delivery of Special Counsel Robert Mueller's long-awaited report. According to Federal Computer Week, by 5pm on the day of the report's release, there had already been 587 million site visits, with 247 million happening within the first hour — a 7,000% increase in traffic. I'm proud of Acquia's ability to deliver at a very critical moment.

Time-to-value and costs are big drivers for our customers; people don't want to spend a lot of time installing, building or upgrading their websites. Throughout 2019, this trend has been the primary driver for our investments in Acquia Cloud and Drupal.

  • We have more than 15 employees who contribute to Drupal full-time; the majority of them focused on making Drupal easier to use and maintain. As a result of that, Acquia remained the largest contributor to Drupal in 2019.
  • In September, we announced that Acquia acquired Cohesion, a Software-as-a-Service visual Drupal website builder. Cohesion empowers marketers, content authors and designers to build Drupal websites faster and cheaper than ever before.
  • We launched a multitude of new features for Acquia Cloud which enabled our customers to make their sites faster and more secure. To make our customer's sites faster, we added a free CDN for all Cloud customers. All our customers also got a New Relic Pro subscription for application performance management (APM). We released Acquia Cloud API v2 with double the number of endpoints to maximize customer productivity, added single-sign on capabilities, obtained FIPS compliance, and much more.
  • We rolled out many "under the hood" improvements; for example, thanks to various infrastructure improvements our customers' sites saw performance improvements anywhere from 30% to 60% at no cost to them.
  • Making Acquia Cloud easier to buy and use by enhancing our self-service capabilities has been a major focus throughout all of 2019. The fruits of these efforts will start to become more publicly visible in 2020. I'm excited to share more with you in future blog posts.

At the end of 2019, Gartner announced it is ending their Magic Quadrant for Web Content Management. We're proud of our six year leadership streak, right up to this Magic Quadrant's end. Instead, Gartner is going to focus on the broader scope of Digital Experience Platforms, leaving stand-alone Web Content Management platforms behind.

Gartner's decision to drop the Web Content Management Magic Quadrant is consistent with the second part of our product strategy; a transition from Web Content Management to Digital Experience Management.

Acquia's expansion into Digital Experience Management

We started our expansion from Web Content Management to the Digital Experience Platform market five years ago, in 2014. We believed, and still believe, that just having a website is no longer sufficient: customers expect to interact with brands through their websites, email, chat and more. The real challenge for most organizations is to drive personalized customer experiences across all these different channels and to make those customer experiences highly relevant.

For five years now, we've been patient investors and builders, delivering products like Acquia Lift, our web personalization tool. In June, we released a completely new version of Acquia Lift. We redesigned the user interface and workflows from scratch, added various new capabilities to make it easier for marketers to run website personalization campaigns, added multi-lingual support and much more. Hands down, the new Acquia Lift offers the best web personalization for Drupal.

In addition to organic growth, we also made two strategic acquisitions to accelerate our investment in becoming a full-blown Digital Experience Platform:

  1. In May, Acquia acquired Mautic, an open marketing automation platform. Mautic helps open up more channels for Acquia: email, push notifications, and more. Like Drupal, Mautic is Open Source, which helps us deliver the only Open Digital Experience Platform as an alternative to the expensive, closed, and stagnant marketing clouds.
  2. In December, we announced that Acquia acquired AgilOne, a leading Customer Data Platform (CDP). To make customer experiences more relevant, organizations need to better understand their customers: what they are interested in, what they purchased, when they last interacted with the support organization, how they prefer to consume information, etc. Without a doubt, organizations want to better understand their customers and use data-driven decisions to accelerate growth.

We have a clear vision for how to redefine a Digital Experience Platform such that it is free of any silos.

In 2020, expect us to integrate Lift, Mautic and AgilOne, as well as make them the best solution for Drupal. We believe that this will benefit not only our customers, but also our agency partners.

Momentum

Demand for our Open Digital Experience Platform continued to grow among the world's most well-known brands. New customers include Liverpool Football Club, NEC Corporation, TDK Corporation, L'Oreal Group, Jewelers Mutual Insurance, Chevron Phillips Chemical, Lonely Planet, and GOL Airlines among hundreds of others.

We ended the year with more than 1,050 Acquians working around the globe with offices in 14 locations. The three acquisitions we made during the year added an additional 150 new Acquians to the team. We celebrated the move to our new and bigger India office in Pune, and ended the year with 80 employees in India. We celebrated over 200 promotions or role changes showing great development and progression within our team.

We continued to introduce Acquia to more people in 2019. Our takeover of the Kendall Square subway station near MIT in Cambridge, Massachusetts, in April, for instance, helped introduce more than 272,000 daily commuters to our company. In addition to posters on every wall of the station, the campaign — in which photographs of fellow Acquians were prominently featured — included Acquia branding on entry turnstiles, 75 digital live boards, and geo-targeted mobile ads.

Last but not least, we continued our tradition of "Giving back more", a core part of our DNA or values. We sponsored 250 kids in the Wonderfund Gift Drive (an increase of 50 from 2018), raised money to help 1,000 kids in India to get back to school after the floods in Kolhapur, raised more than $10,000 for Girls Who Code, $10,000 for Cancer Research UK, and more.

Some personal reflections

With such a strong focus on product and engineering, 2019 was one of the busiest years for me personally. We grew our R&D organization by about 100 employees in 2019. This meant I spent a lot of time restructuring, improving and scaling the R&D organization to make sure we could handle the increased capacity, and to help make sure all our different initiatives remain on track.

On top of that, Acquia received a substantial majority investment from Vista Equity Partners. Attracting a world-class partner like Vista involved a lot of work, and was a huge milestone for the company.

It feels a bit surreal that we crossed 1,000 employees in 2019.

There were also some low-lights in 2019. On Christmas, Acquia's SVP of Engineering Mike Aeschliman, unexpectedly passed away. Mike was one of the three people I worked most closely with and his passing is a big loss for Acquia. I miss Mike greatly.

If I have one regret for 2019, it is that I was almost entirely internally focused. I missed hitting the road — either to visit employees, customers or Drupal and Mautic community members around the world. I hope to find a better balance in 2020.

Thank you

2019 was a busy year, but also a very rewarding year. I remain very excited about Acquia's long-term opportunity, and believe we've steered the company to be positioned at the right place at the right time. All of this is not to say 2020 will be easy. Quite the contrary, as we have a lot of work ahead of us in 2020, including the release of Drupal 9. 2020 should be another exciting year for us!

Thank you for your support in 2019!

Categories: Drupal CMS

CiviCRM Blog: E-Commerce for Nonprofits: Maximize Revenue for your Mission

Drupal.org aggregator - Mon, 01/13/2020 - 13:58

For a nonprofit, raising enough funds to do the most good is at the forefront of goal setting this new year. Direct and recurring donations have always been time-proven and effective ways to achieve this goal. But how can a nonprofit differentiate themselves and maximize the revenue available to aid their cause? Adding an e-commerce store with profitable products that both connect to your organization’s vision and add funds to fuel your efforts can be a game-changer.

 

Charity:Water’s success in the e-commerce space is both aspirational and strategic genius. By implementing an e-commerce solution, powered by a payments processor similar to the Commerce iATS module available for both Drupal 7, 8 and the iATS extension on CiviCRM, Charity:Water has turned branded products into additional brand recognition, a compelling story, and increased financial support. They are successfully speaking the language of millennials, providing authentic alternatives to traditional donations.  

 

While nonprofits explore different income streams, there are important considerations.

 

Make an Impact with your Product Selections

Reflect on the demographics of your donors when choosing products to boost profit possibilities. Some products will appeal to different age groups and doing your research ahead of time will allow you to curate the most appealing product lineup.

 

Keep your Nonprofit’s Mission Top of Mind

The e-commerce addition that best represents the values and aspirations of your organization are more likely to be received as genuine by your existing donors. 

 

Protect your Organization

Avoid costly fraud complications by selecting a payment processor that is secure and easy to use. With the payment processing modules and extensions already available for Drupal 7, Drupal 8 and CiviCRM, you’ll have your store up and running in no time.

 

Ready to get started or have questions? Feel free to reach out for more information.

 

MembersPartnersCase studies and user storiesDrupalDrupal 8
Categories: Drupal CMS

Promet Source: Baking Accessibility into Web Design and Development

Drupal.org aggregator - Mon, 01/13/2020 - 08:00
Too often, compliance with WCAG 2.1, to ensure web accessibility for people with disabilities, is an afterthought of the web development process. WCAG 2.1 compliance is a multifaceted endeavor, and when accessibility is incorporated into every phase of development, the result is greater efficiencies and superior outcomes. Let’s look at the key phases of the web development workflow, and the advantage of keeping accessibility top of mind every step of the way. 
Categories: Drupal CMS

Issue 419

TheWeeklyDrop - Thu, 01/09/2020 - 01:59
Issue 419 - January, 9th 2020
Categories: Drupal CMS

InternetDevels: Drupal Commerce 2.16: cart expiration, exact promotion time & more!

Drupal.org aggregator - Thu, 12/26/2019 - 05:48

E-commerce opportunities are endless nowadays. More and more business owners decide to hire e-commerce developers and skim the cream off online sales. Today, we will describe the new opportunities offered by Drupal Commerce 2.16.

Read more
Categories: Drupal CMS

Leopathu: Drupal 8 Synchronize Configuration between Two Different Site

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
Drupal 8 has lot of inbuilt functionality within it, one of the main important features is Configuration Synchronization. It will help us to migrate full setup properly on site deployment. But the main problem is that, According to the Drupal 8 CMI documentation,
Categories: Drupal CMS

Leopathu: Dynamic Block Weight in Drupal 8

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
In such a time, i want to place blocks in sidebar region with the dynamic weight. It means the blocks should render in different position for each page request. I have searched and tried lots of method but unfortunately i can’t find proper method to do that. So i have decided to do that with some hacky way.
Categories: Drupal CMS

Leopathu: Create a custom Twig filter in Drupal 8

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
Twig can be extended in many ways; you can add extra tags, filters, tests, operators, global variables, and functions. You can even extend the parser itself with node visitors. In this blog, I am going to show you how to create new custom twig filters in drupal. For example we are going to create a filter to remove numbers from string, will explain with hello_world module. Create hello_world folder in modules/custom/ folder with the following files,
Categories: Drupal CMS

Leopathu: Configure Multisite in Drupal 8

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
One of the most favourite and  valuable features in drupal is multisite configuration, Drupal 8 provide simple way to create multisite it reduced lots of works. The following steps shows to configure multisite in drupal 8,
Categories: Drupal CMS

Leopathu: Drupal Tricks - 1

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
I needed a way to check the currect user has permission to view the currect/particular page, Searched lot finally got the exact way, going to show the tricks to you in this blog. Drupal has an api called " drupal_valid_path " , Normally it used to test the url is valid or not. but the trick is that, It also check the user has permission to view the currect/particular page.
Categories: Drupal CMS

Leopathu: Install Drupal Using Drush

Drupal.org aggregator - Thu, 12/26/2019 - 04:08
Most of the times developers don't like the GUI, It makes feel lazy. Drupal has a tool (Drush) to do some management work from command line. And also the installing the drupal site makes very lazy while doing with browser, The Drush has an option to install the full site with a single command. The Following command will install the drupal in standard method, drush site-install standard --account-name=admin --account-pass=[useruser_pass] --db-url=mysql://[db_user]:[db_pass]@localhost/[db_name]
Categories: Drupal CMS

Colorfield: Extract tokens from a Drupal database dump

Drupal.org aggregator - Mon, 12/23/2019 - 09:15
Extract tokens from a Drupal database dump christophe Mon, 23/12/2019 - 18:15 While working on migrations from Drupal 7 to 8 it could be necessary to convert tokens from formatted text fields + get an idea of how many of them are in the database for estimation, e.g. see if it is possible to rely on Token Filter or if there are custom tokens/filters.
Categories: Drupal CMS

wishdesk.com: Language switcher as a vital feature of multilingual Drupal 8 sites

Drupal.org aggregator - Mon, 12/23/2019 - 08:33
A language switcher is vital for a user-friendly multilingual website. See how language switcher is created in Drupal 8 (with the video).
Categories: Drupal CMS

Spinning Code: On Being Self-Taught

Drupal.org aggregator - Mon, 12/23/2019 - 00:00

From time to time conversations come up among developers, and other fellow travelers, about being self-taught vs getting formal training. Over time I’ve come to realize that the further and further you get into your career, the less the distinction means anything; eventually we are all mostly self-taught.

I’ve written before about the value of my liberal arts education and I stand by my assertion that what I learned in that setting was, and is, valuable to my life and work. But just because something was useful to life does not mean it was the only way to acquire the skills. It’s a good way for many people, but far from the only way.

For anyone in a technical field, and most professional fields really, to succeed over time you need to learn new tools, skills, and techniques. The tools I knew when I graduated college are all largely outmoded or significantly upgraded, and I’ve had to learn a variety of technologies that didn’t exist in 2001.

Within the Drupal community lots of people talk about being self-taught, sometimes with pride sometimes with embarrassment, but in truth very few people were formally trained on the platform. A CS degree is not required. Lots of very successful developers in the Drupal community (and beyond) have degrees in fields like religion and art history. In fact, I’ll argue that just about every Drupaler taught themselves most of what they know about Drupal. How they did that can vary widely, but we are a community with few formal training programs and lots of people who stumbled into Drupal trying to solve a non-technical problem (communications or marketing for an organization). Even advanced workshops at conferences dig deep into one small area and expect you to generalize that knowledge to your projects, which I count as self-taught. For example, I had a friend ask the other day about how to control the PDO connection settings in Drupal 7 — which I didn’t know how to do, but knew they were similar to Drupal 8 — so I sent him my Drupal 8 instructions and he figured it out how from there. He’s now taught himself how to do what he needed for that project and in the process generalized the approach for whatever he may need next time.

So then it is important for all of us to find, and hopefully share, techniques for self-teaching — even for those who have some kind of formal training. Here are my suggestions for people who are starting out and haven’t yet found the pattern that works for them:

  1. Assume you first solution is wrong. Most of us have, or will, stumble our way through a project where we don’t really know what we’re doing without a lot of support. We usually learn a great deal in the process, and launching those projects can feel pretty good cause you’ve succeeded at something hard. It is easy to get into the habit of assuming the solutions from that project were correct because they worked. In truth those projects are really rough around the edges, and just because we got it to work does not mean the solution was good. Assuming the first solution is good enough forever is how you come an expert beginner which then takes a lot of effort to undo. Once you have a working solution, step back and see if you can think of a better one, or if you now can guess better search terms to see if someone else wrote up a different solution to the same problem. Admit your work could be better and try to improve it.
  2. Learn a few more programming languages. Most people who are self-taught from the start, and even some who have a BA/BS in Computer Science, only know 2 or 3 programming languages (PHP, JS, and CSS+HTML are often the only languages new people learn at first). One of the courses I took by chance in college forced me to learn 8 in 16 weeks. It was grueling, miserable, and darned useful. I can still learn a new language in just a couple weeks and rarely do I hit a language construct I don’t recognize. You don’t need to go that far. When I first started out a mentor told me you should learn a new language every year, and for several I did. Some of those, not the languages I learned in college, are the ones I use most day-to-day. All told I’ve spent time writing code in more than twenty different languages. That many isn’t terribly useful but the more languages you learn, the more you learn to understand the elements of your primary language.
  3. Learn basic algorithms and to measure complexity. The kind of thinking that goes into formal algorithms will help you be a better developer overall; badly thought through processes is the place I tend to see the largest gaps between developers with and without formal training. Any college-level CS program will put you through an algorithms course that teaches a variety of specific algorithms and force you to understand their structures. If you didn’t go through one of those programs, this is probably the course that will help you the most. On the one hand most of us rarely rewrite these algorithms as on modern platforms some library or another will provide a better version than we are likely to craft for our project. But learning what they are, when they are used, and how to understand their performance is useful for any project that involves lots of data or processing. MIT has a version of their algorithms course from 2011 online, or find one through another provider. Even if you just watch the lectures (really watching, not just vaguely have them on while cooking and cleaning), you can learn a great deal of useful information. I learned a lot watching those lectures as it refreshed and updated my understanding of the topics.
  4. Find and learn from mentors. Notice I used a plural there; you should try to find a few people willing to help you learn your profession, and more generally help you learn to advance in your field. Most of us benefit from learning from the experiences of multiple people, and who we need to learn from changes over time. I had the great experience of having a few wonderful mentors when I was first starting out, and much of the advice they gave me still serves me well. Some of it contradicted, and resolving those contradictions forced me to learn to do things my own way and find my own solutions.
  5. Learn other platforms. This is both a protection against future shifts in the market, and also a way to see how things work from outside your current professional bubble. Drupal developers can learn a lot from writing a WordPress plugin, or better yet an add-on for a platform in another language (think about Plone, Gatsby, or Hugo). Or try to learn to work with a platform like Salesforce or AWS. Other platforms have different communities, different learning styles, and different patterns. Like understanding additional languages, different platforms help you broaden your understanding and provide insights you can bring back to your main work.
  6. Learn to give and take criticism. Part of learning is getting feedback on your work, and part of being on a team is sharing feedback with others. If you took art or music classes in high school or college you probably learned some of the basic lessons you need here, but if you didn’t, consider taking one now at your local community college or art center. The arts are wonderful for getting experience with criticism. For all art is often open to interpretation, it also requires specific skills. If you play off-key, it sounds wrong. If your sculpture collapses under its own weight, the project failed. If your picture’s subject is out of focus, you need to re-shoot it. Sure there are brilliant artists who can violate all the rules, but if you have never experienced an art critique you are not one of those artists. The experience of getting direct, blunt, and honest feedback will help you understand its value and have to give that feedback yourself.
  7. Share what you think you know. We learn a great deal with we teach others. Both because it forces us to refine our thinking and understanding so we can explain it, and because learners ask questions we cannot answer off the top of our heads. This can be user group or conference presentations, internal trainings for your team, mentoring junior developers, writing a blog, or anything else that gets your from learning to teaching. It’s okay if you’re not 100% right, that’s part of how we learn. A few years ago I was doing a joint project with a junior developer who asked me a lot of questions, and pushed hard when she thought I was making mistakes. When she asked why I was selecting a solution or setting a pattern, she was never satisfied with “because that’s the best way to do it.” She wanted me to explain why that was the best way. If I couldn’t walk her through it right away, I went back and hunted for reference material to explain it or if that failed I tested her counter ideas against my plans to see if I was missing something. While I was usually right, not always and we did make changes based on her feedback. More importantly it forced me to show my work in fine detail which was a good exercise for me and gave her insights to help her do better work.
  8. Find your own patterns. At the start I said this list was for people who didn’t have their own patterns yet. In the long-run of your career you need to figure out what you need to know to get to where you want to go next. Eventually you will need to find a pattern that works for you and the life you are living. No one can tell you what that is, nor how to learn it all yourself. Experiment with learning styles, areas of work, roles, and types of projects as much as you are able until you feel your way to the right solutions for you.
Categories: Drupal CMS

Gizra.com: Translating Drupal User interface with Spreadsheets

Drupal.org aggregator - Sun, 12/22/2019 - 16:00

Making multilingual sites is hard. I’ve been using Drupal since version 5 and I can say a few things about the evolution of Drupal multilingual capabilities:

  • First, Drupal 8 is – in my opinion – the first version of Drupal where someone could say that multilingual works, pretty much out of the box.
  • Second, the documentation about how to deal with different scenarios is quite good.
  • And third, from a user experience perspective, translating the user interface of a site is really hard.

In this post we will talk about the third point and what we did to manage that complexity.

Our Current Scenario

We are building a really complex site, and the main challenges we faced regarding multilingual are:

  • The site is a multisite architecture, one database using Organic Groups.
  • Each group represents a country, and each country needs its site in one or more languages.
  • We have several variations of the same language depending on the region this language is spoken in.
  • We don’t want to let content editors translate the site directly from the UI.
  • We don’t speak all the languages the site is in.

The last item is quite relevant, when you don’t speak a language, you cannot even be sure if the string you are copying into a textbox says what it should.

The First Attempt

We started with a translation matrix to store all the translations. A simple Google drive spreadsheet to track each string translation in each language.

Each column uses the language code as a header.

Using a tool to convert Spreadsheets into po files we get each translation file fr.po, es.po, pt.po.

We used wichert/po-xls to achieve this with good results.

Not So Fast

This initial, somewhat naive, approach had a few problems.

  • Drupal string translations are case sensitive. This means that if you made a typo and wrote Photo instead of photo the translation will fail.
  • Some strings are the result of a calculation. For example. Downloads: 3 is actually managed by Drupal as Downloads: @count.

But the more complex item is that Drupal 8 has two ways to translate strings. The first one is inherited from Drupal 7. The one that makes use of the well known t function for example t('Contact us.').

The other one is a new way that allows site builders to translate configuration entities.

The two scenarios that allow translation of a Drupal site. Translating Configuration Entities is Really Hard

To translate configuration entities, you need to identify which configuration needs translation, and find the exact part relevant to you. For complex configuration entities like views, this could be quite hard to understand.

Even for an experienced site admin this can be hard to understand.

Another problem that we had to solve was the vast amount of configuration alternatives you have when dealing with a medium-size Drupal site.

Each category has a lot of items to translate.

It was clear to us that in order to translate all those items we needed to find another way.

More problems… Identifying Which Strings to Translate is Hard

One thing to consider when dealing with Drupal translations is that it’s not easy to identify if a string is displayed somewhere in the frontend or if it is only a backend string.

Translating the entire codebase may not be a viable option if you want to keep a short list of translations reviewed by a group of people. In our case, it was important to make sure that translations are accurate, and that translators do not feel overwhelmed.

We don’t have a great solution to this problem yet. One of the strategies we used was to search for all the strings in twig templates and custom modules code using a grep search.

egrep -hro "[\>, ]t\('.*'\)" . | cut -c 5- # Get strings inside ->t(...) and t(...) egrep -hro "{{ '.*'\|\t" . # Get twig strings '....'|t egrep -hro " trans .*" . # Get twig strings inside trans

However, as we figured out later by reading the documentation, twig strings cannot be used as a source for translations. Internally, Drupal maps those strings back to the regular use of t('strings').

This means that strings like:

{% trans %}Copyright {{ year }}{% endtrans %}

Are actually converted to

t('Copyright @year')

And that last string is the one you should use as source of the translation.

At the end, we cleaned up the spreadsheet list using visual inspect, and so far it has been working fine.

How We Solved the Problems?

To recap the problems we had:

  • We did not want to translate all the available strings.
  • We did not know all the languages, therefore copy and pasting was a risk.
  • Translators were expecting to have a reduced number of strings to translate.
  • Configuration translations are quite complex to track.

As we mentioned before using the xls-to-po tool, we were able to obtain the PO files to translate one part of the strings that we needed to translate.

We also used drush_language to automate the process.

drush language-import --langcode=fr path/to/po_files/fr.po

This little snippet iterates over all of the po files in the po_files directory and imports the language using the drush command mentioned above.

find po_files -type f -name *.po | xargs basename --suffix=.po | \ xargs -I@ drush language-import --langcode=@ @.po

The xls spreadsheet has in the first column the Message Id, and the language codes of the system

By using conditional cell colors, we can quickly identify which translations are pending. Solving the Configuration Translation Problem

The second part of our problem was a bit more tricky to fix.

We used a custom script to get all the config entity strings that were relevant to us.

Here is a simplified version of the script.

$prefix = 'views.view.custom_view'; $key = 'display.default.display_options.exposed_form.options.reset_button_label'; $configFactory = \Drupal::service('config.factory'); $list = $configFactory->listAll($prefix); $rows = []; foreach ($list as $config_name) { $columns = []; // Add the unique identifier for this field. $columns[] = $config_name . ':' . $key; // Get the untranslated value from the config. $base_config = $configFactory->getEditable($name); $columns[] = $base_config->get($key); $rows[] = $columns; }

If you wonder how to get the $prefix and $key, they are obtained by inspecting the name of the field we want to translate in the Configuration Translation UI.

You need to inspect the HTML of the page, see the name attribute.

We print the result of the script to obtain a new CSV file that looks like this

The first column is a unique id that combines the prefix and the key.

Then, we copy and paste this CSV file as a new tab in the general translation matrix, and complete the header with the rest of the languages translations.

Finally we use a spreadsheet formula to find the translation we want for the languages we are interested in.

=IFERROR(VLOOKUP($B2,$Strings!$A$2:Y299,COLUMN()-1,0);"")

This will search for a match in the Strings matrix, and provide a translation.

Spreadsheet magic. Final step: Importing the Configuration Strings Translation Back to Drupal

Once we have all the translations we need. We export the CSV file again and use this other script (simplified version) to do the inverse process:

use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Encoder\CsvEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; $filename = 'path/to/config_translations.csv'; $serializer = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]); $configFactory = \Drupal::service('config.factory'); $languageManager = \Drupal::service('language_manager'); $serializer->encode($data, 'csv'); $data = $serializer->decode(file_get_contents($filename), 'csv'); foreach ($data as $row) { $name_key = array_values($row)[0]; list($name, $key) = explode(':', $name_key); // The languages we care start after the second column. $languages = array_filter(array_slice($row, 2)); foreach ($languages as $langcode => $translation) { $config_translation = $languageManager ->getLanguageConfigOverride($langcode, $name); $saved_config = $config_translation->get(); $config_translation->set($key, $translation); $config_translation->save(); } } Some Other Interesting Problems We Had

Before finishing the article, we would like to share something interesting regarding translations with contexts. As you may know, context allows you to have variations of the same translation depending on, well… context.

In our case, we needed context to display different variations of a French translation. In particular, this is the string in English that we needed to translate to French:

Our organization in {Group Name}

In France, this translates into Notre organisation en France. But if you want to say the same for Canada, due to French grammatical rules you need to say Notre organisation au Canada (note the change en for au).

We decided to create a context variation for this particular string using context with twig templating.

{% trans with {'context': group_iso2_code} %} Our organization in { group_name } {% endtrans %}

This worked ok-ish, until we realized that this affected all the other languages. So we need to specify the same translation for each group even if the language was not French

This is not what we want...

After some research we found the translation_fallback module but unfortunately it was a Drupal 7 solution.

Long story short, we ended up with this solution.

{% if group_uses_language_context %} {% trans with {'context': country_iso2_code} %} Our organization in { group_name } {% endtrans %} {% else %} {% trans %}Our organization in { group_name }{% endtrans %} {% endif %}

Which basically provides two versions of the same string. But if the group needs some special treatment, we have the change to override it. Lucky for us, xls-to-po has support for strings with context. This is how we structured the translations for strings that require context:

CA, in this case, is the ISO code for Canada Conclusion

For us, this is still a work in progress. We will have to manage around 20 or more languages at some point in the project. By that point, having everything in a single spreadsheet may not be maintainable anymore. There are other tools that could help us to organize source strings. But so far a shared Google Sheet worked.

We still use configuration management to sync the strings in production. The snippets provided in this post are run against a backup database so we can translate all the entities with more confidence. Once we ran the script we use drush config:export to save all the translations to the filesystem.

Continue reading…

Categories: Drupal CMS

OSTraining: How to use the Slick Module in Drupal 8

Drupal.org aggregator - Sat, 12/21/2019 - 21:00

One of OSTraining’s members wants to have a carousel slider in her site. She wants the carousel to show 3 image slides and some text below them, and the carousel to move only one position at a time when you click the “Next” button. 

This is possible to achieve, thanks to the Drupal Slick module which has several options and settings to customize this interaction with a couple of clicks. 

Keep reading in order to learn how to use this module!

Categories: Drupal CMS

Palantir: Guide to the Drupal 8.8 Update

Drupal.org aggregator - Fri, 12/20/2019 - 07:04

Updating to Drupal 8.8 is the first step in preparing your site for Drupal 9.

In this post we will cover...
  • Changes required to update a Drupal 8 site to the 8.8.0 release
  • Contrib module flags
  • Troubleshooting this update

If you're currently running a Drupal 8 site and are interested in upgrading to Drupal 9 when it is released in the summer of 2020, the first step is to update to the recently-released Drupal 8.8. Drupal 8.8 contains both the deprecated APIs and the new APIs that will become standard in Drupal 9, so once your site is on 8.8, you can begin to review your contrib modules and update your custom code to move from deprecated APIs to the state of the art. No new features will be added in the 9.0 release, which means that 8.8 has feature parity to streamline the upgrade path between 8.x and 9.x.

The update to 8.8 is more involved than previous Drupal 8 point releases because 8.8 renames some configuration variables and changes the core drupal packages and dependency structure in composer.json, which means that updates need to be made to both settings.php and composer.json.

At Palantir, our team maintains many Drupal 8 sites in both active development and support, and we've documented some important tips that are important to keep in mind when updating your site to 8.8. We also want to give a shout-out to the folks at PreviousNext for their post on what they learned when updating to the 8.8 beta release.

Update process overview
  1. Contrib module conflicts: If your site is using the contrib modules Pathauto, Workspace, or Coder, update those first.
  2. Update settings.php: Change the temp and config sync directory variables settings.php
  3. Update composer.json: Manually update your composer.json
  4. Run the Drupal database updates
  5. Export changed config
Contrib module conflicts Pathauto

We use the Pathauto module on all of the sites we build, and Pathauto needs some handholding in this update process. If you don't update Pathauto while you're still on Drupal core 8.7, you could lose your path alias data!

  1. While your site is still running Drupal 8.7, update Pathauto to the latest release (8.x-1.6): composer require drupal/pathauto:^1.6
  2. Deploy the updated code
  3. Run the database updates: drush updatedb
  4. Begin your Drupal 8.8 update
Workspace

Workspace isn't common on our sites, so running into an issue with it usually means doing some research. The contrib Workspace module has been moved into core, and renamed "Workspaces"; installing both modules on the same site creates code-level conflicts. Additionally, the Drupal 8.8 release introduces an incompatibility between core Content Moderation module and the contrib Workspace module.

As of December 2019, there is no ready-made upgrade path from the contrib module to the core module; the recommendation is to uninstall the contrib module -- which will delete all workspace content that is not yet live -- and then install core's module (documentation).

Coder

If you're using Coder to do automated code review against the Drupal coding standards, you may need to update. Drupal 8.8 requires a minimum of version 8.3.2.

  1. Check your coder version: composer show drupal/coder
  2. You'll see the package information with the version -- in this case, 8.2.10: [ 3:15P ~/repos/example] (develop) $ composer show drupal/coder
    name     : drupal/coder
    descrip. : Coder is a library to review Drupal code.
    keywords : code review, phpcs, standards
    versions : * 8.2.10
    type     : library
    ...
  3. Update the package: composer require drupal/coder:^8.3.2
Updating settings.php

First, find your settings.php file; this will be within your Drupal site at sites/default/settings.php, or may be an include file named like sites/default/settings.*.php.

Config sync directory

The config sync directory is where Drupal stores your exported configuration YAML files. Before Drupal 8.8, you could configure multiple directories for exporting config; now there's only one, and the variable name has changed.

Check settings.php files for the $config_directories variable:

$config_directories = [];
$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sites/default';

Replace this (using your original path) with:

$settings['config_sync_directory'] = '../config/sites/default'; More information Temporary (temp) directory

The temp directory is usually specific to your host or the environment where your Drupal site is running, so you may need to set this differently for production vs. local development.

Check your settings.php files for the temp directory configuration:

$config['system.file']['path']['temporary'] = $_ENV['TEMP'];

Replace this (using your environment-specific path) with:

$settings['file_temp_path'] = $_ENV['TEMP']; More information Update composer.json

Drupal 8.8 introduced scaffolding in core and separated dev dependencies into a separate package. The scaffolding manages core files like index.php and .htaccess, which are required for Drupal to run but don't live within the core/ directory. You might already be using drupal-composer/drupal-scaffold for this purpose, which will need to be replaced.

Because these changes involve replacing existing packages and updating composer plugin configuration, they need to be manually applied to your composer.json.

Use the drupal/core-composer-scaffold package

Edit your composer.json and to the require section, add:

        "drupal/core-composer-scaffold": "^8.8",

This should replace the drupal-composer/drupal-scaffold package, if you were using it.

This is a composer plugin, and needs to be configured in the extra section of your composer.json. Add or update the drupal-scaffold configuration:

        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            },
            "allowed-packages": [
                "drupal/core"
            ],
            "file-mapping": {
                "[web-root]/.htaccess": {
                    "mode": "replace",
                    "path": "web/core/assets/scaffold/files/htaccess",
                    "overwrite": false
                }
            }
        },

Double check the web-root location and change web/ if necessary -- for example, if you're hosting on Acquia, set this to docroot/.

Also check the file-mapping section and make sure the value for path is correct. This file-mapping configuration will prevent your .htaccess file from being overwritten if you've customized it, but can be left out otherwise.

More information Add the new drupal/core-recommended package to your Composer requirements

This will install your core Drupal requirements.

Edit your composer.json and in the require section, replace the drupal/core package with:

        "drupal/core-recommended": "^8.8", Add the new drupal/core-dev package to your Composer dev requirements

This will install optional, development-specific core dependencies so that you can run things like automated testing.

Edit your composer.json and to the dev section, add:

        "drupal/core-dev": "^8.8",

This should replace the webflo/drupal-core-require-dev package, if you were using it.

More information Finally, run Composer

Now that you've updated your composer.json file, run Composer to update your packages. In order to update only the packages you've changed (and not every package all at once), run:

composer update --lock Troubleshooting Composer

After making these changes to your composer.json, you may see the following error when you run composer install or composer update:

Installation failed, reverting ./composer.json to its original content.
[RuntimeException]
Could not delete /srv/users/serverpilot/apps/sandbox/drupal/web/sites/default/default.services.yml:

This happens because the scaffolder (which runs on composer install and update) is trying to write files to your sites/default/ directory, but doesn't have the permissions. You can resolve this with:

chmod +w web/sites/default

See Troubleshooting: Permission issues prevent running Composer for more details.

Running the update scripts

Finally, you'll need to do the normal Drupal update process: run the database exports, and export any config changes:

drush updatedb
drush config:export Troubleshooting the database updates

If you're testing the database updates multiple times on the same environment, you may run into this error:

[error] Update failed: system_update_8804

This happens because system_update_8804 creates new database tables. If you are using drush sql-sync to test and re-test the update against a copy of the production database, you'll need to clear your local database with drush sql-drop first, in order to delete tables created by a previous run.

What next?

Once your site has been updated to Drupal 8.8, you'll be in good shape for the upgrade to Drupal 9, which is currently anticipated on or around June 3, 2020. Between now and then, we'll be working alongside other Drupal contributors to make sure that key contributed modules are ready for Drupal 9, as well helping our clients make sure that custom code and modules on their sites are free of deprecated APIs. Stay tuned for more!

Development Drupal Support
Categories: Drupal CMS

Pages

1 2 3 4 5 6 7 8 9 next › last »