This disguised campsite security system lets you know ‘hoos’ there

1 week 3 days ago

Motion sensors for home security stick out like a sore thumb, as their shiny white exteriors can be easily seen from a distance. This is made worse when camping, as small, discrete security devices that blend into their surroundings are even harder to come by. This is what inspired Sean Miller to create his own that uses […]

The post This disguised campsite security system lets you know ‘hoos’ there appeared first on Arduino Blog.

Arduino Team

Oomph Insights: Platform Metrics: Using Measurement to Optimize Performance

1 week 3 days ago
If you can’t measure it, you can’t improve it. It’s true for your business, and it’s true for your digital platform. Yet we’ve seen organizations from startups to enterprises neglect to incorporate measurement into their platform strategy. Data shows you what is and isn’t working in your platform. And, unlike most websites, platforms provide detailed information about known users across specific touchpoints — accurate, first-party data that doesn’t rely on cookies or fuzzy analytics. Actionable insights await; you just have to know what you’re measuring for. Here’s how to take a strategic…

Lullabot: Understanding Create Once Publish Everywhere (COPE)

1 week 3 days ago

Do you ever stop to think about how many "things" make up the internet? 

Not necessarily websites and social media networks, but instead the individual pieces of information. Every button. Every callout. Every image. Every teeny-tiny item description in your shopping cart.

A long time ago, if you wanted to write about something on the internet, you had to create it and publish it. And if you wanted to write about it again somewhere else, you had to create it again and publish it again. 

Axelerant Blog: Upgrade Drupal to PHP 8: Compiling extensions

1 week 3 days ago

In the last article, we discussed the changes required to get Drupal 9.1 running on PHP 8. At that time, we got the Drupal 9.1 dev release working on PHP 8.0.0 RC4 with a few patches. Since then, a lot has changed with many of those patches being committed and Drupal 9.2 dev open for development. But we’ll talk about all of that at a later date. Today, let’s look at getting some of the common PHP extensions and configure it to run with Drupal.

We left off at a point where we have plain Drupal 9.1 running on a plain PHP 8 RC4 setup. Drupal doesn’t require any extensions, not in PHP core, and that means we only had to enable extensions like gd, MySQL, and others to have Drupal 9.1 running. With that, we were able to install Umami and use the site without any problems at all. To enable those extensions, we only needed our docker-php-ext-enable script, which is part of the PHP base Docker imageSee the Dockerfile in the reference repository for the source code (lines 41-52). Installing other extensions that are not part of the PHP core is not quite that simple. Think of it this way: if a module is present in Drupal core, you can install it right after downloading Drupal. But if it is a contrib module, you have to download and install it separately. It’s the same thing with PHP extensions.

Why test with extensions?

Just as you probably wouldn’t have a Drupal site with at least one contrib module, you probably wouldn’t have a PHP installation without a few of the common extensions. Drupal core utilizes some of these extensions when they are available (such as APCu and YAML), which yields better performance. This means that even though the extensions are not technically required, you would most likely have them.

Axelerant Blog: Drupal 9.1 Is Here: Are You Ready to Upgrade?

1 week 3 days ago

As expected, Drupal 9.1 was released on schedule at the closure of 2020. We have already talked about the Drupal 9 release and how it’s a testament to the predictable and reliable nature of the Drupal release cycle. Drupal 9.1 takes a step forward by adding more features and releasing them as predicted.

In this blog, we will be discussing the new improvements and more that will follow. 

Is it worth upgrading?

The Drupal 9.1 stable release was out as expected on Dec 2nd, 2020. We previously advocated that if you are on Drupal 8.9, you needn’t hurry to upgrade to Drupal 9.0 as you would not see many new features. But that’s changed.

Drupal 9.1 adds exciting features and updates along with support for PHP 8 (we have previously written about making Drupal 9 compatible with PHP 8).

It’s also worth upgrading as Drupal 9.1 brings significant changes in the user interface for both sighted users and assistive technology.

Axelerant Blog: Developing a custom CSV validator in Drupal 8

1 week 3 days ago

In our recent project, we had a requirement from one of our clients where we need to validate data in CSV files based on custom requirements. This validated CSV would need to be imported into Drupal 8 into various content types.  

In this article, we will look at the requirement, the library, the architecture of the custom module, the different components of the module with some code samples and finally adding some ideas on how this module can be made more reusable and even contributed.

Introduction

Our client is a well known international NGO with offices worldwide, each with different types of data management systems and frameworks. They wanted a centralized system to manage the data from each of these offices. Having concluded that Drupal 8 was the ideal solution to implement that centralized system, the challenge was to set up a migration pipeline to bring in data from all of the offices and their varying frameworks. Consequently, the files generated by these systems needed to be validated for specific constraints before being imported into our Drupal system.

Axelerant Blog: Axelerant Celebrates Drupal By Giving Back

1 week 3 days ago

Open-source has the power to change the world, but, as we depend on it for democratic innovation, open-source also depends on us to thrive. At Axelerant, we know and own this; hence we’re constantly engaging in different open web communities, including Drupal’s.

Why are we writing this? First of all, we are always keen to shine a light on our team members because our people-first culture makes Axelerant succeed. Second, in a knowledge sharing spirit, we are willing to put out what has worked for us (and what we struggle with) regarding contributing and our community involvement.

We are celebrating Drupal’s 20th Anniversary, and we are proud of being part of that history for over a decade. What better way to celebrate than recognizing and sharing the stories of the people involved, the makers that keep the ball rolling.  

Celebrating our people and the community has been among our values since the beginning. Drupal’s 20th anniversary is one of those occasions where both of these values come together in demonstrating Axelerant’s commitment to be a productive part of the amazing Drupal community through its team.

Here, we want to share a few stories from team members who recently contributed and inspired us with their Drupal journey.

ComputerMinds.co.uk: Context-aware blocks

1 week 3 days ago

Defining your own Drupal block plugins in custom code is really powerful, but sometimes you can feel limited by what those blocks have access to. Your block class is like a blank canvas that you know you'll be pulling data into, but how should you get that data from the surrounding page? Often you have to resort to fetching the entity for the current page (e.g. on a node page), in order to get the values out of its fields that you want to display. Plugins can actually have a context passed to them directly - which can be common things like the logged-in user, or the node for the page being viewed. Let's have a look at how to tell Drupal what your plugin needs, so you don't have to do the donkey work.

If you've created a block plugin, you'll already be aware of the annotation comment just above the class name at the top of your PHP file. It might look something like this:

<?php namespace Drupal\mymodule\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * Show some fields for the current page in a block. * * This block can be placed anywhere on the page, so the fields could appear in * a sidebar, etc. * * @Block( * id = "specialityfields", * label = @Translation("Special fields"), * context_definitions = { * "node" = @ContextDefinition("entity:node", label = @Translation("Node")), * } * ) */ class SpecialityFields extends BlockBase {

Spot that last property in the annotation: the context_definitions part. That's where the block is defined as requiring a node context. The 'entity:node' part tells Drupal that the context should be a node; Drupal supports it just being 'entity' or various other things, such as 'language' or even 'string'. You can very easily get hold of the context for your block, e.g. in the build() method of your class, allowing your block to adapt to its surroundings:

/** * {@inheritdoc} */ public function build() { $entity = $this->getContextValue('node'); return $entity->field_my_thing->view(); }

I've used a very simple tip from our article on rendering fields for the output of this method. But the key here is the use of $this->getContextValue('node');. Our block class is extending the BlockBase base class, which gives us that getContextValue() method to use (via ContextAwarePluginTrait, which you could use directly in your plugin class if you're not extending BlockBase). The 'node' parameter that we've passed to it should match the key of the context definition array up in the class annotation - it's just a key that you could rename to anything helpful. Plugins can specify multiple contexts, so distinguish each with appropriate names.

In this basic case of using a node, the chances are that you're just wanting to use the node that the current page is for. Drupal core has 'context provider' services - one of which provides exactly that. Most basic Drupal installations probably won't have other context providers that provide nodes, so the node just gets automatically passed through, without you having to do anything else to wire it up. Brilliantly, the block will only show up when on a node page, regardless of any other visibility settings in the block placement configuration. You can bypass that by flagging that the context is optional in its definition - spot the 'required' key:

