Drupal 7 Text Format Filters -- the Internal Links Module

Drupal 7 Text Format Filters -- the Internal Links Module

Working with Text format filters (aka Input format filters) can be a sticky point when building and configuring a Drupal site. Even experienced Drupal site administrators might sometimes forget a step when they turn on a module which provides an input filter -- then it can be confusing why things aren't working as expected. In this short lesson, we activate and configure the Internal Links module, which adds node titles as the HTML title attributes for links to other nodes on the site. Since we might normally do this from a WYSIWYG editor, we also configure the WYSIWYG module to use the ckEditor, and since the module also changes "node/123" -type links to "/some/custom/path" (rewrites links to use any custom URL aliases), we will briefly show how that is done, too. And since it's the most common method of creating those custom URL aliases for our nodes, we also touch on using Pathauto. Much of what is covered here applies to configuring and using any text format filter, so you can see the use of the Internal links module as simply an example which should be pretty easy to extend to other filters.

Required modules:

Recommended or helpful:

  • Token (dependency of Pathauto, but also one of the most useful Drupal modules)
  • Pathauto
  • Devel (only used here for auto-generation of test content, but a very useful module when developing a Drupal site)
  • WYSIWYG (with at least one editor library)


Contrib modules are typically added to 'sites/all/modules'

Add contributed modules to sites/all/modules

If you haven't already done so, please copy the unarchived Internal Links module folder (called intlinks) to your "sites/all/modules" directory or other appropriate location. If you are going to use a WYSIWYG editor and haven't already set it up, you can add that, too. During configuration of WYSIWYG, you'll see that most optional editors that it can integrate are stored in sites/all/libraries, a directory you'll need to create if it doesn't already exist in your site.

Now you can turn on the Internal Links module

Activate the Internal Links module

Go to: admin/modules
Toward the bottom of the modules page, in the "Other" section, you'll find the checkbox to activate the Internal Links module. Check that box and click on "Save configuration".

If you are going to follow all steps of this tutorial, you might as well also add and activate the other modules listed above (Pathauto, Token, WYSIWYG, etc). If you want to use the Devel module to generate nodes, users, comments, etc, you'll need to activate both the "Devel" and "Devel generate" modules ("Devel generate" is a sub-module within the Devel project, not a separate download).

Be sure you also have 'Clean URLs' enabled

Enable Clean URLs

If clean URLs aren't active, these particular input filters won't work.

Configure your Pathauto settings

Configure your settings for automated URL aliases

If you haven't already configured your automated URL alias generation, you can do so at:


I've decided to use 'blog/[node:title]' as the URL alias pattern for my blog content. It means that if I write an article with the title, "Drupal 7 Text Format Filters -- the Internal Links Module", my URL alias will automatically be:


The node title is converted for use by making it all lower case, replacing spaces with hyphens, and removing common words such as articles and prepositions. This keeps all the most important words in the URL, for good SEO.

Make sure you have some content to use...

Generate some content, if necessary

Since this is a simple demonstration of the module, I'm just going to use it on content that I've autogenerated with the Devel module. I'll create a few blog entries in English, with a URL alias for each. If you don't have the "blog" module turned on, you can create "Basic page", "Article", or other appropriate nodes. All of the generated nodes will have random "Lorem ipsum... " body text and titles.

Order of Text formats...

Rearrange desired order of text formats.


Before we configure the text formats, I'm going to drag the order so that users (Administrators) who have access to the "Full HTML" text format will use it, by default, when they create new content. If you change the order of the text formats, be sure to click on "Save changes" before you click on any other links (such as "configure" to edit the settings for any of the text formats).

Configure at least one text format to use the new filter(s)

Configure at least one text format for use with the desired filter(s)


This is a good time to talk about the different filters which are available by default. Obviously for the "Full HTML" format, it doesn't make much sense to "Limit allowed HTML tags" or "Display any HTML as plain text". If the first is checked, you no longer have "full HTML", do you? (And if that option is selected, for any text format with which you wish to use the Internal links filter, be sure that <a> tags are allowed.) If you have the "Display any HTML as plain text" checkbox selected, you will see the HTML code when viewing the node, rather than have it get rendered as formatted text. Those options are enabled for the "Filtered HTML" and "Plain text" text formats, respectively, but don't make sense to enable for the "Full HTML" text format.

