Make WordPress Core

Changeset 55261


Ignore:
Timestamp:
02/07/2023 02:03:26 PM (4 years ago)
Author:
audrasjb
Message:

Privacy: Add rel="privacy-policy" to the Privacy Policy link.

This changeset adds a rel="privacy-policy" attribute to user-facing links to the Privacy Policy of the website, when a privacy policy page is set and available. While this rel value is still a RFC of the Link Types HTML specification, this changeset helps to make Privacy Policy link more discoverable for user agents and HTML parsers.

Props dshanske, audrasjb, bhavz-10, bookwyrm, faisal03, JeffPaul, peterwilsoncc, paapst, davidbaumwald, costdev, robinwpdeveloper, kawserz.
Fixes #56345.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-walker-nav-menu.php

    r54178 r55261  
    183183                        $atts['rel'] = $menu_item->xfn;
    184184                }
    185                 $atts['href']         = ! empty( $menu_item->url ) ? $menu_item->url : '';
     185
     186                if ( ! empty( $menu_item->url ) ) {
     187                        if ( get_privacy_policy_url() === $menu_item->url ) {
     188                                $atts['rel'] = empty( $atts['rel'] ) ? 'privacy-policy' : $atts['rel'] . ' privacy-policy';
     189                        }
     190
     191                        $atts['href'] = $menu_item->url;
     192                } else {
     193                        $atts['href'] = '';
     194                }
     195
    186196                $atts['aria-current'] = $menu_item->current ? 'page' : '';
    187197
  • trunk/src/wp-includes/link-template.php

    r55239 r55261  
    46654665        if ( $privacy_policy_url && $page_title ) {
    46664666                $link = sprintf(
    4667                         '<a class="privacy-policy-link" href="%s">%s</a>',
     4667                        '<a class="privacy-policy-link" href="%s" rel="privacy-policy">%s</a>',
    46684668                        esc_url( $privacy_policy_url ),
    46694669                        esc_html( $page_title )
  • trunk/tests/phpunit/tests/link/getThePrivacyPolicyLink.php

    r54090 r55261  
    161161                return 'Policy: ' . $privacy_policy_url;
    162162        }
     163
     164        /**
     165         * Tests that `get_the_privacy_policy_link()` adds `rel="privacy-policy"`.
     166         *
     167         * @ticket 56345
     168         */
     169        public function test_get_the_privacy_policy_link_should_add_rel_privacy_policy() {
     170                update_option( 'wp_page_for_privacy_policy', self::$privacy_policy_page_id );
     171
     172                $this->assertStringContainsString( 'rel="privacy-policy"', get_the_privacy_policy_link() );
     173        }
    163174}
  • trunk/tests/phpunit/tests/menu/walker-nav-menu.php

    r54090 r55261  
    153153                );
    154154        }
     155
     156        /**
     157         * Tests that `Walker_Nav_Menu::start_el()` adds `rel="privacy-policy"`.
     158         *
     159         * @ticket 56345
     160         *
     161         * @covers Walker_Nav_Menu::start_el
     162         *
     163         * @dataProvider data_walker_nav_menu_start_el_should_add_rel_privacy_policy_to_privacy_policy_url
     164         *
     165         * @param string $expected The expected substring containing the "rel" attribute and value.
     166         * @param string $xfn      Optional. The XFN value. Default empty string.
     167         * @param string $target   Optional. The target value. Default empty string.
     168         */
     169        public function test_walker_nav_menu_start_el_should_add_rel_privacy_policy_to_privacy_policy_url( $expected, $xfn = '', $target = '' ) {
     170                $post_id = self::factory()->post->create(
     171                        array(
     172                                'post_type'   => 'page',
     173                                'post_title'  => 'Test Privacy Policy',
     174                                'post_status' => 'publish',
     175                        )
     176                );
     177
     178                // Set the privacy policy page.
     179                update_option( 'wp_page_for_privacy_policy', $post_id );
     180                $privacy_policy_id = (int) get_option( 'wp_page_for_privacy_policy' );
     181
     182                $output = '';
     183
     184                $item = array(
     185                        'ID'        => $privacy_policy_id,
     186                        'object_id' => $privacy_policy_id,
     187                        'title'     => 'Privacy Policy',
     188                        'target'    => $target,
     189                        'xfn'       => $xfn,
     190                        'current'   => false,
     191                        'url'       => get_privacy_policy_url(),
     192                );
     193
     194                $args = array(
     195                        'before'      => '',
     196                        'after'       => '',
     197                        'link_before' => '',
     198                        'link_after'  => '',
     199                );
     200
     201                $this->walker->start_el( $output, (object) $item, 0, (object) $args );
     202
     203                $this->assertStringContainsString( $expected, $output );
     204        }
     205
     206        /**
     207         * Data provider.
     208         *
     209         * @return array[]
     210         */
     211        public function data_walker_nav_menu_start_el_should_add_rel_privacy_policy_to_privacy_policy_url() {
     212                return array(
     213                        'no xfn value'                          => array(
     214                                'expected' => 'rel="privacy-policy"',
     215                        ),
     216                        'an xfn value'                          => array(
     217                                'expected' => 'rel="nofollow privacy-policy"',
     218                                'xfn'      => 'nofollow',
     219                        ),
     220                        'no xfn value and a target of "_blank"' => array(
     221                                'expected' => 'rel="noopener privacy-policy"',
     222                                'xfn'      => '',
     223                                'target'   => '_blank',
     224                        ),
     225                        'an xfn value and a target of "_blank"' => array(
     226                                'expected' => 'rel="nofollow privacy-policy"',
     227                                'xfn'      => 'nofollow',
     228                                'target'   => '_blank',
     229                        ),
     230                );
     231        }
     232
     233        /**
     234         * Tests that `Walker_Nav_Menu::start_el()` does not add `rel="privacy-policy"` when no
     235         * privacy policy page exists.
     236         *
     237         * @ticket 56345
     238         *
     239         * @covers Walker_Nav_Menu::start_el
     240         */
     241        public function test_walker_nav_menu_start_el_should_not_add_rel_privacy_policy_when_no_privacy_policy_exists() {
     242                $post_id = self::factory()->post->create(
     243                        array(
     244                                'post_type'   => 'page',
     245                                'post_title'  => 'Test Privacy Policy',
     246                                'post_status' => 'publish',
     247                        )
     248                );
     249
     250                // Do not set the privacy policy page.
     251
     252                $output = '';
     253
     254                $item = array(
     255                        'ID'        => $post_id,
     256                        'object_id' => $post_id,
     257                        'title'     => 'Privacy Policy',
     258                        'target'    => '',
     259                        'xfn'       => '',
     260                        'current'   => false,
     261                        'url'       => get_the_permalink( $post_id ),
     262                );
     263
     264                $args = array(
     265                        'before'      => '',
     266                        'after'       => '',
     267                        'link_before' => '',
     268                        'link_after'  => '',
     269                );
     270
     271                $this->walker->start_el( $output, (object) $item, 0, (object) $args );
     272
     273                $this->assertStringNotContainsString( 'rel="privacy-policy"', $output );
     274        }
     275
     276        /**
     277         * Tests that `Walker_Nav_Menu::start_el()` does not add `rel="privacy-policy"` when no URL
     278         * is passed in the menu item object.
     279         *
     280         * @ticket 56345
     281         *
     282         * @covers Walker_Nav_Menu::start_el
     283         */
     284        public function test_walker_nav_menu_start_el_should_not_add_rel_privacy_policy_when_no_url_is_passed() {
     285                $post_id = self::factory()->post->create(
     286                        array(
     287                                'post_type'   => 'page',
     288                                'post_title'  => 'Test Privacy Policy',
     289                                'post_status' => 'publish',
     290                        )
     291                );
     292
     293                // Set the privacy policy page.
     294                update_option( 'wp_page_for_privacy_policy', $post_id );
     295                $privacy_policy_id = (int) get_option( 'wp_page_for_privacy_policy' );
     296
     297                $output = '';
     298
     299                $item = array(
     300                        'ID'        => $privacy_policy_id,
     301                        'object_id' => $privacy_policy_id,
     302                        'title'     => 'Privacy Policy',
     303                        'target'    => '',
     304                        'xfn'       => '',
     305                        'current'   => false,
     306                        // Do not pass URL.
     307                );
     308
     309                $args = array(
     310                        'before'      => '',
     311                        'after'       => '',
     312                        'link_before' => '',
     313                        'link_after'  => '',
     314                );
     315
     316                $this->walker->start_el( $output, (object) $item, 0, (object) $args );
     317
     318                $this->assertStringNotContainsString( 'rel="privacy-policy"', $output );
     319        }
     320
     321        /**
     322         * Tests that `Walker_Nav_Menu::start_el()` does not add `rel="privacy-policy"` when the
     323         * menu item's ID does not match the privacy policy page, but the URL does.
     324         *
     325         * @ticket 56345
     326         *
     327         * @covers Walker_Nav_Menu::start_el
     328         */
     329        public function test_walker_nav_menu_start_el_should_add_rel_privacy_policy_when_id_does_not_match_but_url_does() {
     330                $post_id = self::factory()->post->create(
     331                        array(
     332                                'post_type'   => 'page',
     333                                'post_title'  => 'Test Privacy Policy',
     334                                'post_status' => 'publish',
     335                        )
     336                );
     337
     338                // Set the privacy policy page.
     339                update_option( 'wp_page_for_privacy_policy', $post_id );
     340                $privacy_policy_id = (int) get_option( 'wp_page_for_privacy_policy' );
     341
     342                $output = '';
     343
     344                // Ensure the ID does not match the privacy policy.
     345                $not_privacy_policy_id = $privacy_policy_id - 1;
     346
     347                $item = array(
     348                        'ID'        => $not_privacy_policy_id,
     349                        'object_id' => $not_privacy_policy_id,
     350                        'title'     => 'Privacy Policy',
     351                        'target'    => '',
     352                        'xfn'       => '',
     353                        'current'   => false,
     354                        'url'       => get_privacy_policy_url(),
     355                );
     356
     357                $args = array(
     358                        'before'      => '',
     359                        'after'       => '',
     360                        'link_before' => '',
     361                        'link_after'  => '',
     362                );
     363
     364                $this->walker->start_el( $output, (object) $item, 0, (object) $args );
     365
     366                $this->assertStringContainsString( 'rel="privacy-policy"', $output );
     367        }
    155368}
Note: See TracChangeset for help on using the changeset viewer.