context_definitions = { "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node")), }

A slightly more interesting example is for users, as Drupal core can potentially provide two possible contexts for them:

  1. The currently logged-in user, or at least the entity object representing the anonymous user if no-one is logged in.
  2. The user being viewed - which will only be available when visiting an actual user profile page.

When there are more than one possible contexts available, block placement configuration forms offer the choice of which to use. So you might want a block in a sidebar on profile pages to show things to do with the user who owns that profile - in which case, select the 'User being viewed' option in the dropdown. Otherwise the data your block shows will just be about you, the logged-in user, even when looking at someone else's profile. Internally, your selection in the dropdown gets stored as the context mapping, which you can see in the exported configuration files for any context-aware block (including those automatically selected due to only one context being available).

If all this talk of Contexts is reminding you of something, it's because the concept was brought into core after being used with Panels in older versions of Drupal. Core's Layout Builder now uses it heavily, usually to pass the entity being viewed into the blocks that represent fields etc that you place in each section. For anyone that really wants to know, those blocks are defined using a plugin deriver - i.e. a separate class that defines multiple possible block plugins, dynamically. In the case of Layout Builder, that means a block is dynamically created for every field an entity can have. If you use plugin derivers, you might need dynamically set up context definitions too. So in the deriver's getDerivativeDefinitions() method, you could have something like this, the PHP equivalent of the regular block's static annotation:

/** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { $derivative['context_definitions'] = [ 'node' => new ContextDefinition('entity:node', $this->t('Node')), ]; $this->derivatives['your_id'] = $derivative; return $this->derivatives; }

I've only lightly touched on context provider services, but you can of course create your own too. I recently used one to provide a related 'section' taxonomy term to blocks, which pulls from an entity reference field that nearly all entity types & bundles on a site had. The blocks display fields from the current page's parent section. It made for a common interface separating that 'fetching' code from the actual block 'display' code. I recommend understanding, copying & adapting the NodeRouteContext class (and accompanying service definition in node.services.yml) for your case if you have a similar need.

I hope this awareness of context allows your blocks to seamlessly adapt to their surroundings like good chameleons, and maybe even write better code along the way. I know I've had many blocks in the past that each had their own ways of pulling relevant data for a page. Contexts seem like the answer to me as they separate fetching and display data, so each part can be done well. Getting creative with making my own context types and context providers was fun too, though probably added unnecessary complication in the end. Let me know in the comments what context-aware plugins enable you to do!

 

Photo by Andrew Liu on Unsplash

Coolest Projects 2021: young people’s journeys & special judges’ favourites

1 week 3 days ago

Wow, we haven’t stopped smiling since yesterday’s live Coolest Projects celebration! Hosts Maddie Moate and Greg Foot led us through a live online event jam-packed with stories from participants, cool tech creations, and inspiring messages from our special judges. AND they revealed whose projects the judges picked as their favourites from among all of this…

The post Coolest Projects 2021: young people’s journeys & special judges’ favourites appeared first on Raspberry Pi.

Helen Drury

Epilet is a tinyML-powered bracelet for detecting epileptic seizures

1 week 4 days ago

Epilepsy can be a very terrifying and dangerous condition, as sufferers often experience seizures that can result in a lack of motor control and even consciousness, which is why one team of developers wanted to do something about it. They came up with a simple yet clever way to detect when someone is having a convulsive […]

The post Epilet is a tinyML-powered bracelet for detecting epileptic seizures appeared first on Arduino Blog.

Arduino Team

This sensory extension puppet lets you detect magnetic fields like a bird

1 week 4 days ago

Birds have an amazing sense of direction that aids in migrating across vast distances, and scientists think this is due to their ability to detect magnetic fields — just like a compass. Chris Hill on Instructables wanted a way to experience this for himself by using a sensor and some sort of feedback mechanism to feel a magnetic […]

The post This sensory extension puppet lets you detect magnetic fields like a bird appeared first on Arduino Blog.

Arduino Team