Theme-Mentor icon indicating copy to clipboard operation
Theme-Mentor copied to clipboard

wp_head/wp_footer before closing head/body tags need to ignore blank lines and comments

Open mpeshev opened this issue 12 years ago • 4 comments

Still not TBD for all templates (keeping both performance and number of detected issues with a higher priority than preciseness), but could be added to the header and footer validations.

Sample report: http://wordpress.org/support/topic/wp_head-before-closing-head-tag-error?replies=2

A loop between the closing head before wp_head and body before wp_footer that ignores all blank lines and lines starting with any of the three comments in-between.

mpeshev avatar Feb 17 '13 20:02 mpeshev

The obvious fix for this issue and the problem with # wp_head(); is using a tokenizer. Then you could just iterate over all found tokens, ignore comments and whitespace, and get very exact results. It would be faster and less error prone than regexes.

thefuxia avatar Feb 17 '13 20:02 thefuxia

I have started with ignoring all blank lines and reverted that in the last commits due to the wrong line number reported. Tokenizer (or just verifying first logical symbol within an array of excludes) were considered options, I'm not sure how it would work for

wp_head();
/* some comment */ ugly stuff;
?>
</head>

If the all-edge-catcher could be done with small and lite steps, I'm all for it. Want to issue a pull req for that?

mpeshev avatar Feb 17 '13 20:02 mpeshev

I have literally no time this week for anything but work. :/

Here is an example that could be extended to real OOP. Just an illustration to show what I mean.

$path = dirname( __FILE__ ) . '/header.php';

if ( ! file_exists( $path ) )
    die( "$path not found" );

if ( ! $content = file_get_contents( $path ) )
    die( "could not read $path with file_get_contents()" );

$tokens = token_get_all( $content );

$result = new stdClass;
$result->path            = $path;
$result->wp_head         = FALSE;
$result->wp_head_is_last = FALSE;
$result->closing_php_tag = FALSE;



function token_walker( $token, $i, &$result )
{
    static $is_after_wp_head = FALSE;

    $name    = token_name( $token[0] );
    $content = trim( $token[1] );

    if ( NULL !== $name )
        print "$name: \n\t$content\n";
    else
        print "$token\n";

    # T_STRING is a function name
    if ( 'T_STRING' === $name && 'wp_head' === $content ) {
        $result->wp_head         = TRUE;
        $result->wp_head_is_last = TRUE;
        $is_after_wp_head        = TRUE;
    }

    if ( $is_after_wp_head ) {
        # @todo watch out for wrong HTML/PHP content
    }

    $result->closing_php_tag = 'T_CLOSE_TAG' === $name;

    #/*
    $result = apply_filters(
        'theme_mentor_token_parser',
        $result,
        $token
    );
    /**/
}
array_walk( $tokens, 'token_walker', $result );

var_export( $result );

The walker should be a class extending a base class, and the $result should follow the same pattern.

thefuxia avatar Feb 18 '13 19:02 thefuxia

I was unaware of the existence of token_get_all, I was going to use preg_split or more likely, since file() is reading the file line by line, iterate the lines between wp_head and and check for the pattern. Will be able to test that approach late Sun or Mon as I'm travelling on Thu and keeping up with the work as well.

mpeshev avatar Feb 19 '13 08:02 mpeshev