/**
* Get the "Continue Reading" URL for a novel.
*
* @param int $novel_id Novel post ID.
* @return string|null Chapter permalink or null.
*/
function webnovel_get_continue_reading_url( $novel_id ) {
// Check server-side history for logged-in users.
if ( is_user_logged_in() ) {
$history = \WebNovel\Reading_Tracker::get_last_read( $novel_id );
if ( $history && ! empty( $history['chapter_id'] ) ) {
$chapter = get_post( $history['chapter_id'] );
if ( $chapter && 'publish' === $chapter->post_status ) {
return get_permalink( $chapter->ID );
}
}
}
// Fallback to first chapter.
$chapters = \WebNovel\CPT_Chapter::get_chapters_by_novel( $novel_id, array( 'posts_per_page' => 1 ) );
if ( ! empty( $chapters ) ) {
return get_permalink( $chapters[0]->ID );
}
return null;
}
/**
* Output Open Graph and Twitter Card meta tags.
*
* @return void
*/
function webnovel_social_meta_tags() {
if ( ! is_singular( array( 'novel', 'chapter' ) ) && ! is_post_type_archive( 'novel' ) && ! is_tax( array( 'genre', 'novel_status' ) ) ) {
return;
}
$title = wp_get_document_title();
$url = esc_url( home_url( add_query_arg( array() ) ) );
$site_name = get_bloginfo( 'name' );
$description = '';
// Determine image and description.
$image = '';
if ( is_singular( 'novel' ) && has_post_thumbnail() ) {
$image = get_the_post_thumbnail_url( null, 'novel-cover-large' );
$description = get_post_meta( get_the_ID(), '_webnovel_synopsis', true );
if ( ! $description ) {
$description = get_the_excerpt();
}
} elseif ( is_singular( 'chapter' ) ) {
$novel_id = wp_get_post_parent_id( get_the_ID() );
if ( $novel_id && has_post_thumbnail( $novel_id ) ) {
$image = get_the_post_thumbnail_url( $novel_id, 'novel-cover-large' );
}
$description = get_the_excerpt();
if ( ! $description ) {
$description = sprintf(
/* translators: %s: Novel title */
__( 'Read the latest chapter of %s.', 'webnovel' ),
get_the_title( $novel_id )
);
}
} elseif ( is_post_type_archive( 'novel' ) ) {
$description = __( 'Discover amazing web novels and stories.', 'webnovel' );
}
$description = $description ? wp_strip_all_tags( $description ) : get_bloginfo( 'description' );
$description = wp_trim_words( $description, 40 );
// Open Graph.
echo '' . "\n";
echo '' . "\n";
echo '' . "\n";
echo '' . "\n";
echo '' . "\n";
if ( $image ) {
echo '' . "\n";
}
// Twitter Card.
echo '' . "\n";
echo '' . "\n";
echo '' . "\n";
if ( $image ) {
echo '' . "\n";
}
// Schema.org JSON-LD.
if ( is_singular( 'novel' ) ) {
webnovel_schema_novel();
} elseif ( is_singular( 'chapter' ) ) {
webnovel_schema_chapter();
}
}
add_action( 'wp_head', 'webnovel_social_meta_tags', 5 );
/**
* Output Schema.org Book structured data for a novel.
*
* @return void
*/
function webnovel_schema_novel() {
$novel_id = get_the_ID();
$author = get_post_meta( $novel_id, '_webnovel_author', true );
$synopsis = get_post_meta( $novel_id, '_webnovel_synopsis', true );
$genres = get_the_terms( $novel_id, 'genre' );
$status = get_the_terms( $novel_id, 'novel_status' );
$image = has_post_thumbnail() ? get_the_post_thumbnail_url( null, 'full' ) : '';
$chapter_count = webnovel_get_chapter_count( $novel_id );
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'Book',
'name' => get_the_title(),
'url' => get_permalink(),
'description' => $synopsis ? wp_strip_all_tags( $synopsis ) : get_the_excerpt(),
'numberOfPages' => $chapter_count,
);
if ( $author ) {
$schema['author'] = array(
'@type' => 'Person',
'name' => $author,
);
}
if ( $image ) {
$schema['image'] = $image;
}
if ( $genres && ! is_wp_error( $genres ) ) {
$schema['genre'] = wp_list_pluck( $genres, 'name' );
}
if ( $status && ! is_wp_error( $status ) ) {
$schema['bookEdition'] = $status[0]->name;
}
// BreadcrumbList.
$schema = array(
'@context' => 'https://schema.org',
'@graph' => array(
$schema,
array(
'@type' => 'BreadcrumbList',
'itemListElement' => array(
array(
'@type' => 'ListItem',
'position' => 1,
'name' => __( 'Home', 'webnovel' ),
'item' => home_url( '/' ),
),
array(
'@type' => 'ListItem',
'position' => 2,
'name' => __( 'Novels', 'webnovel' ),
'item' => get_post_type_archive_link( 'novel' ),
),
array(
'@type' => 'ListItem',
'position' => 3,
'name' => get_the_title(),
'item' => get_permalink(),
),
),
),
),
);
echo '' . "\n";
}
/**
* Output Schema.org Chapter / Article structured data.
*
* @return void
*/
function webnovel_schema_chapter() {
$chapter_id = get_the_ID();
$novel_id = wp_get_post_parent_id( $chapter_id );
$novel = $novel_id ? get_post( $novel_id ) : null;
$word_count = get_post_meta( $chapter_id, '_webnovel_word_count', true );
$image = $novel_id && has_post_thumbnail( $novel_id ) ? get_the_post_thumbnail_url( $novel_id, 'full' ) : '';
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'Chapter',
'headline' => get_the_title(),
'url' => get_permalink(),
'datePublished' => get_the_date( 'c' ),
'dateModified' => get_the_modified_date( 'c' ),
'wordCount' => absint( $word_count ),
);
if ( $image ) {
$schema['image'] = $image;
}
if ( $novel ) {
$schema['isPartOf'] = array(
'@type' => 'Book',
'name' => $novel->post_title,
'url' => get_permalink( $novel_id ),
);
}
echo '' . "\n";
}
studentfocusspots.com
https://validator.w3.org/feed/docs/rss2.html
-
Latest Updates
-
Privacy Policy
-
Pick-Up Request
-
PBS Ch66: Afraid of Losing
-
ICSST CH69: Progress: 100%
-
ICSST CH68: The Victim
-
WTNL Chapter 378.2
-
WTNL Chapter 379
-
PBS CH69: Test
-
PBS CH68: Stimulation
-
PBS CH67: The Test Subject
-
ICSST CH70: Performance
-
UE CH49: Connecting Link
-
UE CH48: Connecting Link
-
WTNL Chapter 378.1
-
POST PAGE
-
The World Controlled By Dice
-
ICSST CH67: Twin Carvings
-
WTNL Chapter 375.2
-
WTNL Chapter 374.2
-
WTNL Chapter 377.2
-
WTNL Chapter 377.1
-
ICSST CH66: Just Ridiculous
-
WTNL Chapter 375.1
-
WTNL Chapter 376
-
ICSST CH65: Home TurfÂ
-
PBS CH65: The Past
-
WTNL Chapter 374.1
-
Stairs of Paradox
-
ICSST CH64: Kill the Boss
-
UE CH47: Connecting Link
-
WTNL Chapter 373
-
Lantern: Reflection of the Peach Blossoms
-
UE CH46: Connecting Links
-
PBS Ch64: Chief of Technology
-
Peach Blossom Spring
-
Welcome to the Nightmare Live
-
ICSST CH63: Tide Rider
-
This marriage won’t end in divorce?!
-
The Daily Life of the Reborn Adopted Son of a Wealthy Family
-
Untamed Enemy
-
The Substitute Awakens
-
Privacy Policy
-
Survivorship Bias
-
Mirror Puzzle
-
Replacing the Evil Way
-
Terms and Conditions
-
The Feast of Filth