Skip to main content
info@drupalodyssey.com
Thursday, September 18, 2025
Contact

Main navigation

  • Home
  • Blog
    • all
    • Development
    • Community
    • Management
    • DevOps
    Photo by Ann H: https://www.pexels.com/photo/sneakers-beside-arrows-2646530/
    Shortlink Manager: A Hitchhiker's Guide to Better Analytics
    Sep 03, 2025
    https://www.pexels.com/photo/an-artist-s-illustration-of-artificial-intelligence-ai-this-image-was-inspired-neural-networks-used-in-deep-learning-it-was-created-by-novoto-studio-as-part-of-the-visualising-ai-proje-17483870/
    Unleashing the Power of Shortlink Manager: From Bulk Imports to Extensibility
    Sep 03, 2025
    Photo by Ramon Karolan: https://www.pexels.com/photo/orchestra-and-conductor-during-the-performance-13673492/
    Building a Smarter Shortlink: A Deep Dive into a Drupal Module
    Aug 25, 2025
    Photo by Ramon Karolan: https://www.pexels.com/photo/orchestra-and-conductor-during-the-performance-13673492/
    Building a Smarter Shortlink: A Deep Dive into a Drupal Module
    Aug 25, 2025
    Photo by Negative Space: https://www.pexels.com/photo/blue-and-green-pie-chart-97080/
    How to Automate UTM Parameters with a Drupal Module
    Aug 20, 2025
    Photo by Negative Space: https://www.pexels.com/photo/blue-and-green-pie-chart-97080/
    How to Automate UTM Parameters with a Drupal Module
    Aug 20, 2025
    Photo by Ivan Samkov: https://www.pexels.com/photo/text-4491829/
    Building a Custom Drupal Shortlink Manager: An SEO and Marketing Journey
    Aug 13, 2025
    Photo by  Anastasia  Shuraeva: https://www.pexels.com/photo/a-bearded-man-reading-a-burning-newspaper-7539726
    Bulletproof Your Drupal Data With Automated Nightly Backups
    Jul 30, 2025
    Photo by Tara Winstead: https://www.pexels.com/photo/white-ipad-on-white-paper-8386713/
    Is Your Content Calendar Working You to Death? Schedule It Away in Drupal!
    Jul 26, 2025
    Contractor happy with blueprints.
    Streamlining Drupal Deployments Using Drush and GitHub Actions CI/CD
    Jul 22, 2025
    Reduce, Reuse, Recycle
    Streamlined Content: Effortless PDF Display & Management in Drupal
    Jul 21, 2025
    Aluminum Cans Passing Through the Assembly Line by cottonbro studio on Pexels
    Automate and Simplify Your Drupal Workflow with Bash Scripts for Shared Hosting
    Jul 19, 2024
    Binoculars resting on newspapers.
    Evaluating Search and Replace Scanner: The Ultimate Tool for Drupal Bulk Content Edits?
    Jun 29, 2024
    People looking at a computer screen
    S3 File System Module Not Working with Media Entity Download Module? Here's the Fix
    Jun 18, 2024
    Mechanic hands working on an engine.
    Setting Up the Etsy OAuth2 Client For Use With The Etsy Shop Integration Module
    May 10, 2024
    Fashion designer sketching new garments.
    Crafting Your Online Store: Drupal's Role in Your Etsy Success
    May 09, 2024
    Socket toolbox
    Beginner's Guide: Getting Started With Drush for Efficient Drupal Development
    May 08, 2024
    Stargazing over mountians.
    Drupal-Powered Stargazing: A Module for NASA's Astronomy Picture of the Day
    Sep 15, 2023
    Computer screen with code.
    Learn How To Script Drupal Installations Using Drush
    Dec 08, 2014
    Scuba diver with Drupal mask.
    Scuba: Drupal Style
    Oct 16, 2014
    Woman frustrated with laptop.
    5 Reasons Your CMS Sucks
    Jul 24, 2013
    Two young men having a discussion in front of a computer.
    Deployment Module XSRF Patch Committed
    Jul 05, 2013
    Two young men having a discussion in front of a computer.
    Deployment Module XSRF Patch Committed
    Jul 05, 2013
    Application settings.
    Using PHP To Disable Internet Explorer Compatibility Mode
    Jun 04, 2013
  • Resources
  • About
  • SPACER
  • SPACER
  • SPACER
  • SPACER
  • SPACER
Search
Development

