{"id":235800,"date":"2025-06-17T06:46:25","date_gmt":"2025-06-17T06:46:25","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/init-view-count\/"},"modified":"2026-03-04T15:27:18","modified_gmt":"2026-03-04T15:27:18","slug":"init-view-count","status":"publish","type":"plugin","link":"https:\/\/pcd.wordpress.org\/plugins\/init-view-count\/","author":14479633,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.19.3","stable_tag":"1.19.3","tested":"6.9.4","requires":"5.5","requires_php":"7.4","requires_plugins":null,"header_name":"Init View Count","header_author":"Init HTML","header_description":"Count real post views based on user interaction \u2014 with delay, scroll detection, and flexible shortcodes to display view stats beautifully. Lightweight, accurate, and extensible.","assets_banners_color":"af1ebe","last_updated":"2026-03-04 15:27:18","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/inithtml.com\/plugin\/init-view-count\/","header_author_uri":"https:\/\/inithtml.com\/","rating":5,"author_block_rating":0,"active_installs":100,"downloads":1889,"num_ratings":3,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.10":{"tag":"1.10","author":"brokensmile.2103","date":"2025-06-26 10:28:41"},"1.11":{"tag":"1.11","author":"brokensmile.2103","date":"2025-06-30 14:36:24"},"1.12":{"tag":"1.12","author":"brokensmile.2103","date":"2025-07-10 03:18:02"},"1.13":{"tag":"1.13","author":"brokensmile.2103","date":"2025-07-13 04:58:51"},"1.14":{"tag":"1.14","author":"brokensmile.2103","date":"2025-07-25 16:54:30"},"1.15":{"tag":"1.15","author":"brokensmile.2103","date":"2025-08-08 06:23:30"},"1.16":{"tag":"1.16","author":"brokensmile.2103","date":"2025-08-16 06:26:37"},"1.17":{"tag":"1.17","author":"brokensmile.2103","date":"2025-08-26 19:40:34"},"1.18":{"tag":"1.18","author":"brokensmile.2103","date":"2025-10-01 04:15:52"},"1.19":{"tag":"1.19","author":"brokensmile.2103","date":"2025-10-02 03:26:56"},"1.19.1":{"tag":"1.19.1","author":"brokensmile.2103","date":"2025-10-24 06:34:01"},"1.19.2":{"tag":"1.19.2","author":"brokensmile.2103","date":"2025-10-26 15:37:27"},"1.19.3":{"tag":"1.19.3","author":"brokensmile.2103","date":"2026-03-04 15:27:18"},"1.5":{"tag":"1.5","author":"brokensmile.2103","date":"2025-06-18 18:23:35"},"1.6":{"tag":"1.6","author":"brokensmile.2103","date":"2025-06-19 09:22:05"},"1.7":{"tag":"1.7","author":"brokensmile.2103","date":"2025-06-21 05:01:37"},"1.8":{"tag":"1.8","author":"brokensmile.2103","date":"2025-06-22 14:39:21"},"1.9":{"tag":"1.9","author":"brokensmile.2103","date":"2025-06-24 15:18:54"}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":3},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3312929,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3312929,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3312929,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3312929,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.10","1.11","1.12","1.13","1.14","1.15","1.16","1.17","1.18","1.19","1.19.1","1.19.2","1.19.3","1.5","1.6","1.7","1.8","1.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3318166,"resolution":"1","location":"assets","locale":""},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3312929,"resolution":"2","location":"assets","locale":""},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3312929,"resolution":"3","location":"assets","locale":""},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3312929,"resolution":"4","location":"assets","locale":""},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3312929,"resolution":"5","location":"assets","locale":""},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3312929,"resolution":"6","location":"assets","locale":""}},"screenshots":{"1":"Plugin settings page \u2013 configure post types, view types, delay, scroll check, and storage method.","2":"Shortcode builder for [init_view_list] \u2013 generate view-based post lists with custom templates.","3":"Shortcode builder for [init_view_ranking] \u2013 generate tabbed rankings for different view ranges.","4":"Shortcode builder for [init_view_count] \u2013 display view count for current post with format options.","5":"Frontend view \u2013 ranking display (all time), light mode interface.","6":"Frontend view \u2013 ranking display (this week), dark mode interface."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[5990,23853,80,53163,23753],"plugin_category":[36,43],"plugin_contributors":[242666],"plugin_business_model":[],"class_list":["post-235800","plugin","type-plugin","status-publish","hentry","plugin_tags-post-views","plugin_tags-rest-api","plugin_tags-shortcode","plugin_tags-trending-posts","plugin_tags-view-counter","plugin_category-analytics","plugin_category-customization","plugin_contributors-brokensmile2103-1","plugin_committers-brokensmile2103-1"],"banners":{"banner":"https:\/\/ps.w.org\/init-view-count\/assets\/banner-772x250.png?rev=3312929","banner_2x":"https:\/\/ps.w.org\/init-view-count\/assets\/banner-1544x500.png?rev=3312929","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/init-view-count\/assets\/icon-128x128.png?rev=3312929","icon_2x":"https:\/\/ps.w.org\/init-view-count\/assets\/icon-256x256.png?rev=3312929","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-1.png?rev=3318166","caption":"Plugin settings page \u2013 configure post types, view types, delay, scroll check, and storage method."},{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-2.png?rev=3312929","caption":"Shortcode builder for [init_view_list] \u2013 generate view-based post lists with custom templates."},{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-3.png?rev=3312929","caption":"Shortcode builder for [init_view_ranking] \u2013 generate tabbed rankings for different view ranges."},{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-4.png?rev=3312929","caption":"Shortcode builder for [init_view_count] \u2013 display view count for current post with format options."},{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-5.png?rev=3312929","caption":"Frontend view \u2013 ranking display (all time), light mode interface."},{"src":"https:\/\/ps.w.org\/init-view-count\/assets\/screenshot-6.png?rev=3312929","caption":"Frontend view \u2013 ranking display (this week), dark mode interface."}],"raw_content":"<!--section=description-->\n<p><strong>Init View Count<\/strong> is a fast, clean plugin to track post views without clutter. It:<\/p>\n\n<ul>\n<li>Uses REST API and JS to count real views<\/li>\n<li>Prevents duplicate counts with session\/local storage<\/li>\n<li>Stores counts in meta keys like <code>_init_view_count<\/code>, <code>_init_view_day_count<\/code>, etc.<\/li>\n<li>Provides <code>[init_view_count]<\/code> and <code>[init_view_list]<\/code> shortcodes<\/li>\n<li>Includes <code>[init_view_ranking]<\/code> shortcode with tabbed ranking by time range<\/li>\n<li>Supports template overrides (like WooCommerce)<\/li>\n<li>Lightweight. No tracking, no admin bloat.<\/li>\n<li>Includes REST API to query most viewed posts<\/li>\n<li>Supports pagination in <code>[init_view_list]<\/code> via the <code>page<\/code> attribute<\/li>\n<li>Batch view tracking support to reduce REST requests on busy sites<\/li>\n<li>Optional strict IP-based filtering to block fake view requests posted directly to the REST endpoint<\/li>\n<li>Includes a Dashboard widget to monitor top viewed posts directly in wp-admin<\/li>\n<li>Learns site-wide traffic shape (hourly &amp; weekday) via AI-powered smoothing<\/li>\n<li>Shapes cached and updated efficiently with minimal overhead<\/li>\n<li>Safe reset action to rebuild patterns automatically<\/li>\n<li>Fully integrated with Trending Engine v3 for uplift-based scoring<\/li>\n<\/ul>\n\n<p>This plugin is part of the <a href=\"https:\/\/en.inithtml.com\/init-plugin-suite-minimalist-powerful-and-free-wordpress-plugins\/\">Init Plugin Suite<\/a> \u2014 a collection of minimalist, fast, and developer-focused tools for WordPress.<\/p>\n\n<p>GitHub repository: <a href=\"https:\/\/github.com\/brokensmile2103\/init-view-count\">https:\/\/github.com\/brokensmile2103\/init-view-count<\/a><\/p>\n\n<h3>Highlights<\/h3>\n\n<ul>\n<li>REST-first design \u2014 no jQuery or legacy Ajax<\/li>\n<li>View tracking powered by time + scroll detection<\/li>\n<li>Realtime display with optional animated counters<\/li>\n<li>Fully theme-compatible with overrideable templates<\/li>\n<li>Developer-friendly with rich filter support<\/li>\n<li>Optional <code>[init_view_ranking]<\/code> shortcode for tabbed view by day\/week\/month\/total<\/li>\n<li>Assets are only loaded when needed \u2013 perfect for performance-conscious themes<\/li>\n<li>Fully compatible with headless and SPA frameworks (REST-first + lazy)<\/li>\n<li>Supports batch mode: delay view requests and send in groups (configurable in settings)<\/li>\n<li>Includes optional Dashboard widget for quick admin overview of top viewed posts<\/li>\n<li>AI-powered Traffic Shape Learner \u2013 understands your site\u2019s hourly &amp; weekly rhythm<\/li>\n<li>Auto-integrated with Trending Engine v3 for seasonality-aware uplift detection<\/li>\n<li>Smart fallbacks (day \u2192 week \u2192 month \u2192 total) ensure rankings never run empty<\/li>\n<li>Ultra-light: only 1 write per increment + 1 rollup per day, cache-first design<\/li>\n<\/ul>\n\n<h3>Shortcodes<\/h3>\n\n<h3>[init_view_count]<\/h3>\n\n<p>Shows current view count for a post. Only works inside a post loop.<\/p>\n\n<p><strong>Attributes:<\/strong>\n- <code>field<\/code>: <code>total<\/code> (default), <code>day<\/code>, <code>week<\/code>, <code>month<\/code> \u2013 which counter to display\n- <code>format<\/code>: <code>formatted<\/code> (default), <code>raw<\/code>, or <code>short<\/code> \u2013 controls number formatting\n- <code>time<\/code>: <code>true<\/code> to show time diff from post date (e.g. \"3 days ago\")\n- <code>icon<\/code>: <code>true<\/code> to display a small SVG icon before the count\n- <code>schema<\/code>: <code>true<\/code> to output schema.org microdata (InteractionCounter)\n- <code>class<\/code>: add a custom CSS class to the outer wrapper<\/p>\n\n<h3>[init_view_list]<\/h3>\n\n<p>Show list of most viewed posts.<\/p>\n\n<p><strong>Attributes:<\/strong>\n- <code>number<\/code>: Number of posts to show (default: 5)\n- <code>page<\/code>: Show a specific page of results (default: 1)\n- <code>post_type<\/code>: Type of post (default: post)\n- <code>template<\/code>: <code>sidebar<\/code> (default), <code>full<\/code>, <code>grid<\/code>, <code>details<\/code> (can be overridden)\n- <code>title<\/code>: Title above list. Set to empty (<code>title=\"\"<\/code>) to hide\n- <code>class<\/code>: Custom class added to wrapper\n- <code>orderby<\/code>: Sort field (default: meta_value_num)\n- <code>order<\/code>: ASC or DESC (default: DESC)\n- <code>range<\/code>: <code>total<\/code>, <code>day<\/code>, <code>week<\/code>, <code>month<\/code>, <code>trending<\/code>\n- <code>category<\/code>: Filter by category slug\n- <code>tag<\/code>: Filter by tag slug\n- <code>empty<\/code>: Message to show if no posts found<\/p>\n\n<h3>[init_view_ranking]<\/h3>\n\n<p>Show tabbed ranking of most viewed posts. Uses REST API and JavaScript for dynamic loading. Optimized for SPA\/headless usage.<\/p>\n\n<p><strong>Attributes:<\/strong>\n- <code>tabs<\/code>: Comma-separated list of ranges. Available: <code>total<\/code>, <code>day<\/code>, <code>week<\/code>, <code>month<\/code> (default: all)\n- <code>number<\/code>: Number of posts per tab (default: 5)\n- <code>class<\/code>: Custom class for outer wrapper<\/p>\n\n<p>This shortcode automatically enqueues required JS and uses skeleton loaders while fetching data.<\/p>\n\n<h3>REST API<\/h3>\n\n<p>This plugin exposes two REST endpoints to interact with view counts: one for recording views and another for retrieving top posts.<\/p>\n\n<p><strong><code>POST \/wp-json\/initvico\/v1\/count<\/code><\/strong><br \/>\nRecord one or more views. Accepts a single post ID or an array of post IDs.<\/p>\n\n<p><strong>Parameters:<\/strong>\n- <code>post_id<\/code> \u2014 <em>(int|array)<\/em> Required. One or more post IDs to increment view count for.<\/p>\n\n<p>This endpoint checks if the post is published, belongs to a supported post type, and applies delay\/scroll config (via JavaScript). It updates total and optionally day\/week\/month view counters.<\/p>\n\n<p>Note: The number of post IDs processed per request is limited based on the batch setting in plugin options.<\/p>\n\n<p><strong><code>GET \/wp-json\/initvico\/v1\/top<\/code><\/strong><br \/>\nRetrieve the most viewed posts, ranked by view count.<\/p>\n\n<p><strong>Parameters:<\/strong>\n- <code>range<\/code> \u2014 <em>(string)<\/em> <code>total<\/code>, <code>day<\/code>, <code>week<\/code>, <code>month<\/code>. Defaults to <code>total<\/code>.\n- <code>post_type<\/code> \u2014 <em>(string)<\/em> Post type to query. Defaults to <code>post<\/code>.\n- <code>number<\/code> \u2014 <em>(int)<\/em> Number of posts to return. Default: <code>5<\/code>.\n- <code>page<\/code> \u2014 <em>(int)<\/em> Pagination offset. Default: <code>1<\/code>.\n- <code>fields<\/code> \u2014 <em>(string)<\/em> <code>minimal<\/code> (id, title, link) or <code>full<\/code> (includes excerpt, thumbnail, type, date, etc.)\n- <code>tax<\/code> \u2014 <em>(string)<\/em> Optional. Taxonomy slug (e.g. <code>category<\/code>).\n- <code>terms<\/code> \u2014 <em>(string)<\/em> Comma-separated term slugs or IDs.\n- <code>no_cache<\/code> \u2014 <em>(bool)<\/em> If <code>1<\/code>, disables transient caching.<\/p>\n\n<p>This endpoint supports filtering and caching, and can be extended to support custom output formats.<\/p>\n\n<h3>Filters for Developers<\/h3>\n\n<p>This plugin provides multiple filters to help developers customize behavior and output in both REST API and shortcode use cases.<\/p>\n\n<p><strong><code>init_plugin_suite_view_count_should_count<\/code><\/strong><br \/>\nAllow or prevent counting views for a specific post.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/count<\/code><br \/>\n<strong>Params:<\/strong> <code>bool $should_count<\/code>, <code>int $post_id<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_meta_key<\/code><\/strong><br \/>\nChange the meta key used to read or write view counts.<br \/>\n<strong>Applies to:<\/strong> REST &amp; Shortcodes<br \/>\n<strong>Params:<\/strong> <code>string $meta_key<\/code>, <code>int|null $post_id<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_after_counted<\/code><\/strong><br \/>\nRun custom logic after view count has been incremented.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/count<\/code><br \/>\n<strong>Params:<\/strong> <code>int $post_id<\/code>, <code>array $updated<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_api_top_args<\/code><\/strong><br \/>\nCustomize WP_Query arguments used for <code>\/top<\/code> endpoint.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/top<\/code><br \/>\n<strong>Params:<\/strong> <code>array $args<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_api_top_item<\/code><\/strong><br \/>\nModify each item before it's returned in the <code>\/top<\/code> response.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/top<\/code><br \/>\n<strong>Params:<\/strong> <code>array $item<\/code>, <code>WP_Post $post<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_api_top_cache_time<\/code><\/strong><br \/>\nAdjust cache time (in seconds) for <code>\/top<\/code> results.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/top<\/code><br \/>\n<strong>Params:<\/strong> <code>int $ttl<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_top_post_types<\/code><\/strong><br \/>\nCustomize the list of post types returned by the <code>\/top<\/code> endpoint.<br \/>\n<strong>Applies to:<\/strong> REST <code>\/top<\/code><br \/>\n<strong>Params:<\/strong> <code>array $post_types<\/code>, <code>WP_REST_Request $request<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_query_args<\/code><\/strong><br \/>\nFilter WP_Query args for <code>[init_view_list]<\/code> shortcode.<br \/>\n<strong>Applies to:<\/strong> <code>[init_view_list]<\/code><br \/>\n<strong>Params:<\/strong> <code>array $args<\/code>, <code>array $atts<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_empty_output<\/code><\/strong><br \/>\nCustomize the HTML output when no posts are found.<br \/>\n<strong>Applies to:<\/strong> <code>[init_view_list]<\/code><br \/>\n<strong>Params:<\/strong> <code>string $output<\/code>, <code>array $atts<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_view_list_atts<\/code><\/strong><br \/>\nModify shortcode attributes before WP_Query is run.<br \/>\n<strong>Applies to:<\/strong> <code>[init_view_list]<\/code><br \/>\n<strong>Params:<\/strong> <code>array $atts<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_default_shortcode<\/code><\/strong><br \/>\nCustomize the default shortcode used when auto-inserting view count into post content.<br \/>\n<strong>Applies to:<\/strong> <code>[init_view_count]<\/code> auto-insert<br \/>\n<strong>Params:<\/strong> <code>string $shortcode<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_auto_insert_enabled<\/code><\/strong><br \/>\nControl whether auto-insert is enabled for a given context.<br \/>\n<strong>Applies to:<\/strong> <code>[init_view_count]<\/code> auto-insert<br \/>\n<strong>Params:<\/strong> <code>bool $enabled<\/code>, <code>string $position<\/code>, <code>string $post_type<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_engagement_meta_keys<\/code><\/strong><br \/>\nChange the meta keys used to retrieve <code>like<\/code> and <code>share<\/code> counts when calculating engagement quality.<br \/>\n<strong>Applies to:<\/strong> Engagement algorithm<br \/>\n<strong>Params:<\/strong> <code>array $meta_keys<\/code> (<code>likes<\/code>, <code>shares<\/code>), <code>int $post_id<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_trending_post_types<\/code><\/strong><br \/>\nOverride the list of post types used by the Trending cron calculation.<br \/>\n<strong>Applies to:<\/strong> Cron Trending<br \/>\n<strong>Params:<\/strong> <code>array $post_types<\/code><\/p>\n\n<p><strong><code>init_plugin_suite_view_count_trending_component_weights<\/code><\/strong>\nAdjust weights for Trending score components.\n<strong>Applies to:<\/strong> Trending algorithm<br \/>\n<strong>Params:<\/strong> <code>array $weights<\/code> (<code>velocity<\/code>, <code>engagement<\/code>, <code>freshness<\/code>, <code>momentum<\/code>)<\/p>\n\n<h3>Template Override<\/h3>\n\n<p>To customize output layout, copy any template file into your theme:<\/p>\n\n<p>Example: <code>your-theme\/init-view-count\/view-list-grid.php<\/code><\/p>\n\n<h3>License<\/h3>\n\n<p>This plugin is licensed under the GPLv2 or later.<br \/>\nYou are free to use, modify, and distribute it under the same license.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload plugin to <code>\/wp-content\/plugins\/init-view-count\/<\/code><\/li>\n<li>Activate via Plugins menu<\/li>\n<li>Use <code>[init_view_count]<\/code> or <code>[init_view_list]<\/code> in your content<\/li>\n<li>Customize settings in Settings \u2192 Init View Count<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"can%20i%20customize%20the%20layout%20of%20the%20list%3F\"><h3>Can I customize the layout of the list?<\/h3><\/dt>\n<dd><p>Yes. Use the <code>template<\/code> attribute in <code>[init_view_list]<\/code> (e.g. <code>template=\"grid\"<\/code>), and override the corresponding file in your theme like WooCommerce templates.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20custom%20post%20types%3F\"><h3>Does it work with custom post types?<\/h3><\/dt>\n<dd><p>Yes. Just set <code>post_type=\"your_custom_type\"<\/code> in the shortcode or REST query.<\/p><\/dd>\n<dt id=\"how%20does%20it%20avoid%20duplicate%20views%3F\"><h3>How does it avoid duplicate views?<\/h3><\/dt>\n<dd><p>Init View Count uses both <strong>time delay<\/strong> and <strong>scroll detection<\/strong> via JavaScript, and stores viewed post IDs in either sessionStorage or localStorage (your choice).<\/p><\/dd>\n<dt id=\"is%20the%20view%20count%20updated%20immediately%3F\"><h3>Is the view count updated immediately?<\/h3><\/dt>\n<dd><p>Yes. When the scroll+delay conditions are met, the count is updated via REST API and saved using <code>update_post_meta()<\/code>.<\/p><\/dd>\n<dt id=\"what%20meta%20key%20is%20used%20to%20store%20views%3F\"><h3>What meta key is used to store views?<\/h3><\/dt>\n<dd><p>By default:<br \/>\n- <code>_init_view_count<\/code> (total)<br \/>\n- <code>_init_view_day_count<\/code><br \/>\n- <code>_init_view_week_count<\/code><br \/>\n- <code>_init_view_month_count<\/code><br \/>\nThese keys can be changed via the <code>init_plugin_suite_view_count_meta_key<\/code> filter.\nTrending scores are calculated separately and stored in a transient.<\/p><\/dd>\n<dt id=\"can%20i%20display%20view%20counts%20in%20my%20template%20manually%3F\"><h3>Can I display view counts in my template manually?<\/h3><\/dt>\n<dd><p>Yes. Use <code>get_post_meta($post_id, '_init_view_count', true)<\/code> or similar keys. Or use <code>[init_view_count]<\/code> shortcode in post content.<\/p><\/dd>\n<dt id=\"can%20i%20disable%20the%20built-in%20css%3F\"><h3>Can I disable the built-in CSS?<\/h3><\/dt>\n<dd><p>Yes. There is an option in the plugin\u2019s settings to disable the default stylesheet. You can style the output manually as needed.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20caching%20plugins%3F\"><h3>Is it compatible with caching plugins?<\/h3><\/dt>\n<dd><p>Yes. Since it uses JavaScript + REST for counting, page caching doesn't interfere. However, REST responses (<code>\/top<\/code>) are cached using transients.<\/p><\/dd>\n<dt id=\"can%20i%20use%20it%20in%20block%20editor%20%2F%20gutenberg%3F\"><h3>Can I use it in block editor \/ Gutenberg?<\/h3><\/dt>\n<dd><p>Yes. Just insert a Shortcode block and paste <code>[init_view_count]<\/code> or <code>[init_view_list]<\/code> as needed.<\/p><\/dd>\n<dt id=\"does%20it%20track%20bots%3F\"><h3>Does it track bots?<\/h3><\/dt>\n<dd><p>No. Since counting only happens after scroll and delay via JavaScript, bots like Googlebot are naturally excluded.<\/p><\/dd>\n<dt id=\"can%20i%20sort%20posts%20by%20views%20in%20wp_query%3F\"><h3>Can I sort posts by views in WP_Query?<\/h3><\/dt>\n<dd><p>Yes. Use <code>'meta_key' =&gt; '_init_view_count'<\/code> and <code>'orderby' =&gt; 'meta_value_num'<\/code> in your <code>WP_Query<\/code> args.<\/p><\/dd>\n<dt id=\"can%20i%20reduce%20the%20number%20of%20view%20requests%20sent%20to%20the%20server%3F\"><h3>Can I reduce the number of view requests sent to the server?<\/h3><\/dt>\n<dd><p>Yes. You can enable batch view tracking in the plugin settings. Instead of sending one request per view, views will be stored in the browser and sent in a group once the threshold is reached.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.19 \u2013 October 2, 2025<\/h4>\n\n<ul>\n<li>Hotfix: Daily\/Weekly\/Monthly counters now <strong>enabled by default<\/strong>\n\n<ul>\n<li><code>init_plugin_suite_view_count_enable_day<\/code> \u2192 default = 1<\/li>\n<li><code>init_plugin_suite_view_count_enable_week<\/code> \u2192 default = 1<\/li>\n<li><code>init_plugin_suite_view_count_enable_month<\/code> \u2192 default = 1<\/li>\n<\/ul><\/li>\n<li>Fixes issue where counters stayed disabled unless user manually saved settings<\/li>\n<li>No migration required \u2013 existing installs automatically respect new defaults<\/li>\n<li>Backward compatibility: behavior unchanged if options already set explicitly<\/li>\n<\/ul>\n\n<h4>1.18 \u2013 October 1, 2025<\/h4>\n\n<ul>\n<li>Reset &amp; history tracking:<br \/>\n\n<ul>\n<li>Daily, weekly, and monthly reset now archive values into <code>_init_view_day_yesterday<\/code>, <code>_init_view_week_last<\/code>, <code>_init_view_month_last<\/code>  <\/li>\n<li>Enables direct retrieval of \u201cYesterday\u201d, \u201cLast Week\u201d, and \u201cLast Month\u201d stats  <\/li>\n<li>Fully backward-compatible \u2013 existing keys remain unchanged  <\/li>\n<\/ul><\/li>\n<li>Shortcode <code>[init_view_ranking]<\/code>:<br \/>\n\n<ul>\n<li>New ranges supported: <code>yesterday<\/code>, <code>last_week<\/code>, <code>last_month<\/code>  <\/li>\n<li>Default tabs unchanged (<code>total,day,week,month<\/code>) for compatibility  <\/li>\n<li>Added i18n labels for new ranges (\u201cYesterday\u201d, \u201cLast Week\u201d, \u201cLast Month\u201d) <\/li>\n<\/ul><\/li>\n<li>REST API (<code>init_plugin_suite_view_count_top<\/code>):<br \/>\n\n<ul>\n<li><code>range<\/code> parameter extended with <code>yesterday<\/code>, <code>last_week<\/code>, <code>last_month<\/code>  <\/li>\n<li>Auto-maps to new meta keys, preserves existing defaults  <\/li>\n<li>Minimal\/full field responses and caching remain consistent  <\/li>\n<\/ul><\/li>\n<li>Settings &amp; control:<br \/>\n\n<ul>\n<li>New option <strong>\u201cDisable Trending\u201d<\/strong> in settings page  <\/li>\n<li>When enabled: trending engine, shape learner, and all related calculations return no-op  <\/li>\n<li>When disabled (default): trending runs as normal, no behavior change for existing sites  <\/li>\n<\/ul><\/li>\n<li>Performance &amp; stability:<br \/>\n\n<ul>\n<li>Only 3 additional meta writes per reset cycle  <\/li>\n<li>All new keys pass through <code>init_plugin_suite_view_count_meta_key<\/code> for extensibility  <\/li>\n<li>Trending, shape learner, and caching unaffected unless explicitly disabled  <\/li>\n<\/ul><\/li>\n<li>Backward compatibility:<br \/>\n\n<ul>\n<li>Existing shortcodes, API calls, and filters continue to work unchanged  <\/li>\n<li>No migration required \u2013 new keys auto-populate from next reset cycle  <\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.17 \u2013 August 20, 2025<\/h4>\n\n<ul>\n<li>Traffic Shape Learner \u2013 AI-powered hourly &amp; weekday distribution model:\n\n<ul>\n<li>Collects raw hourly bins per day and rolls them up into site-wide traffic shape<\/li>\n<li>Hour-of-day pattern: updated via EMA with Bayesian prior smoothing (kappa control)<\/li>\n<li>Day-of-week pattern: updated via EMA with stabilized daily totals<\/li>\n<li>Both distributions normalized to mean = 1 for consistent multiplicative scaling<\/li>\n<\/ul><\/li>\n<li>Performance &amp; caching:\n\n<ul>\n<li>Learned shapes cached in transient for 2h with filterable TTL<\/li>\n<li>Rollup action protected by object-cache lock to avoid race conditions<\/li>\n<li>Minimal overhead: only 1 write per view increment + 1 rollup per day<\/li>\n<\/ul><\/li>\n<li>Filters &amp; extensibility:\n\n<ul>\n<li><code>init_plugin_suite_view_count_site_traffic_shape<\/code> provides current hour\/day shape arrays<\/li>\n<li>Tunable alpha\/kappa values via filters for both hour-of-day and weekday models<\/li>\n<li><code>init_plugin_suite_view_count_shape_collect_enabled<\/code> allows enabling\/disabling collection<\/li>\n<\/ul><\/li>\n<li>Reset &amp; admin:\n\n<ul>\n<li>New admin-post action <code>init_plugin_suite_view_count_shape_reset<\/code> to clear all learned shape data<\/li>\n<li>Fully safe to run anytime \u2013 plugin will rebuild patterns automatically<\/li>\n<\/ul><\/li>\n<li>Backward compatibility:\n\n<ul>\n<li>All existing trending and view count filters remain intact<\/li>\n<li>Trending Engine v3 (1.16) automatically integrates with learned shapes for uplift calculation<\/li>\n<\/ul><\/li>\n<li>Trending Engine improvements:\n\n<ul>\n<li>Multi-key fallback (day \u2192 week \u2192 month \u2192 total) ensures enough posts even at start of day<\/li>\n<li>Day-views fallback estimation from week\/month averages prevents empty scores at early hours<\/li>\n<li>Optimized CRON queries: skip week\/month\/total lookups if daily data already sufficient<\/li>\n<li>Debug payload now includes <code>views_day_used<\/code> and fallback flags for transparency<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.16 \u2013 August 16, 2025<\/h4>\n\n<ul>\n<li>Trending Engine v3 \u2013 AI-powered uplift &amp; momentum detection:\n\n<ul>\n<li>Seasonality-aware uplift: compares actual views against expected traffic shape (hour-of-day, day-of-week) for true anomalies<\/li>\n<li>EWMA momentum with acceleration: smoother trend detection, keeps natural growth without noise<\/li>\n<li>Anti-gaming protection: robust ratio checks (day vs month\/total) and capped score growth per run<\/li>\n<li>Exposure fatigue: reduces dominance of posts that stay at the top too long, keeps feed fresh<\/li>\n<li>MMR re-ranking: maximized marginal relevance for better diversity across categories and tags<\/li>\n<li>Explore\/exploit logic: occasional boost for promising new posts with strong uplift signals<\/li>\n<\/ul><\/li>\n<li>Performance &amp; caching:\n\n<ul>\n<li>Cached EWMA velocity per post with 12h TTL, minimal overhead<\/li>\n<li>Site traffic shape cached for 2h with filterable override hook<\/li>\n<li>Added transient-based streak tracking for fatigue multiplier<\/li>\n<\/ul><\/li>\n<li>Debug &amp; transparency:\n\n<ul>\n<li>Extended debug payload includes uplift_raw, expected_views, ewma_val, acc, fatigue_streak<\/li>\n<li>New action <code>init_plugin_suite_view_count_trending_debug_row<\/code> available for developers to log detailed trending rows<\/li>\n<\/ul><\/li>\n<li>Fully backward-compatible:\n\n<ul>\n<li>Existing filters remain intact (<code>init_plugin_suite_view_count_trending_component_weights<\/code>, <code>init_plugin_suite_view_count_meta_key<\/code>)<\/li>\n<li>Default weights added for uplift, ewma, fatigue, explore, and mmr with safe multipliers<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.15 \u2013 August 8, 2025<\/h4>\n\n<ul>\n<li>Trending Engine v2 \u2013 optimized for performance and stability:\n\n<ul>\n<li>Added cache lock (object cache) to prevent race conditions when cron overlaps<\/li>\n<li>Soft-cap scoring using an exponential formula for smooth limits (avoids hard caps)<\/li>\n<li>Optimized O(n) diversity filter with auto fill-back to always return enough items<\/li>\n<li>Improved hot topics SQL for ONLY_FULL_GROUP_BY compatibility and timezone safety with post_date_gmt<\/li>\n<li>Reduced N+1 queries by caching author_id, categories, and tags per post<\/li>\n<\/ul><\/li>\n<li>New filters for Trending:\n\n<ul>\n<li><code>init_plugin_suite_view_count_trending_post_types<\/code> \u2013 limit\/override post types (e.g., only <code>manga<\/code>)<\/li>\n<li><code>init_plugin_suite_view_count_trending_component_weights<\/code> \u2013 adjust weights for velocity, engagement, freshness, momentum<\/li>\n<\/ul><\/li>\n<li>Sanitize &amp; fallback: normalized post types from settings, auto-remove <code>attachment<\/code>, safe fallback when empty<\/li>\n<li>Engagement smoothing: improved stability when daily views are low<\/li>\n<\/ul>\n\n<h4>1.14 \u2013 July 24, 2025<\/h4>\n\n<ul>\n<li>Introduced a powerful hybrid trending algorithm with hourly updates<\/li>\n<li>Trending score is calculated based on five dynamic components:\n\n<ul>\n<li>View velocity (per hour, adjusted by recent growth patterns)<\/li>\n<li>Time decay (natural dropoff over time, with extended half-life)<\/li>\n<li>Engagement quality (comments, likes, shares per view)<\/li>\n<li>Content freshness boost (heavier weight for new posts)<\/li>\n<li>Category\/tag momentum (boost for trending topics in the last 24 hours)<\/li>\n<\/ul><\/li>\n<li>Trending list is automatically cached and refreshed every hour<\/li>\n<li>Added diversity filter to ensure balanced results across authors and categories:\n\n<ul>\n<li>Max 2 posts per author and 3 per category if diversity allows<\/li>\n<li>Automatically lifts limits if not enough authors\/categories to fill the top list<\/li>\n<\/ul><\/li>\n<li>Fully filterable and compatible with all public post types, taxonomies, and view tracking logic<\/li>\n<\/ul>\n\n<h4>1.13 \u2013 July 13, 2025<\/h4>\n\n<ul>\n<li>Added <code>init_plugin_suite_view_count_top_post_types<\/code> filter to allow overriding <code>post_type<\/code> in top view REST API route<\/li>\n<li>Useful for restricting or customizing results (e.g., only <code>manga<\/code>, <code>article<\/code>, etc.)<\/li>\n<\/ul>\n\n<h4>1.12 \u2013 July 8, 2025<\/h4>\n\n<ul>\n<li>Shortcode <code>[init_view_count]<\/code> now supports <code>id=\"...\"<\/code> attribute to display the view count of any post (not just the current one)<\/li>\n<li>Allows showing view counts for related posts, custom queries, or manually selected IDs<\/li>\n<li>Fully backward-compatible: if <code>id<\/code> is omitted, the current post will be used as before<\/li>\n<\/ul>\n\n<h4>1.11 \u2013 June 30, 2025<\/h4>\n\n<ul>\n<li>Shortcode <code>[init_view_ranking]<\/code> now supports <code>post_type=\"...\"<\/code> to filter rankings by custom post type<\/li>\n<li>JS file <code>ranking.js<\/code> updated to pass <code>post_type<\/code> to REST API and cache results per tab and type<\/li>\n<li>Removed redundant function <code>init_plugin_suite_view_count_human_time_diff()<\/code> in favor of core <code>human_time_diff()<\/code><\/li>\n<li>Updated <code>[init_view_count]<\/code> shortcode to use native <code>human_time_diff()<\/code> for publishing time display<\/li>\n<li>Updated all templates to use native <code>human_time_diff()<\/code> instead of removed custom function<\/li>\n<\/ul>\n\n<h4>1.10 \u2013 June 26, 2025<\/h4>\n\n<ul>\n<li>Added new <code>icon=\"true\"<\/code> attribute to <code>[init_view_count]<\/code> shortcode to display inline SVG before the view count<\/li>\n<li>New setting: \"Auto-insert shortcode into post content?\" with options to insert before or after post content<\/li>\n<li>Auto-insert only applies to post types where view tracking is enabled (manual shortcode use still supported)<\/li>\n<li>Added <code>schema=\"true\"<\/code> attribute to <code>[init_view_count]<\/code> to output Schema.org microdata (<code>InteractionCounter<\/code>)<\/li>\n<li>Added <code>class=\"custom-class\"<\/code> attribute to allow injecting custom CSS classes into the shortcode wrapper<\/li>\n<li>New filter <code>init_plugin_suite_view_count_default_shortcode<\/code> allows developers to override default auto-insert output<\/li>\n<li>New filter <code>init_plugin_suite_view_count_auto_insert_enabled<\/code> gives control over whether auto-insert is active per context<\/li>\n<li>Fully backward-compatible: all new features are optional and disabled by default<\/li>\n<\/ul>\n\n<h4>1.9 \u2013 June 24, 2025<\/h4>\n\n<ul>\n<li>Replaced all PHP 8+ <code>match<\/code> expressions with backwards-compatible logic using array maps and switches<\/li>\n<li>Now fully compatible with PHP 7.4 and above \u2013 no syntax errors on legacy environments<\/li>\n<li>All changes preserve existing filters like <code>init_plugin_suite_view_count_meta_key<\/code> and template behavior<\/li>\n<li>Maintained consistent behavior across REST API endpoints, <code>[init_view_list]<\/code>, and <code>[init_view_count]<\/code> shortcodes<\/li>\n<li>Improved code clarity and maintainability without altering plugin output or logic<\/li>\n<\/ul>\n\n<h4>1.8 \u2013 June 22, 2025<\/h4>\n\n<ul>\n<li>Added new \"Strict IP check\" option to block repeated views from the same IP in a short timeframe<\/li>\n<li>Uses hashed IPs and transient-based FIFO cache (default: 75 recent IPs per post)<\/li>\n<li>Designed to prevent fake views posted directly to the REST endpoint (e.g., bots, cURL scripts)<\/li>\n<li>Fully privacy-safe: does not store raw IPs and automatically expires over time<\/li>\n<li>New setting: \"Enable strict IP check?\" (disabled by default)<\/li>\n<\/ul>\n\n<h4>1.7 \u2013 June 21, 2025<\/h4>\n\n<ul>\n<li>Added Dashboard widget with [init_view_ranking] display<\/li>\n<li>Introduced admin-style.css optimized for clean, one-line layout<\/li>\n<li>REST API \/count now respects the batch limit setting to avoid overload<\/li>\n<\/ul>\n\n<h4>1.6 \u2013 June 19, 2025<\/h4>\n\n<ul>\n<li>Added batch view tracking option to reduce server requests on high-traffic sites<\/li>\n<li>Views can be temporarily stored in localStorage and sent in groups<\/li>\n<li>New setting: \"Batch view tracking\" (default = 1 for real-time)<\/li>\n<li>Updated JS to support batch logic with scroll + delay detection<\/li>\n<li>REST API now accepts multiple post IDs and returns array responses<\/li>\n<li>View count updates instantly after tracking, no reload needed<\/li>\n<\/ul>\n\n<h4>1.5 \u2013 June 16, 2025<\/h4>\n\n<ul>\n<li>Added shortcode builder panel to settings screen for easier shortcode generation<\/li>\n<li>Introduced new <code>init-shortcode-builder.js<\/code> with full shortcode configuration UI<\/li>\n<li>Supports <code>[init_view_list]<\/code>, <code>[init_view_ranking]<\/code>, and <code>[init_view_count]<\/code> shortcodes<\/li>\n<li>i18n-ready: all UI strings are fully translatable via <code>InitViewCountShortcodeBuilder.i18n<\/code><\/li>\n<li>Improved JS architecture to separate builder panel from core builder logic<\/li>\n<\/ul>\n\n<h4>1.4 \u2013 June 8, 2025<\/h4>\n\n<ul>\n<li>Introduced \"Trending\" scoring system based on daily views and post age (views per hour)<\/li>\n<li>Trending posts are calculated hourly via cron, optimized for high-traffic and large sites<\/li>\n<li>New <code>range=trending<\/code> support added to <code>\/top<\/code> REST endpoint with built-in sorting and pagination<\/li>\n<li>Shortcode <code>[init_view_list range=\"trending\"]<\/code> now fetches trending posts<\/li>\n<li>Internal meta key filtering is fully respected in all ranking and trending logic<\/li>\n<li>Improved post meta cleanup for day\/week\/month reset with filterable keys<\/li>\n<li>Prepared shortcode UI and REST responses for enhanced performance and data accuracy<\/li>\n<\/ul>\n\n<h4>1.3 \u2013 June 7, 2025<\/h4>\n\n<ul>\n<li>Added new <code>[init_view_ranking]<\/code> shortcode to display tabbed ranking UI by day\/week\/month\/all-time<\/li>\n<li>Shortcode uses lazy-loading via REST API and includes built-in skeleton loaders for smoother UX<\/li>\n<li>Fully compatible with headless or SPA environments \u2013 optimized to load only when visible<\/li>\n<li>All assets are conditionally enqueued: JS loads only when shortcode is used, styles are shared via <code>style.css<\/code><\/li>\n<\/ul>\n\n<h4>1.2 \u2013 June 5, 2025<\/h4>\n\n<ul>\n<li>Enqueued <code>style.css<\/code> earlier to avoid being printed in the footer<\/li>\n<li>Added toggle option to disable plugin\u2019s default CSS in the settings page<\/li>\n<li>Applied <code>init_plugin_suite_view_count_meta_key<\/code> consistently across REST API, shortcodes, and background tasks<\/li>\n<li>Fixed issue where custom meta key override was ignored in some cases<\/li>\n<\/ul>\n\n<h4>1.1 \u2013 May 28, 2025<\/h4>\n\n<ul>\n<li>Added <code>page<\/code> parameter to <code>\/top<\/code> REST endpoint for pagination<\/li>\n<li>Added <code>page<\/code> attribute to <code>[init_view_list]<\/code> shortcode for paginated lists<\/li>\n<li>Removed infinite scroll trigger for simplicity and better template control<\/li>\n<li>Fully compatible with existing templates and theme overrides<\/li>\n<\/ul>\n\n<h4>1.0 \u2013 May 18, 2025<\/h4>\n\n<ul>\n<li>Initial release  <\/li>\n<li>REST-based view counter  <\/li>\n<li>4 templates included  <\/li>\n<li>Fully extensible with filters\/hooks  <\/li>\n<li>Shortcodes with layout switching<\/li>\n<\/ul>","raw_excerpt":"Count post views accurately via REST API with customizable display. Lightweight, fast, and extensible. Includes shortcode with multiple layouts.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/235800","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=235800"}],"author":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/brokensmile2103-1"}],"wp:attachment":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=235800"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=235800"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=235800"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=235800"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=235800"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=235800"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}