CRM-19665 Canonical URL for WP basepage pages is the basepage itself

    Details

    • Versioning Impact:
      Patch (backwards-compatible bug fixes)
    • Documentation Required?:
      None
    • Funding Source:
      Contributed Code
    • Verified?:
      No

      Description

      The canonical link element helps search engines and social media platforms know which URLs are minor variations of each other as opposed to distinct pages. WordPress puts together a canonical URL using the post's permalink.

      When using basepage URLs (as opposed to shortcodes), all CiviCRM pages use the same basepage, and WordPress includes the same canonical URL. Besides being terrible for SEO (event 2 is considered to be the same page as contribution page 1), it also means that sharing basepage-based CiviCRM pages on social media is ugly.

      This is a really big problem for PCPs, since there is no shortcode support for them (and anyway, you might not have the time to manually set up pages with shortcodes for each personal campaign page).

      WordPress 4.6.0 added a new filter for setting the canonical URL, and the popular Yoast WordPress SEO plugin has a filter for doing the same. We should post the canonical URLs to include all the parameters.

        Attachments

          Activity

          [CRM-19665] Canonical URL for WP basepage pages is the basepage itself
          Andrew Hunt added a comment -

          Maybe someday we'll establish a firm list of params that might be expected on a frontend URL, and we could also establish a canonical order of params. This would help say, for example, that
          http://example.org/civicrm/?page=CiviCRM&q=civicrm/event/register&reset=1&id=1&cid=0
          is based upon the canonical URL
          http://example.org/civicrm/?page=CiviCRM&q=civicrm/event/register&id=1&reset=1

          But until then, we can at the very least provide the whole query string and set the official basepage.

          Kevin Cristiano added a comment -

          Andrew Hunt Do we want to test for the version of WP we are on before loading the filter?
          I am also reluctant to start incuding filters for specific plugins. I'd prefer to leave it up the the developer. If we add Yoast's (35 million downloads) do we also make sure we work with All in One SEO (30 million downloads)? I would think it best to leave adding plugin specific filters to the developer. Ehat do you think?

          Andrew Hunt added a comment -

          Do you know what happens if you add a filter for something that doesn't exist yet? I'm totally happy to add a version check if you think it makes a difference.

          Re: Yoast, I agree in general. In this case, though, Yoast's filter predates the core filter and totally bypasses it. Yes, that's Yoast's fault, but it still has only been a little while since the other filter is out. If All in One is in the same boat (longstanding filter that's incompatible with get_canonical_url), I would also be in favor of working with that.

          Christian Wach added a comment -

          My $0.02: I agree entirely with Andrew, both on adding the WP 4.6 filter as is and supporting third party plugins. The CiviCRM plugin already has support for the Yoast plugin's Open Graph title. Further support where required seems sensible.

          Kevin Cristiano added a comment -

          From all I can tell (testing and docs) adding a filter where it does not exist is a soft fail. I had expected a Warning, but not seeing any in my logs.

          If we are going to do 3rd party support, I would definitely want All In One SEO (AIOSEO) support added.

          We can do that by adding

               // All in One SEO has separate way of establishing canonical URL
              add_filter( 'aioseop_canonical_url', array($this, 'basepage_canonical_url' ), 999);
          

          I've tested the patch with no SEO plugin, Yoast and AIOSEO and it works in all three cases. The original patch won't cover if AIOSEO is installed.

          Christian Wach added a comment - - edited

          Kevin Cristiano OT: it's a feature not a bug. If only more plugins would offer actions for their functionality instead of providing functions, then it all those endless

          if ( function_exists( 'some_plugin_function' ) ) { some_plugin_function() }

          tests could be replaced with

          do_action( 'some_plugin_action' )

          Andrew Hunt added a comment -

          I added the AIOSEO line, the param in the docblock, and a bunch of spaces everywhere. (I like to use the phpcs plugin in Atom, but it freaks out if you use the WordPress standard on this file because all of the lines are space-indented--you can't see the real problems among them.)

          Kevin Cristiano added a comment -

          tagged for 4.7.17.

          Tested again against current master branches, works propoerly. Tested with Yoast SEO, AIOSEO and with no SEO plugin. Works in all conditions.

          I consider this a bug fix, and would like to see in 4.7.17

            People

            • Assignee:
              Andrew Hunt
              Reporter:
              Andrew Hunt

              Dates

              • Created:
                Updated:
                Resolved: