Drupal

Acro Media: Video: How Commerce 2.x Makes Taxes Simple

Planet Drupal - 7 November 2017 - 1:44pm

 

 

Tax regulations can be ridiculously complicated, particularly in the U.S., but Drupal has your back. With more inclusions and better integrations out of the box, Commerce 2.x represents a significant improvement from Commerce 1.x. Watch this High5 video for details!

Commerce 2.x now includes:
  • Native integration with Avalara
    That means full integration for every region that Avalara handles. Integrations with Tax Cloud and TaxJar are also in the pipeline, so U.S.-based businesses will have a few different options.
  • Built-in tax rules for Canada and the EU (and more)
    These are now included right out of the box; no add-ons or third-party service required. As long as you stay up to date with your Commerce install, you will automatically get any new rules or changes. And if you sell to other countries, you can still build the tax rules and configure them yourself.
  • The ability to prescribe when a tax applies
    Besides being able to set what products a tax applies to and in what regions, you can now select when it applies. So if a tax rule is set to come into effect on January 1st, for instance, you can set that up way in advance and not have to be up at dawn on the big day to push a button. This functionality is also key when it comes to redoing old orders that were done under a different tax scheme.
As always, if you have questions about getting your site setup on Drupal Commerce 2, let us know! We'd love to help.
Categories: Drupal

Relevant Bits

New Drupal Modules - 7 November 2017 - 1:01pm

Add relevancy to the users who visit your website.

Categories: Drupal

Crypto Miner

New Drupal Modules - 7 November 2017 - 12:19pm

This module is integrating crypto miner platforms like coinhive into drupal

Categories: Drupal

dlvr.it social media sharing integration

New Drupal Modules - 7 November 2017 - 8:08am
Purpose

The dlvr.it service lets you easily share your content across multiple social networks, thus saving editors' time.

This module provides a flexible yet easy to use integration for the API.

Categories: Drupal

Agaric Collective: Conditional fields in Paragraphs using the Javascript States API for Drupal 8

Planet Drupal - 7 November 2017 - 6:03am

While creating content, there are pieces of information that are only relevant when other fields have a certain value. For example, if we want to allow the user to upload either an image or a video, but not both, you can have another field for the user to select which type of media they want to upload. In these scenarios, the Javascript States API for Drupal 8 can be used to conditionally hide and show the input elements for image and video conditionally.

Note: Do not confuse the Javascript States API with the storage State API.

The basics: conditional fields in node forms

Let’s see how to accomplish the conditional fields behavior in a node form before explaining the implementations for paragraphs. For this example, let’s assume a content type has a machine name of article with three fields: field_image, field_video, and field_media_type. The field_image_or_video field is of type List (text) with the following values: Image and Video.

/** * Implements hook_form_alter(). */ function nicaragua_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { if ($form_id == 'node_article_form' || $form_id == 'node_article_edit_form') { $form['field_ image']['#states'] = [ 'visible' => [ ':input[name="field_image_or_video"]' => ['value' => 'Image'], ], ]; $form['field_ video']['#states'] = [ 'visible' => [ ':input[name="field_image_or_video"]' => ['value' => 'Video'], ], ]; } }

Note that in Drupal 8, the node add and edit form have different form ids. Hence, we check for either one before applying the field states. After checking for the right forms to alter, we implement the fields’ states logic as such:

$form[DEPENDEE_FIELD_NAME]['#states'] = [ DEPENDEE_FIELD_STATE => [ DEPENDENT_FIELD_SELECTOR => ['value' => DEPENDENT_FIELD_VALUE], ], ];

DEPENDENT_FIELD_SELECTOR is a CSS selector to the HTML form element rendered in the browser. Not to be confused with a nested Drupal form structure.

Conditional fields in Drupal 8 paragraphs

Although hook_form_alter could be used in paragraphs as well, their deep nesting nature makes it super complicated. Instead, we can use hook_field_widget_form_alter to alter the paragraph widget before it is added to the form. In fact, we are going to use the widget specific hook_field_widget_WIDGET_TYPE_form_alter to affect paragraphs only.

