Tetrakern / fictioneer

A web fiction theme for WordPress.
https://fictioneer-theme.com
GNU General Public License v3.0
104 stars 16 forks source link

The words count is incorrect. #19

Closed babydu closed 8 months ago

babydu commented 8 months ago

When I write in Chinese, it can't count the words of the chapter. this is the test page: https://novel2.littleprince.site/chapter/qiandu90/ 图片

Tetrakern commented 8 months ago

Hello, thanks for the bug report.

The issue is that the PHP functions to count words (str_word_count) is not compatible with Chinese, or any other character based language, apparently. I must admit I never expected Fictioneer to be used with those languages, I simply did not account for the possibility. Honestly, I'm surprised it works, but then again it's WordPress.

Preliminary investigations into alternative counting methods were... not promising. The whole "words" concept does not seem to apply well to Chinese, Korean, Japanese, etc. anyway.

What I can do is adding an option to count multi-byte characters instead. I'm just not sure if that is what you want, I'm not familiar with the language and its peculiarities. So you tell me.

If you set up a child theme, you can try yourself by adding this to the functions.php:

// Remove function that counts words
remove_action( 'save_post', 'fictioneer_save_word_count' );

// Add function that counts characters
function child_save_character_count( $post_id ) {
  // Prevent multi-fire
  if ( fictioneer_multi_save_guard( $post_id ) ) {
    return;
  }

  // Prepare
  $content = get_post_field( 'post_content', $post_id );
  $content = strip_shortcodes( $content );
  $content = strip_tags( $content );

  // Count characters instead of words
  $word_count = mb_strlen( $content );

  // Remember
  update_post_meta( $post_id, '_word_count', $word_count );
}
add_action( 'save_post', 'child_save_character_count' );

If that works for you, I can add it as new option to the theme.

Edit: Note that this will not update existing word counts. This is only done when you save a post.

babydu commented 8 months ago

Hello, thanks for the bug report.

The issue is that the PHP functions to count words (str_word_count) is not compatible with Chinese, or any other character based language, apparently. I must admit I never expected Fictioneer to be used with those languages, I simply did not account for the possibility. Honestly, I'm surprised it works, but then again it's WordPress.

Preliminary investigations into alternative counting methods were... not promising. The whole "words" concept does not seem to apply well to Chinese, Korean, Japanese, etc. anyway.

What I can do is adding an option to count multi-byte characters instead. I'm just not sure if that is what you want, I'm not familiar with the language and its peculiarities. So you tell me.

If you set up a child theme, you can try yourself by adding this to the functions.php:

// Remove function that counts words
remove_action( 'save_post', 'fictioneer_save_word_count' );

// Add function that counts characters
function child_save_character_count( $post_id ) {
  // Prevent multi-fire
  if ( fictioneer_multi_save_guard( $post_id ) ) {
    return;
  }

  // Prepare
  $content = get_post_field( 'post_content', $post_id );
  $content = strip_shortcodes( $content );
  $content = strip_tags( $content );

  // Count characters instead of words
  $word_count = mb_strlen( $content );

  // Remember
  update_post_meta( $post_id, '_word_count', $word_count );
}
add_action( 'save_post', 'child_save_character_count' );

If that works for you, I can add it as new option to the theme.

Edit: Note that this will not update existing word counts. This is only done when you save a post.

I am sorry I had added it in the chind theme, but it still not work. This is the new page. https://novel2.littleprince.site/story/test1-story/ 图片

Tetrakern commented 8 months ago

You need to wrap the override into an init action, as described in the child theme example function.php. You can also wait for the next update, which will add options for logographic writing systems, making this overwrite unnecessary.


image
/**
 * Remove or customize parent filters and actions on the frontend
 */

function fictioneer_child_customize_parent() {
  // Remove function that counts words
  remove_action( 'save_post', 'fictioneer_save_word_count' );

  // Add function that counts characters
  function child_save_character_count( $post_id ) {
    // Prevent multi-fire
    if ( fictioneer_multi_save_guard( $post_id ) ) {
      return;
    }

    // Prepare
    $content = get_post_field( 'post_content', $post_id );
    $content = strip_shortcodes( $content );
    $content = strip_tags( $content );

    // Count characters instead of words
    $word_count = mb_strlen( $content );

    // Remember
    update_post_meta( $post_id, '_word_count', $word_count );
  }
  add_action( 'save_post', 'child_save_character_count' );
}
add_action( 'init', 'fictioneer_child_customize_parent' );
babydu commented 8 months ago

You need to wrap the override into an init action, as described in the child theme example function.php. You can also wait for the next update, which will add options for logographic writing systems, making this overwrite unnecessary.您需要将覆盖包装到init操作中,如子主题示例function.php中所述。您也可以等待下一次更新,这将添加标识文字书写系统的选项,使这种覆盖变得不必要。

image
/**
 * Remove or customize parent filters and actions on the frontend
 */

function fictioneer_child_customize_parent() {
  // Remove function that counts words
  remove_action( 'save_post', 'fictioneer_save_word_count' );

  // Add function that counts characters
  function child_save_character_count( $post_id ) {
    // Prevent multi-fire
    if ( fictioneer_multi_save_guard( $post_id ) ) {
      return;
    }

    // Prepare
    $content = get_post_field( 'post_content', $post_id );
    $content = strip_shortcodes( $content );
    $content = strip_tags( $content );

    // Count characters instead of words
    $word_count = mb_strlen( $content );

    // Remember
    update_post_meta( $post_id, '_word_count', $word_count );
  }
  add_action( 'save_post', 'child_save_character_count' );
}
add_action( 'init', 'fictioneer_child_customize_parent' );

Thanks. It works now!

Tetrakern commented 8 months ago

Update scheduled for 5.9.4: https://github.com/Tetrakern/fictioneer/commit/f13f1d40f20e28ac6b0d20d381b76874ed111c38

image