The "Convert line breaks into HTML" option is convenient for text formats which will not get use of a WYSIWYG editor. I'm turning this option off since I've seen it cause issues when used in combination with a WYSIWYG editor.

I'll activate the "Internal links title filter", which is the primary filter in the Internal links module. It "looks" in the database to replace root-relative links, such as <a href="/node/50"> to include the URL alias for the node and the node title as the "title attribute" for the link, so when a visitor rolls over the link, they will see the linked article's title. It makes for good SEO and also enhances the UX. Note that it does add to your site's database queries, however, so it's best to ensure that you have a method of caching content so that page load times are not impacted (this could especially be an issue on pages with a lot of internal links).

I'm also checking the Internal Links 'hide bad' filter, which could probably have been better named. What it does is remove any root-relative links to articles or nodes which are not published or do not appear to exist. If you choose to use this filter, use it with care as it's possible that it could still remove some links which are valid. At some point, I plan to improve this filter to fine-tune its action and/or to create log entries in the Watchdog whenever it finds internal links it can't resolve. It should be safe to use for "normal use", but it won't currently recognize links with appended queries, etc. (This will likely be fixed in a coming release -- someone just needs to find the time to learn his way around working with Drupal.org's new Git versioning system. ;-)

The "Convert URLs to links" filter is convenient and simple. It means that if someone pastes in a full link to a URL, such as:


the URL will be rewritten to link it, i.e.:

<a href="http://example.com/article1.html">http://example.com/article1.html</a>.

If you have both the Internal links filters activated, use the "hide bad" filter first.

Rearrange the filters by 'weight' to make sure they are processed in the right order.

It should be obvious that a filter which removes a link, altogether, should run before a filter which would waste valuable database queries and processor cycles modifying that link. If the link is removed, it won't be there for the titles and URL aliases to be added; so it's most efficient to put the "hide bad" filter at the top.

[Note: This screenshot is from configuring the Filtered HTML text format, for which you might also want to enable the Internal links filter(s). Hence we see the "Limit allowed HTML tags" filter in the order process. For the Internal Links title filter to work, we'll need <a> tags in the list of allowed tags for any text format used. The order that text filters are run can be very important as some filters might change the input for filters that follow it in the order, so this is a good place to look if you ever experience issues with the display of filtered content.]

Add a simple link in one of your nodes...

Adding a root-relative link with the integrated WYSIWYG editor, ckEditor

Be sure that your link starts with a slash (is a normal "root-relative" link) if you want the title filter to operate on it. This screenshot displays what adding text links looks like when using the ckEditor library with the WYSIWYG module. Configuring a WYSIWYG editor profile for each text format is complex enough that we'll save that for another tutorial.

The link we added to the article looks like this (code view):

<a href="/node/50">typicus</a>. Indeed, if we edit the article, this is how the link will always look in the original source code.

It gets rewritten to look like this:

<a href="/blog/custom_url_alias" title="Amet Nisl Refero Ullamcorper">typicus</a>

If there were no custom URL, the rewritten link would only get the title added. And if we add a custom title to the original link, it will take the place of the actual node title (so site administrators have a way to modify the output, manually, if necessary).

Of course, if the linked node is unpublished (or the URL does not exist), and we have the "hide bad" filter activated, the "link" will be rewritten as simply:


And now you should see your filter in action...

When a visitor moves their mouse over the link, they see the title of the linked article

As long as the text format selected for the body field is the same as one you've configured to use the Internal links filter(s), you should see it working. In the status bar of your browser, you should also see that the link directs to your URL alias, too, rather than to "/node/50" (or whatever node you linked to).

If you don't see it in action, you may need to clear your site cache at:


Keep posted for further Drupal articles… we'll be back shortly.

About Lowell Montgomery

Lowell Montgomery works for Kairion, a subsidiary of Cocomore. He joined Cocomore to extend his skills in Drupal during an initial internship. Today, Lowell is kept busy in his role as Kairion’s Head of Quality Assurance, but he is still interested in Drupal and visits Drupalcons, DrupalCamps, code sprints, and other Drupal community events, whenever he has the chance.

Lowell Montgomery