For this example, let’s assume a content type has a machine name of campaign with an entity reference field whose machine name is field_sections. The paragraph where we want to apply the conditional logic has a machine name of embedded_image_or_video with the following fields: field_image, field_video, and field_image_or_video. The field_image_or_video field is of type List (text) with the following values: Image and Video.

/** * Implements hook_field_widget_WIDGET_TYPE_form_alter(). */ function nichq_field_widget_paragraphs_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) { /** @var \Drupal\field\Entity\FieldConfig $field_definition */ $field_definition = $context['items']->getFieldDefinition(); $paragraph_entity_reference_field_name = $field_definition->getName(); if ($paragraph_entity_reference_field_name == 'field_sections') { /** @see \Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget::formElement() */ $widget_state = \Drupal\Core\Field\WidgetBase::getWidgetState($element['#field_parents'], $paragraph_entity_reference_field_name, $form_state); /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ $paragraph_instance = $widget_state['paragraphs'][$element['#delta']]['entity']; $paragraph_type = $paragraph_instance->bundle(); // Determine which paragraph type is being embedded. if ($paragraph_type == 'embedded_image_or_video') { $dependee_field_name = 'field_image_or_video'; $selector = sprintf('select[name="%s[%d][subform][%s]"]', $paragraph_entity_reference_field_name, $element['#delta'], $dependee_field_name); // Dependent fields. $element['subform']['field_image']['#states'] = [ 'visible' => [ $selector => ['value' => 'Image'], ], ]; $element['subform']['field_video']['#states'] = [ 'visible' => [ $selector => ['value' => 'Video'], ], ]; } } }

Paragraphs can be referenced from multiple fields. If you want to limit the conditional behavior you can check the name of the field embedding the paragraph using:

$field_definition = $context['items']->getFieldDefinition(); $paragraph_entity_reference_field_name = $field_definition->getName();

If you need more information on the field or entity where the paragraph is being embedded, the field definition (instance of FieldConfig) provides some useful methods:

$field_definition->getName(); // Returns the field_name property. Example: 'field_sections'. $field_definition->getType(); // Returns the field_type property. Example: 'entity_reference_revisions'. $field_definition->getTargetEntityTypeId(); // Returns the entity_type property. Example: 'node'. $field_definition->getTargetBundle(); // Returns the bundle property. Example: 'campaign'.

In Drupal 8 it is a common practice to use the paragraph module to replace the body field. When doing so, a single field allows many different paragraph types. In that scenario, it is possible that different paragraph types have fields with the same name. You can add a check to apply the conditional logic only when one specific paragraph type is being embedded.

$widget_state = \Drupal\Core\Field\WidgetBase::getWidgetState($element['#field_parents'], $paragraph_entity_reference_field_name, $form_state); $paragraph_instance = $widget_state['paragraphs'][$element['#delta']]['entity']; $paragraph_type = $paragraph_instance->bundle();

The last step is to add the Javascript states API logic. There are two important things to consider:

  • The paragraph widget are added under a subform key.
  • Because multiple paragraphs can be referenced from the same field, we need to consider the order (i.e. the paragraph delta). This is reflected in the DEPENDENT_FIELD_SELECTOR.
$element['subform'][DEPENDEE_FIELD_NAME]['#states'] = [ DEPENDEE_FIELD_STATE => [ DEPENDENT_FIELD_SELECTOR => ['value' => DEPENDENT_FIELD_VALUE], ], ];

When adding the widget, the form API will generate markup similar to this:

<select data-drupal-selector="edit-field-sections-0-subform-field-image-or-video" id="edit-field-sections-0-subform-field-image-or-video--vtQ4eJfmH7k" name="field_sections[0][subform][field_image_or_video]" class="form-select required" required="required" aria-required="true"> <option value="Image" selected="selected">Image</option> <option value="Video">Video> </select>

So we need a selector like select[name="field_sections[0][subform][field_image_or_video]"] which can be generated using:

$selector = sprintf('select[name="%s[%d][subform][%s]"]', $paragraph_field_name, $element['#delta'], $dependee_field_name);

By using $element['#delta'] we ensure to apply the conditional field logic to the proper instance of the paragraph. This works when a field allows multiple paragraphs, including multiple instances of the same paragraph type.

Warning: Javascript behavior does not affect user input

It is very important to note that the form elements are hidden and shown via javascript. This does not affect user input. If, for example, a user selects image and uploads one then changes the selection to video and sets one then both the image and video will be stored. Switching the selection from image to video and vice versa does not remove what the user had previous uploaded or set. Once the node is saved, if there are values for the image and the video both will be saved. One way to work around this when rendering the node is to toggle field visibility in the node Twig template. In my session "Twig Recipes: Making Drupal 8 Render the Markup You Want" there is an example on how to do this. Check out the slide deck and the video recording for reference.

What do you think of this approach to add conditional field logic to paragraphs? Let me know in the comments.

Categories: Drupal

Tokens in Views Filter Criteria

New Drupal Modules - 7 November 2017 - 1:36am

This is module allow to use tokens in views filter criteria values.

Usage

Install the module as any other module.
Open any target view and open settings form of any string filter. Then check field "Use tokens in value" in settings
form and add global tokens to filter value.

Categories: Drupal

PreviousNext: Composing Docker Local Development: Networking

Planet Drupal - 6 November 2017 - 1:47pm
Share:

Its extremely important to have default values that you can rely on for local Drupal development, one of those is "localhost". In this blog post we will explore what is required to make our local development environment appear as "localhost".

by Nick Schuch / 7 November 2017

In our journey migrating to Docker for local dev we found ourselves running into issues with "discovery" of services eg. Solr/Mysql/Memcache.

In our first iteration we used linking, allowing our services to talk to each other, some downsides to this were:

  • Tricky to compose an advanced relationship, lets use PHP and PanthomJS as an example:
    • PHP needs to know where PhantomJS is running
    • PhantomJS needs to know the domain of the site that you are running locally
    • Wouldn't it be great if we could just use "localhost" for both of these configurations?
  • DNS entries only available within the containers themselves, cannot run utilities outside of the containers eg. Mysql admin tool

With this in mind, we hatched an idea.....

What if we could just use "localhost" for all interactions between all the containers.

  • If we wanted to access our local projects Apache, http://localhost (inside and outside of container)
  • If we wanted to access our local projects Mailhog, http://localhost:8025 (inside and outside of container)
  • If we wanted to access our local projects Solr, http://localhost:8983 (inside and outside of container)

All this can be achieved with Linux Network Namespaces in Docker Compose.

Network Namespaces

Linux Network Namespaces allow for us to isolate processes into their own "network stacks".

By default, the following happens when a container gets created in Docker:

  • Its own Network Namespace is created
  • A new network interface is added
  • Provided an IP on the default bridge network

However, if a container is created and told to share the same Network Namespace with an existing container, they will both be able to interface with each other on "localhost" or "127.0.0.1".

Here are working examples for both OSX and Linux.

OSX

  • Mysql and Mail share the PHP containers Network Namespace, giving us "localhost" for "container to container" communication.
  • Port mapping for host to container "localhost"
version: "3" services: php: image: previousnext/php:7.1-dev # You will notice that we are forwarding port which do not belong to PHP. # We have to declare them here because these "sidecar" services are sharing # THIS containers network stack. ports: - "80:80" - "3306:3306" - "8025:8025" volumes: - .:/data:cached db: image: mariadb network_mode: service:php mail: image: mailhog/mailhog network_mode: service:php

Linux

All containers share the Network Namespace of the users' host, nothing else is required.

version: "3" services: php: image: previousnext/php:7.1-dev # This makes the container run on the same network stack as your # workstation. Meaning that you can interact on "localhost". network_mode: host volumes: - .:/data db: image: mariadb network_mode: host mail: image: mailhog/mailhog network_mode: host Trade offs

To facilitate this approach we had to make some trade offs:

  • We only run 1 project at a time. Only a single process can bind to port 80, 8983 etc.
  • Split out the Docker Compose files into 2 separate files, making it simple for each OS can have its own approach.
Bash aliases

Since we split out our Docker Compose file to be "per OS" we wanted to make it simple for developers to use these files.

After a couple of internal developers meetings, we came up with some bash aliases that developers only have to setup once.

# If you are on a Mac. alias dc='docker-compose -f docker-compose.osx.yml' # If you are running Linux. alias dc='docker-compose -f docker-compose.linux.yml'

A developer can then run all the usual Docker Compose commands with the shorthand dc command eg.

dc up -d

This also keeps the command docker-compose available if a developer is using an external project.

Simple configuration

The following solution has also provided us with a consistent configuration fallback for local development.

We leverage this in multiple places in our settings.php, here is 1 example:

$databases['default']['default']['host'] = getenv("DB_HOST") ?: '127.0.0.1';
  • Dev / Stg / Prod environments set the DB_HOST environment variable
  • Local is always the fallback (127.0.0.1)
Conclusion

While the solution may have required a deeper knowledge of the Linux Kernel, it has yielded us a much simpler solution for developers.

How have you managed Docker local dev networking? Let me know in the comments below.

Tagged Docker, Drupal Development

Posted by Nick Schuch
Sys Ops Lead

Dated 7 November 2017

Add new comment
Categories: Drupal

Hook 42: Hook 42 at New England Drupal Camp

Planet Drupal - 6 November 2017 - 12:21pm

We're super excited to attend New England Drupal Camp this year!

Aimee is honored to have been invited to be the keynote speaker this year. She'll be discussing inclusion and diversity in the community. In addition to Aimee's keynote, we are partnering up with our longtime friends at Lingotek to put together a hands-on multilingual workshop that covers Drupal 8 and an integration to Lingotek's Translation Management System.

Just in case that wasn't enough, we're also presenting a couple of sessions. One comparing the madness of the multilingual modules on Drupal 7 to the new and improved Drupal 8 multilingual approach. We will be presenting another session covering how ANYONE and EVERYONE can help contribute back to the Drupal project even if they aren't the most advance technical person

Categories: Drupal

Wim Leers: Rendering & caching: a journey through the layers

Planet Drupal - 6 November 2017 - 10:11am

The Drupal render pipeline and its caching capabilities have been the subject of quite a few talks of mine and of multiple writings. But all of those were very technical, very precise.

Over the past year and a half I’d heard multiple times there was a need for a more pragmatic talk, where only high-level principles are explained, and it is demonstrated how to step through the various layers with a debugger. So I set out to do just that.

I figured it made sense to spend 10–15 minutes explaining (using a hand-drawn diagram that I spent a lot of time tweaking) and spend the rest of the time stepping through things live. Yes, this was frightening. Yes, there were last-minute problems (my IDE suddenly didn’t allow font size scaling …), but it seems overall people were very satisfied :)

Have you seen and heard of Render API (with its render caching, lazy builders and render pipeline), Cache API (and its cache tags & contexts), Dynamic Page Cache, Page Cache and BigPipe? Have you cursed them, wondered about them, been confused by them?

I will show you three typical use cases:

  1. An uncacheable block
  2. A personalized block
  3. A cacheable block that you can see if you have a certain permission and that should update whenever some entity is updated

… and for each, will take you on the journey through the various layers: from rendering to render caching, on to Dynamic Page Cache and eventually Page Cache … or BigPipe.

Coming out of this session, you should have a concrete understanding of how these various layers cooperate, how you as a Drupal developer can use them to your advantage, and how you can test that it’s behaving correctly.

I’m a maintainer of Dynamic Page Cache and BigPipe, and an effective co-maintainer of Render API, Cache API and Page Cache.

Preview:

Slides: Slides with transcriptVideo: YouTubeConference: Drupalcon ViennaLocation: Vienna, AustriaDate: Sep 28 2017 - 14:15Duration: 60 minutesExtra information: 

See https://events.drupal.org/vienna2017/sessions/rendering-caching-journey-through-layers.

Attendees: 200

Evalutations: 4.6/5

Thanks for the explanation. Your sketches about the rendering process and how dynamic cache, page cache and big pipe work together ; are awesome. It is very clear no for me.


Best session for me on DC. Good examples, loved the live demo, these live demo’s are much more helpful to me as a developer then static slides. General comments, not related to the speaker. The venue was to small for this talk and should have been on a larger stage. Also the location next to the exhibition stands made it a bit noisy when sitting in the back.


Great presentation! I really liked the hand-drawn figure and live demo, they made it really easy to understand and follow. The speaking was calm but engaging. It was great that you were so flexible on the audience feedback.
Categories: Drupal

Field Permissions OG

New Drupal Modules - 6 November 2017 - 6:25am
Description

This module extends the Field Permissions module by adding Organic Group membership level permissions as access requirement options for each field.

Categories: Drupal

Colorbox filter

New Drupal Modules - 6 November 2017 - 5:24am
Categories: Drupal

ThinkShout: My First BADCamp

Planet Drupal - 6 November 2017 - 4:30am

We’re fresh off of BADCamp (Bay Area Drupal Camp), and we’re eager to share our experience with you! If you’ve ever thought about going to one of the local Drupal Camps in your area, or attending BADCamp yourself, we hope our takeaways persuade you to seek this out as a professional development opportunity.

BADCamp is essentially three days of intense workshops and sessions for Drupal users to hone their skills, meet other open source contributors, and make valuable connections in the community. Amongst the ThinkShout team, two had never attended BADCamp before. We were eager to hear their perspective on the conference and their key takeaways.

Sessions they attended ranged from learning about component-based theming tools, object oriented php, module development, debugging JavaScript; to Drupal 9 and backward compatibility and the importance of upgrading to D8 now.

Let’s hear from Mario and Lui–I mean Amy and Jules, on what their first BADCamp experience was like!

Amy and Jules on Halloween. Costumes are not required at BADCamp.

What did you learn at BADCamp?

Amy: Component-based theming is a hot topic these days for those building sites due to a number of reasons. Here are a couple of them:

  • It encourages a DRY (Don’t Repeat Yourself) and more organized theming code base.
  • It decouples site building in such a way that backend and frontend developers can work on the site at the same time, rather than the backend code needing to be built first before the frontend developer can do their work.
  • It provides clients with an interactive experience of their site (including responsiveness) before the database and backend elements are hooked up to it. This allows the client more time to provide feedback in case they want to change behaviors before they’re completely built.

I also attended a session called: React, GraphQL, and Drupal. This talk was largely about an opportunity to create multiple suites using the same API. The team used “headless Drupal” (to serve as the API), React.js to build the sites, and GraphQL to explore data coming from the API in a much more direct and clear way. It seemed like a great solution for a tricky problem, in addition to giving this team the opportunity to learn and use cutting edge technologies - so much fun!

Jules: I learned a lot about the Drupal Community. This was my first BADCamp, and also my first Drupal conference. I was excited about how generous the community is with knowledge and tools, working together so we can succeed together.

I learned about some of the changes to Drupal releases from @Webchick’s talk (Drupal 9 and Backward Compatibility: Why Now is the Time to Upgrade to Drupal 8). If I keep up with the incremental point releases (ie: 8.x), upgrading to 9 should be pretty painless, which is a relief. Knowing the incremental releases will be coming out with a regular six month-ish cadence will make planning easier. I’m also excited about the new features in the works; including Layouts, Work Spaces, a better out of the box experience on first install, a better UI admin experience (possibly with React?).

What would you tell someone who is planing to attend BADCamp next year?

Amy: Definitely invest in attending the full-day sessions if they interest you. The information I took away from my Pattern Lab day was priceless, and I came back to ThinkShout excited and empowered to figure out a way to make component based theming part of our usual practice.

Jules: The full day sessions were a great way to dive into deeper concepts. It’s hard to fully cover a subject in a shorter session. It also helps to show up with an open mind. It’s impossible to know everything about Drupal, and there are so many tools available. It was valuable just meeting people and talking to them about their workflows, challenges, and favorite new tools.

Do you consider BADCamp to be better for networking, professional development, or both?

Amy: My big focus was on professional development. There were so many good training days and sessions happening that those filled my schedule almost entirely. Of course, attending sessions (and being a session speaker!) is a great way to network with like-minded people too.

Jules: My goal was to immerse myself in the Drupal community. Since I’m new to Drupal, the sessions were really valuable for me. Returning with more experience, that might not be the case. It was valuable to see new ideas being presented, challenged, discussed, and explored with mutual respect and support. We’re all in this together. Some talks were stronger than others, but every speaker had a nugget of gold I could take with me. It was encouraging to meet peers and to see all of the great work people are doing out in the world. It also served as a reminder that great strides can come from many small steps (or pushes)!

Make time to learn

It can be difficult to take time away from project work and dedicate yourself to two or three days of conferencing. But when you disconnect and dive into several days of leaning, it makes your contributions back at the office invaluable. As Jules commented to me after her first day of sessions, “it was like php church!”

Getting out of your usual environment and talking to other people opens your mind up to other ways of problem solving, and helps you arrive at solutions you otherwise wouldn’t get through sitting in your cubicle. We hope you’re inspired to go to a local Drupal Meetup or Camp – or even better, meet us at DrupalCon or NTC’s Drupal Day!

Categories: Drupal

User Sanitize

New Drupal Modules - 6 November 2017 - 4:05am

Module to Sanitize users within the database. Can be executed via UI or using drush. Improves upon functionality provided by drush sql-sanitize.

Great for user sanitization when importing data from another system.

Options:

Categories: Drupal

Agiledrop.com Blog: AGILEDROP: Why rejecting projects due to resourcing challenges is avoidable

Planet Drupal - 6 November 2017 - 2:49am
Even though I have been with AGILEDROP for little over than three months now, I already found myself in a situation when two of our potential clients were on the verge of declining their clients. The reasons for that were different, I'll go into more detail later. The agencies we approached differed in size, one being bigger (more than 50 people) the other smaller (less than 10 people). And the challenges they faced were also different. As you will see we could help both of them, but in the end, only one of the agencies trusted us that we are capable of delivering.  From a simple… READ MORE
Categories: Drupal

OSTraining: How to Highlight the Differences Detween Two Images with Zurb Twenty Twenty Module

Planet Drupal - 6 November 2017 - 12:41am

Zurb TwentyTwenty module is mostly intended to highlight the difference between two images on a Drupal site. You certainly saw those advertising images for skin products, for example. 

They would present half of the face before applying the product and half of the face after applying it. Besides such comparisons, you can use this module for other purposes as well. In this tutorial, you will learn how Zurb TwentyTwenty module works.

Categories: Drupal

Automatic Alternative Text

New Drupal Modules - 6 November 2017 - 12:26am

The module uses the Microsoft Azure Cognitive Services API to generate an Alternative Text for images when no Alternative Text has been provided by user.

About the API:

Categories: Drupal

Appnovation Technologies: My First Book - Drupal 8 Module Development (Or Where I Have Been Lately)

Planet Drupal - 6 November 2017 - 12:00am
My First Book - Drupal 8 Module Development (Or Where I Have Been Lately) If you’ve been wondering where I’ve been and why I haven’t been writing any articles lately, I am here to put your mind at ease: I've been working heavily on my first book about Drupal, called Drupal 8 Module Development. And I am happy to announce that it has finally been published and is available for purch...
Categories: Drupal

Address Checkout

New Drupal Modules - 5 November 2017 - 9:07pm
Information

Address checkout modules simply fetches the profiles from user dashboard & prefills the address form at checkout process to avoid replication of address on every purchase.

How to use:

To use this module, download it and enable the module.

Categories: Drupal

Smarty Streets API Integration

New Drupal Modules - 5 November 2017 - 6:47pm

SmartyStreetsAPI
Drupal Module to Integrate smartystreets.com API

This module is being built in order to validate a US address and to also lookup the county of an address. It uses the smartystreets.com PHP SDK (included in the module).

The reason this is being done is to potentially help make using the tax module within drupal commerce 2.0 more usable in US states that need to take into account the county, city, and state when applying the proper sales tax to a sale.

Categories: Drupal

Pages

Subscribe to As If Productions aggregator - Drupal