Building a Smarter Shortlink: A Deep Dive into a Drupal Module

August 25, 2025
The code for the Shortlink Manager module is now a public resource on GitHub. You can find the code and join the project at https://github.com/r0nn1ef/shortlink_manager.

Drupal Odyssey is supported by it's readers. When you purchase products or services using the links on this site, we may earn a small commission at no additional cost to you. Learn more

In the last post, I shared my journey of building the UTM Sets feature to eliminate tedious manual work. That was the "why." This post is the "how." Today, I'm going to pull back the curtain on the key components that make the whole system work: the Shortlink content entity, the controller that handles the redirects, and the service that keeps everything clean and organized – all tied together by the auto-generate form. Think of it as the data model, the helpful utility, and the conductor. This is a step-by-step look at how you can build a URL shortener in Drupal from the ground up.

The Shortlink Content Entity: Your Data Model

At the heart of the system is the Shortlink content entity. If you're a Drupal developer, you know this is where the action starts. A content entity is Drupal's way of storing and managing user-generated data, and in this case, it represents a single shortlink.

This non-fieldable content entity is where the magic of linking to other entities happens. The entity reference field, utm_set, connects this shortlink directly to your pre-configured UTM Set. This is the central piece that links the UTM automation from our last post to the actual redirect.

Key fields on this entity include:

path: The unique, human-readable slug for the shortlink.
utm_set: Our entity reference to the UTM Set we created.
target_entity_type & target_entity_id: This allows a single shortlink to point to any content or configuration entity on the site, such as a blog post or a product page.
destination_override: A field for a custom path, giving me the flexibility to point to external URLs or specific internal paths that aren't tied to an entity.

This entity isn't just a simple data bucket; its resolveDestinationUrl() method intelligently figures out where the user should go, checking for an override first and then falling back to the canonical URL of the target entity. This logic is a great example of keeping related functionality right where it belongs.

Module Configuration: Setting the Stage For The Show

Before you can get to the magic of auto-generation, you need to set the global rules for your shortlinks. That's the job of the ShortlinkSettingsForm. This is your module's central control panel, and it's where you decide the basic behaviors for every shortlink on your site.

Module settings form

This form handles key configurations like the path prefix—the part of the URL that comes before the unique slug. It also lets you choose the default HTTP redirect status (301, 307, etc.), which is a critical detail for SEO and browser caching. Most importantly, this is where you select which content entity types (like "node" or "media") are even available to be configured for automatic shortlink generation!. This setup ensures that your site has a single, consistent way of handling shortlinks.

The User Experience Magic: The Auto Generation Form

The Shortlink content entity is all fine and good and is usable by itself, the real magic for me was automating the process. This is where the ShortlinkAutoGenerateForm comes in. While the UTM Set entity provides the reusable data structure, this form is the user-facing bridge that connects the automation to your content.

This form allows site administrators to decide which content types – like blog posts, news articles, or product pages – should automatically get a shortlink. You can even configure a specific UTM Set to be applied by default, ensuring that every time a new blog post is created, it's not only getting a shortlink but is also instantly trackable.

Auto generate form

The form's code dynamically loads all your site's content types and bundles, presenting them in a clean, vertical tab interface. This is where you configure which entities will have a shortlink automatically created and which UTM Set to apply. It's the simple, "set-it-and-forget-it" piece of the puzzle that makes the whole module so powerful.

Wiring It Up

The settings on this form are implemented using hook_entity_insert() in the .module file; specifically shortlink_manager_entity_insert(). This hook is triggered every time an entity is saved. This implementation checks to see if the saved entity is an instance of ContentEntityBase (which is what every content entity in Drupal is based from).

If the entity meets the criteria, the function performs the following steps:

  • It checks the configuration to see if shortlink auto-generation is enabled for the specific content type and bundle of the new entity.
  • It retrieves the selected UTM Sets from the configuration.
  • It then loops through each selected UTM Set, creating a new Shortlink entity for each one.
  • Each new Shortlink entity gets a unique path and is linked to the newly created content entity and the appropriate UTM Set.
  • Finally, the new shortlinks are saved, automatically making them live and trackable on the site.

This small function is the behind-the-scenes engine that connects all the pieces. It listens for your content authors creating new material and, based on your configured rules, it instantly and effortlessly generates your smart shortlinks.

The ShortlinkRedirectController: The Conductor

A shortlink is useless if it doesn't do its job – redirecting the user. That's where the ShortlinkRedirectController steps in. Its single job is to act as the conductor, directing the incoming request to the correct destination.

