resolver = $resolver; $this->renderer = $renderer; $this->parser = $parser ? $parser : new TokenParser(); } public function register() { add_filter( 'the_content', array( $this, 'filter_content' ), 9 ); add_filter( 'the_excerpt', array( $this, 'filter_excerpt' ), 9 ); add_filter( 'widget_text_content', array( $this, 'filter_widget' ), 9 ); // Block themes render headers, footers, templates, and synced patterns // as blocks outside the post content. add_filter( 'render_block', array( $this, 'filter_block' ), 9 ); // Classic menu labels are free text, where a copied token may be pasted. add_filter( 'nav_menu_item_title', array( $this, 'filter_menu' ), 9 ); } public function filter_menu( $title ) { return $this->filter( $title, 'menu' ); } public function filter_block( $content ) { return $this->filter( $content, 'block' ); } public function filter_content( $content ) { return $this->filter( $content, 'content' ); } public function filter_excerpt( $content ) { return $this->filter( $content, 'excerpt' ); } public function filter_widget( $content ) { return $this->filter( $content, 'widget' ); } public function filter( $content, $source = 'token' ) { if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || false === strpos( (string) $content, '{{glvr:' ) ) { return $content; } $parts = preg_split( '~(<(?:script|style|pre|code)\b[^>]*>.*?|)~is', (string) $content, -1, PREG_SPLIT_DELIM_CAPTURE ); foreach ( $parts as $index => $part ) { if ( 1 === $index % 2 ) { continue; } $parts[ $index ] = $this->replace_text_nodes( $part, $source ); } return implode( '', $parts ); } private function replace_text_nodes( $content, $source ) { $parts = preg_split( '~(<[^>]+>)~s', $content, -1, PREG_SPLIT_DELIM_CAPTURE ); foreach ( $parts as $index => $part ) { if ( 1 === $index % 2 ) { continue; } $parts[ $index ] = $this->parser->replace( $part, function ( $key, $original, $date_format ) use ( $source ) { $context = array( 'source' => 'token_' . sanitize_key( $source ) ); if ( BuiltinVariables::CURRENT_DATE_KEY === $key ) { $context['date_format'] = $date_format; } $resolved = $this->resolver->resolve( $key, $context ); if ( ! $resolved ) { return $original; } return $this->renderer->render( $resolved['value'], $resolved['variable']['type'], $resolved['context'] ); } ); } return implode( '', $parts ); } }