__( 'Display title', '4wp-faq' ),
self::META_SEO_TITLE => __( 'SEO title', '4wp-faq' ),
self::META_SEO_DESC => __( 'SEO description', '4wp-faq' ),
] as $key => $description
) {
register_term_meta(
$taxonomy,
$key,
[
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => static function () {
return current_user_can( 'manage_categories' );
},
'description' => $description,
]
);
}
}
/**
* Fields on Add FAQ Category.
*/
public static function render_add_fields() {
?>
term_id, self::META_DISPLAY_TITLE, true );
$seo = (string) get_term_meta( $term->term_id, self::META_SEO_TITLE, true );
$desc = (string) get_term_meta( $term->term_id, self::META_SEO_DESC, true );
?>
|
|
|
|
|
|
'forwp_display_title',
self::META_SEO_TITLE => 'forwp_seo_title',
self::META_SEO_DESC => 'forwp_seo_description',
];
foreach ( $fields as $meta_key => $post_key ) {
if ( ! isset( $_POST[ $post_key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
continue;
}
$value = sanitize_text_field( wp_unslash( (string) $_POST[ $post_key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( '' === $value ) {
delete_term_meta( $term_id, $meta_key );
} else {
update_term_meta( $term_id, $meta_key, $value );
}
}
}
/**
* Active FAQ category term for the current request, if any.
*
* @return \WP_Term|null
*/
public static function get_active_term() {
$slug = Faq_Filter::get_active_slug();
if ( '' === $slug ) {
return null;
}
$taxonomy = Settings::get_taxonomy();
if ( ! taxonomy_exists( $taxonomy ) ) {
return null;
}
$term = get_term_by( 'slug', $slug, $taxonomy );
return $term instanceof \WP_Term ? $term : null;
}
/**
* Term for document H1 / title / meta — pretty category URLs only.
*
* @return \WP_Term|null
*/
public static function get_seo_term() {
if ( ! Faq_Filter::is_pretty_category_request() ) {
return null;
}
return self::get_active_term();
}
/**
* H1 / group heading: custom display title, else term name.
*
* @param \WP_Term $term Term.
* @return string
*/
public static function get_display_title( $term ) {
if ( ! $term instanceof \WP_Term ) {
return '';
}
$custom = get_term_meta( (int) $term->term_id, self::META_DISPLAY_TITLE, true );
if ( is_string( $custom ) && '' !== trim( $custom ) ) {
return trim( $custom );
}
return (string) $term->name;
}
/**
* Document title for a category URL.
*
* @param \WP_Term $term Term.
* @return string
*/
public static function get_seo_title( $term ) {
if ( ! $term instanceof \WP_Term ) {
return '';
}
$custom = get_term_meta( (int) $term->term_id, self::META_SEO_TITLE, true );
if ( is_string( $custom ) && '' !== trim( $custom ) ) {
return trim( $custom );
}
return self::get_display_title( $term );
}
/**
* Meta description for a category URL.
*
* @param \WP_Term $term Term.
* @return string
*/
public static function get_seo_description( $term ) {
if ( ! $term instanceof \WP_Term ) {
return '';
}
$custom = get_term_meta( (int) $term->term_id, self::META_SEO_DESC, true );
return is_string( $custom ) ? trim( $custom ) : '';
}
/**
* @param string $title Current title.
* @return string
*/
public static function filter_document_title( $title ) {
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term ) {
return $title;
}
$seo = self::get_seo_title( $term );
if ( '' === $seo ) {
return $title;
}
$site = get_bloginfo( 'name', 'display' );
return '' !== $site ? $seo . ' – ' . $site : $seo;
}
/**
* @param array $parts Title parts.
* @return array
*/
public static function filter_document_title_parts( $parts ) {
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term || ! is_array( $parts ) ) {
return $parts;
}
$seo = self::get_seo_title( $term );
if ( '' !== $seo ) {
$parts['title'] = $seo;
}
return $parts;
}
/**
* @param string $title Title from Yoast / Rank Math.
* @return string
*/
public static function filter_plain_title( $title ) {
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term ) {
return $title;
}
$seo = self::get_seo_title( $term );
if ( '' === $seo ) {
return $title;
}
$site = get_bloginfo( 'name', 'display' );
if ( is_string( $site ) && '' !== $site && false === strpos( $seo, $site ) ) {
return $seo . ' – ' . $site;
}
return $seo;
}
/**
* @param string $description Description from Yoast / Rank Math.
* @return string
*/
public static function filter_plain_description( $description ) {
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term ) {
return $description;
}
$desc = self::get_seo_description( $term );
return '' !== $desc ? $desc : $description;
}
/**
* Native meta description when no SEO plugin owns the tag.
*/
public static function render_meta_description() {
if ( defined( 'WPSEO_VERSION' ) || defined( 'RANK_MATH_VERSION' ) ) {
return;
}
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term ) {
return;
}
$desc = self::get_seo_description( $term );
if ( '' === $desc ) {
return;
}
echo '' . "\n";
}
/**
* Replace the first core Heading H1 with the category display title.
*
* @param string $content Block HTML.
* @param array $block Parsed block.
* @return string
*/
public static function filter_heading_block( $content, $block ) {
static $replaced = false;
if ( $replaced || ! is_string( $content ) || '' === $content ) {
return $content;
}
$term = self::get_seo_term();
if ( ! $term instanceof \WP_Term ) {
return $content;
}
$attrs = isset( $block['attrs'] ) && is_array( $block['attrs'] ) ? $block['attrs'] : [];
$level = isset( $attrs['level'] ) ? (int) $attrs['level'] : 2;
if ( 1 !== $level ) {
return $content;
}
$heading = self::get_display_title( $term );
if ( '' === $heading ) {
return $content;
}
$updated = preg_replace(
'/(]*>)(.*?)(<\/h1>)/is',
'$1' . esc_html( $heading ) . '$3',
$content,
1
);
if ( is_string( $updated ) && $updated !== $content ) {
$replaced = true;
return $updated;
}
return $content;
}
/**
* Primary FAQ category term ID for a registry post.
*
* @param int $post_id Registry post ID.
* @return int
*/
public static function get_primary_term_id( $post_id ) {
$post_id = (int) $post_id;
$ids = Registry_Content::get_post_term_ids( $post_id );
if ( empty( $ids ) ) {
return 0;
}
$primary = (int) get_post_meta( $post_id, self::PRIMARY_META, true );
if ( $primary > 0 && in_array( $primary, $ids, true ) ) {
return $primary;
}
return (int) $ids[0];
}
}