Last active
July 10, 2016 06:31
-
-
Save gormus/e2fcb8a42025fc9d66d244472e8251ca to your computer and use it in GitHub Desktop.
Digging In To Drupal 8: Code Snippets for Site Builders. (shamelessly copied from https://chromatichq.com/blog/digging-drupal-8-code-snippets-site-builders)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>The more I work with Drupal 8, the more I realize how much has changed for developers in the Drupal community. While the transition to a modern, object-oriented system is what's best for the longevity of the platform, it certainly doesn't come without challenges. As someone who doesn't come from an OOP background, I've found the transition difficult at times. In many cases, I know exactly <em>what</em> I want to do, just not <em>how</em> to do it the "Drupal 8 way". On top of this, tutorials and blog posts on D8 are all over the map in terms of accuracy. Many posts written during D8's development cycle are no longer applicable because of API changes, etc.</p> | |
<p>Below is a list of snippets that might be helpful to site builders or developers more familiar with D7 hooks and procedural. It might also be useful to OOP folks who are new to Drupal in general. My goal below is to add to and update these snippets over time.</p> | |
<h2>Routes & Links</h2> | |
<h3>Determine the Current Drupal Route</h3> | |
<p>Need to know what the current Drupal route is or need to run some logic against the current route? You can get the current route like so:</p> | |
<pre><code>$route = \Drupal::routeMatch()->getRouteName(); | |
</code></pre> | |
<p>To some, the <code>\Drupal::routeMatch()</code> syntax might look foreign (it did to me). Here's a rundown of what's happening here:</p> | |
<p>First, <code>\Drupal</code>. This is calling the global Drupal class, which, in Drupal 8, is a bridge between procedural and OO methods of writing Drupal code. The following comes from <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/class/Drupal/8.2.x">the documentation</a>:</p> | |
<blockquote> | |
<p>This class acts as a unified global accessor to arbitrary services within the system in order to ease the transition from procedural code to injected OO code.</p> | |
</blockquote> | |
<p>Right. Moving on to <code>::routeMatch()</code>. Here we're using the <code>routeMatch()</code> method which "Retrieves the currently active route match object." Simple enough. But what is "::" all about? <a href="http://stackoverflow.com/a/3173511">This StackOverflow answer</a> helped me to understand what that's all about.</p> | |
<p>From there, the <a href="https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Routing!RouteMatch.php/function/RouteMatch%3A%3AgetRouteName/8.2.x">getRouteName()</a> method returns the current route name as a string. Here are some example routes: <code>entity.node.canonical</code>, <code>view.frontpage</code> and <code>node.type_add</code>.</p> | |
<h3>Is this the Front Page Route?</h3> | |
<p>Need to check if the current route is the front page route? There's a service and method for that:</p> | |
<pre><code>// Is the current route/path the front page? | |
if ($is_front = \Drupal::service('path.matcher')->isFrontPage()) {} | |
</code></pre> | |
<p>Here we're calling the <code>path.matcher</code> service (defined in <code>/core/core.services.yml</code>) and using the <code>isFrontPage()</code> method. For more on services, check out the <a href="https://api.drupal.org/api/drupal/core!core.api.php/group/container/8.2.x">"Services and Dependency Injection Container"</a> documentation on api.drupal.org which helped me understand how all of these bits work together and the <em>why</em> of their structure.</p> | |
<h3>Get the Requested Path</h3> | |
<p>Need to know what the current page's requested path was, as opposed to the route? You can do this:</p> | |
<pre><code>$current_uri = \Drupal::request()->getRequestUri(); | |
</code></pre> | |
<h3>Redirect to a Specific Route</h3> | |
<p>Need to redirect to a specific page? In Drupal 7, you would likely handle this with <code>drupal_goto()</code> in your page callback function. In Drupal 8, you can use <code>RedirectResponse()</code> for that. Here is the <a href="https://www.drupal.org/node/2023537">relevant changelog</a>.</p> | |
<p>Here are some examples, borrowed heavily from said changelog. First, in procedural PHP:</p> | |
<pre><code>use Symfony\Component\HttpFoundation\RedirectResponse; | |
function my_redirect() { | |
return new RedirectResponse(\Drupal::url('user.page')); | |
} | |
</code></pre> | |
<p>Here is how you would use a Drupal 8 controller to accomplish the same thing:</p> | |
<pre><code>use Drupal\Core\Controller\ControllerBase; | |
class MyControllerClass extends ControllerBase { | |
public function foo() { | |
//... | |
return $this->redirect('user.page'); | |
} | |
} | |
</code></pre> | |
<h3>Links on the Fly</h3> | |
<p>Drupal 7 and prior relied heavily on the <a href="https://api.drupal.org/api/drupal/includes%21common.inc/function/l/7.x">l() function</a>. (In fact, I would wager this was my most used function over the years. In Drupal 8, if you need to create links on the fly, utilize the <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Link.php/class/Link/8.2.x">Link class</a></p> | |
<pre><code>$link = \Drupal\Core\Link::fromTextAndUrl($text, $url); | |
</code></pre> | |
<h2>Working with Entities</h2> | |
<h3>Query Database for Entities</h3> | |
<p>If you need to query the database for some nodes (or any other entity) you should use the entityQuery service. The syntax <a href="https://www.drupal.org/node/1343708">should be pretty familiar</a> to most D7 developers who have used EntityFieldQuery:</p> | |
<pre><code>// Query for some entities with the entity query service. | |
$query = \Drupal::entityQuery('node') | |
->condition('status', 1) | |
->condition('type', 'article') | |
->range(0, 10) | |
->sort('created', 'DESC'); | |
$nids = $query->execute(); | |
</code></pre> | |
<h3>Loading Entities</h3> | |
<p>If you need to load the actual entities, you can do so a number of ways:</p> | |
<p>While the following will technically work in Drupal 8:</p> | |
<pre><code>$node = entity_load_multiple('node', $nids); | |
</code></pre> | |
<p>This method has been <a href="https://api.drupal.org/api/drupal/core!includes!entity.inc/function/entity_load_multiple/8.2.x">deprecated in Drupal 8</a> and will be removed before Drupal 9, in favor of methods overriding <code>Entity::loadMultiple()</code>. To future-proof your code, you would do something like the following:</p> | |
<pre><code>$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids); | |
</code></pre> | |
<p>Here's how you would do similar for a single node:</p> | |
<pre><code>$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid); | |
</code></pre> | |
<p>Here are a few other entity snippets that might be useful:</p> | |
<pre><code>// Link to an entity using the entity's link method. | |
$author_link = $user->toLink(); | |
// Do the same thing, but customize the link text. | |
$author_link = $user->toLink('Some Custom Text'); | |
// Given a node object, here's how to determine its type: | |
$type = $node->getType(); | |
// To get the full user entity of the node's author: | |
$author = $node->getOwner(); | |
// To get the raw ID of the author of a node: | |
$author_id = $node->getOwnerId(); | |
</code></pre> | |
<h2>Image Styles</h2> | |
<p>Need to whip up an image using a particular image style on the fly? This will work for that:</p> | |
<pre><code>// Create an instance of an image using a specific image style, given a path to a file. | |
$style = \Drupal\image\Entity\ImageStyle::load('yourStyle_image'); | |
$img_path = $user->field_profile_some_image->entity->getFileUri(); | |
$img_style_url = $style->buildUrl($img_path); | |
</code></pre> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment