6

I used to show content from a catalog via the Views module, accessing an external database, so that all of the URLs would be something like /content?name=[name].

For various reasons, I've opted to import the content directly into Drupal as a unique content type. So now my URLs are /content/[name].

I need to implement a 301 redirect so that people going to the first URL (due to old bookmarks, links, etc.) are taken to the new URL.

Is it possible to set up a rule for the content type to accomplish this? The [name] field is the same so I feel like it should be a fairly straightforward thing to set up.

I did some searching around, and came up with RewriteRule ^/?content/([^/d]+)/?$ content?name=$1 [L,QSA]. I tried putting that in the .htaccess file after RewriteEngine on, and that didn't work. Am I following the proper .htaccess convention? I tried RewriteRule ^(.*)/content?name=(.*)$ $1/content/$2 [R,L] too, but it didn't work.

2
  • I'm not sure this can have anything to do with Drupal, but is about configuring an .htaccess redirect. Commented Aug 23, 2015 at 20:18
  • Hi, @astrosa. Check out the answers tagged with 'htaccess' over at Stack Overflow: stackoverflow.com/questions/tagged/.htaccess. it shouldn't be hard to find what you need. Commented Aug 24, 2015 at 4:58

2 Answers 2

11
+500

Why using .htaccess might not be an option

There are situations where setting up a redirect in your .htaccess file may not be an option, such as:

  • you are not allowed (= do not "have") edit access to your .htaccess file.
  • your provider does not allow specific directives in .htaccess files (which you'd want to use).
  • your Drupal site is running on IIS.
  • you don't have the required knowledge to correctly code the redirect in your .htaccess.
  • ... (what else?).

These are all reasons for using an approach based on the Rules module, as further detailed below.

Use Rules with 'Drupal is initializing'

Using the Rules module to get this to work, you should be able to use the "Drupal is initializing" event. That will ensure that the rule gets triggered BEFORE the actual content is shown.

Use a Regular Expression

The link that you want to "intercept", should be formatted in some type of regular expression, which you then use as your rules "Condition". so that you have a rule that corresponds to "before showing the actual content of something that matches a specific path ...". After you get that part to work, your Rules "action" should specify the actual redirect to be performed.

Remark: in this case you can also use "contains /content?name=" (instead of the regular expression) to get the text match working.

Sample rule

Refer to the "option 1" part of my answer to the question about "How to restrict access to a node via node/12 and allow access via a path like content/sometitle?", which contains this rule in export format:

{ "rules_check_url" : {
    "LABEL" : "Disallow node/* access",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, URLs like [site:current-page:url] are not allowed around here ...",
          "type" : "error"
        }
      },
      { "redirect" : { "url" : "no_access" } }
    ]
  }
}

Here are some suggested tunings of the above sample, to make it work for your case also:

  • machine name and label.
  • replace the node/* by your path (in the "label", and the regular expression).
  • replace the path in the action part of the rule by your target path (more details below), and check if you do want some type of error message to be shown (if not remove that part of the action).

Use the value of the [name] variable in the redirect

To make the value of the URL argument available as new variable to Rules, you can use the Rules URL Argument module. Here is a quote about it (from its project page):

... provides two rules conditions based on URL arguments:

  • check if a URL argument is present.
  • compare the value of an URL argument.

It also provides an action that makes the value of an URL argument available as new variable to Rules.

The newly provided Rules actions and conditions can be found under the "URL Argument" conditions and actions groups in the rule configuration interface.

For an example of how to use it, refer to Comment # 3 in issue # 1686360 which is about "Pass an amount to the url, ie; site/content/node-title?amount=10 or /node-title?=amount:10". Here is the relevant part of it:

  • add a "Check if URL argument exist" condition to your rule and set the "ARGUMENT" value to "amount".
  • add "Provide URL argument value" action to the rule and set "URL ARGUMENT NAME" value to "amount" and in the "Provided variables" section "ARGUMENT FROM URL - Variable name" to e.g. "amount_from_url".

You will now be able to use the amount value as a variable "amount-from-url" for other actions in this rule.

PS: If you're not familiar (enough/yet) with Rules, checkout the 32 (!!!) great, and free, video tutorials Learn the Rules framework.

8
  • 1
    This is interesting. So can you pass arguments from the original path to the redirect action? Since the poster wants to redirect /content?name=[name] to /content/[name], it might be helpful to show this. Commented Aug 23, 2015 at 20:51
  • 1
    I just tested the Rules URL Argument module and it works nicely. Definitely one to keep in the toolbox. Well done. I vote that this should be the accepted answer. Commented Aug 24, 2015 at 5:12
  • 1
    "Let others spread nice words about you ...", merci (= thank you) @othermachines ! FYI: to me the Rules module is becoming more and more like a "site building programming language", wouldn't you agree? The beauty of it being also that it should be relatively simply to upgrade such kind of "cutomizations" from D7 to D8 also. And I'd vote for Rules (and flag ...) to be considered as being moved to core in D9 ... Together with Views (in D8 core) you could do a lot of things with just D9 core ... Commented Aug 24, 2015 at 5:24
  • 1
    @Pierre.Vriens - Agreed on all counts. The down side to Rules (7.x) is it's a bit hard to wrap your head around, at first, but once you do it's awesomely powerful. Commented Aug 24, 2015 at 5:28
  • 1
    Indeed, Rules takes a little effort (learning) to get started with it (so is Views, and Flag ...). Thought I'd add my "PS" to this answer also here. Even though (to my knowledge) it does NOT cover 'Rules URL Argument', for me it was the "Key to the (Rules) kingdom" ... Commented Aug 24, 2015 at 5:42
2

For 301 redirects, you might want to look at the Global Redirect module. Some more details about it (from its project page):

GlobalRedirect is a simple module which…

  • Checks the current URL for an alias and does a 301 redirect to it if it is not being used.
  • Checks the current URL for a trailing slash, removes it if present and repeats check 1 with the new request.
  • Checks if the current URL is the same as the site_frontpage and redirects to the frontpage if there is a match.
  • Checks if the Clean URLs feature is enabled and then checks the current URL is being accessed using the clean method rather than the 'unclean' method.
  • Checks access to the URL. If the user does not have access to the path, then no redirects are done. This helps avoid exposing private aliased node's.
  • Make sure the case of the URL being accessed is the same as the one set by the author/administrator. For example, if you set the alias "articles/cake-making" to node/123, then the user can access the alias with any combination of case.
  • Most of the above options are configurable in the settings page. In Drupal 5 you can access this after enabling the globalredirect_admin module. In Drupal 6, the settings page is bundled into the module.
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.