The controller's redirectShortlink() method is the workhorse. Here's a quick look at its thought process when a user clicks a link:

Find the link: It queries the database for the unique shortlink path.
Determine the destination: It first checks for a destination_override on the shortlink entity. If one exists, it uses that. If not, it loads the target entity (node, user, etc.) and gets its canonical URL.
Apply the UTMs: It then checks if the shortlink has an associated UTM Set. If it does, it grabs the parameters and applies them to the destination URL's query string.
Redirect: Finally, it sends the user on their way with a clean and informative redirect response.

This separation of concerns – storing the data in the entity and handling the request in the controller – is a core principle of good Drupal architecture.

The ShortlinkManager Service: The Helpful Utility

You might be asking yourself: how do we ensure every shortlink path is unique? That's what the ShortlinkManager service is for. A service in Drupal is a reusable helper class that provides common functionality across your application.

My ShortlinkManager service contains a crucial method: generateShortlinkPath(). This method creates a random, unique string and adds a configurable prefix, guaranteeing that every new shortlink has its own unique, conflict-free path. The service also contains the pathExists() method, a simple database query to double-check for uniqueness before a path is saved. This is a perfect example of keeping a specific, reusable task outside of the entity or controller, so it can be called from anywhere in the module.

The power of this module lies in how these three pieces work together. The service provides the helper method to the entity to create the path, and the controller then uses the logic in the entity to handle the redirect. It's a cohesive system where each part has a clearly defined role.

What's Next?

In my next post, I'll cover a few final items that are the icing on the cake for this module that make it easier for content authors to benefit from all of this functionality that we've added as well as some thoughts on how this module could be enhanced and/or extended to customize it and make it work for your workflows.

I've covered a lot of ground here, but I hope this gives you a clear picture of how I built this module from the ground up. What are your thoughts on this architecture? Leave a comment below.

Author

Ron Ferguson

 

Next Blog

0 Comments

Login or Register to post comments.

Categories

Categories

  • Development
    (12)
  • Community
    (9)
  • Management
    (8)
  • DevOps
    (5)

Trending Blog

Trending Blog

Photo by Ramon Karolan: https://www.pexels.com/photo/orchestra-and-conductor-during-the-performance-13673492/
Building a Smarter Shortlink: A Deep Dive into a Drupal Module
25 Aug, 2025
Photo by Ann H: https://www.pexels.com/photo/sneakers-beside-arrows-2646530/
Shortlink Manager: A Hitchhiker's Guide to Better Analytics
03 Sep, 2025
Contractor happy with blueprints.
Streamlining Drupal Deployments Using Drush and GitHub Actions CI/CD
22 Jul, 2025
Photo by Ivan Samkov: https://www.pexels.com/photo/text-4491829/
Building a Custom Drupal Shortlink Manager: An SEO and Marketing Journey
13 Aug, 2025
Photo by Negative Space: https://www.pexels.com/photo/blue-and-green-pie-chart-97080/
How to Automate UTM Parameters with a Drupal Module
20 Aug, 2025

Tags

Tags

  • Drupal 10
  • Drupal 9
  • Drupal 11
  • Drupal 8
  • Drupal
  • Drupal 7
  • Drush
  • MySQL

Ad - Sidebar (300 x 250 AD)

Ad - Sidebar (300 x 600 AD)

Newsletter

Subscribe my Newsletter for new blog & tips Let’s stay updated!

Categories

  • Development
  • Community
  • Management

Useful Links

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Disclaimer
  • Cookies

Must Read

Photo by Ann H: https://www.pexels.com/photo/sneakers-beside-arrows-2646530/
Shortlink Manager: A Hitchhiker's Guide to Better Analytics
03 Sep, 2025
Photo by Tara Winstead: https://www.pexels.com/photo/white-ipad-on-white-paper-8386713/
Is Your Content Calendar Working You to Death? Schedule It Away in Drupal!
26 Jul, 2025
Aluminum Cans Passing Through the Assembly Line by cottonbro studio on Pexels
Automate and Simplify Your Drupal Workflow with Bash Scripts for Shared Hosting
19 Jul, 2024
Binoculars resting on newspapers.
Evaluating Search and Replace Scanner: The Ultimate Tool for Drupal Bulk Content Edits?
29 Jun, 2024

© 2025 All Rights Reserved.

Proud supporter of active military, veterans and first responders.