{"id":5625,"date":"2025-07-24T13:44:43","date_gmt":"2025-07-24T13:44:43","guid":{"rendered":"https:\/\/www.wizbrand.com\/tutorials\/?p=5625"},"modified":"2025-07-24T13:44:47","modified_gmt":"2025-07-24T13:44:47","slug":"counting-all-posts-on-a-joomla-website-from-an-external-app","status":"publish","type":"post","link":"https:\/\/www.wizbrand.com\/tutorials\/counting-all-posts-on-a-joomla-website-from-an-external-app\/","title":{"rendered":"Counting all posts on a Joomla website from an external app"},"content":{"rendered":"\n<p> Counting <strong>all posts<\/strong> on a Joomla website from an external app can be simple for some sites, but tricky for others due to varying configurations, templates, and security settings. Here\u2019s a complete guide to the <strong>options, methods, and caveats<\/strong> for programmatically fetching the total post count from Joomla-powered sites.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. <strong>Using Joomla\u2019s RSS\/Atom Feeds<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Many Joomla sites publish an RSS or Atom feed of their articles, usually at URLs like:\n<ul class=\"wp-block-list\">\n<li><code>https:\/\/example.com\/index.php?format=feed&amp;type=rss<\/code><\/li>\n\n\n\n<li><code>https:\/\/example.com\/index.php?option=com_content&amp;view=category&amp;layout=blog&amp;id=0&amp;format=feed<\/code><\/li>\n\n\n\n<li>Or, more simply: <code>https:\/\/example.com\/feed<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Pros:<\/strong> Quick, doesn\u2019t require authentication.<\/li>\n\n\n\n<li><strong>Cons:<\/strong> Most feeds show only the latest N articles (commonly 10\u201320). You <strong>cannot<\/strong> get the total count unless the feed includes a <code>&lt;totalResults><\/code> or similar tag (rare for Joomla).<\/li>\n\n\n\n<li><strong>How to use:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Fetch the feed via HTTP.<\/li>\n\n\n\n<li>Parse the XML.<\/li>\n\n\n\n<li>If the feed is paginated (has &#8220;next&#8221; links), iterate over all pages and sum articles. <strong>Most Joomla feeds are not paginated.<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. <strong>Sitemap Analysis<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Many Joomla sites use sitemap plugins (like OSMap or JSitemap), generating an XML sitemap (<code>\/sitemap.xml<\/code>).<\/li>\n\n\n\n<li><strong>Pros:<\/strong> Sitemaps often include all articles\/posts URLs.<\/li>\n\n\n\n<li><strong>Cons:<\/strong> Not all sites have sitemaps or may restrict access.<\/li>\n\n\n\n<li><strong>How to use:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Fetch <code>\/sitemap.xml<\/code> or search for <code>sitemap.xml<\/code> in <code>robots.txt<\/code>.<\/li>\n\n\n\n<li>Parse and count URLs corresponding to articles (usually under <code>\/article\/<\/code>, <code>\/news\/<\/code>, etc.).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. <strong>Joomla API (if enabled)<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Modern Joomla (4.x+) offers a web API (<code>\/api\/index.php\/v1\/content\/articles<\/code>) if enabled.<\/li>\n\n\n\n<li><strong>Pros:<\/strong> Official, structured, can return post counts or paginated lists.<\/li>\n\n\n\n<li><strong>Cons:<\/strong> API may be disabled, require authentication, or restricted by CORS.<\/li>\n\n\n\n<li><strong>How to use:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Call: <code>GET https:\/\/example.com\/api\/index.php\/v1\/content\/articles<\/code><\/li>\n\n\n\n<li>Look for a <code>total<\/code> or similar field in the response.<\/li>\n\n\n\n<li>Handle pagination: Some APIs return the total, others require you to iterate.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. <strong>HTML Scraping<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Scrape the website\u2019s blog or news index page.<\/li>\n\n\n\n<li><strong>Pros:<\/strong> Works where no feed\/API is present.<\/li>\n\n\n\n<li><strong>Cons:<\/strong> Fragile\u2014depends on site\u2019s template; changes can break your code.<\/li>\n\n\n\n<li><strong>How to use:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Request the articles listing page (<code>\/blog<\/code>, <code>\/news<\/code>, etc.).<\/li>\n\n\n\n<li>Parse the HTML to detect total count (some sites display \u201cShowing X of Y articles\u201d).<\/li>\n\n\n\n<li>If not, scrape all paginated pages and count articles manually.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. <strong>Database Access or Custom Extension<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Ask the site owner to provide an endpoint or run a custom extension\/plugin.<\/li>\n\n\n\n<li><strong>Pros:<\/strong> 100% accurate.<\/li>\n\n\n\n<li><strong>Cons:<\/strong> Only possible if you control the site or have an arrangement with the owner.<\/li>\n\n\n\n<li><strong>How to use:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Site owner installs a small plugin that exposes post count via a custom endpoint.<\/li>\n\n\n\n<li>Or, provides periodic post counts via API or email.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. <strong>Third-party Plugins\/Analytics<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How:<\/strong> Some plugins (e.g., \u201cArticle Counts\u201d, \u201cSP Page Builder\u201d, etc.) may expose statistics publicly.<\/li>\n\n\n\n<li><strong>How to use:<\/strong> Check if such a plugin is installed and exposes a public stats page or API.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. <strong>Indirect Methods<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Search Engines:<\/strong> Sometimes you can estimate article count by searching <code>site:example.com<\/code> and restricting to \u201cnews\u201d or \u201cblog\u201d URLs, but this is unreliable and often inaccurate.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Best Practices &amp; Considerations<\/strong><\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Respect robots.txt:<\/strong> Always check if scraping or crawling is allowed.<\/li>\n\n\n\n<li><strong>Handle Pagination:<\/strong> If fetching from APIs or feeds, handle pagination to avoid missing articles.<\/li>\n\n\n\n<li><strong>Respect Rate Limits:<\/strong> Don\u2019t hammer the site with requests; add delays if scraping.<\/li>\n\n\n\n<li><strong>Expect Security Blocks:<\/strong> Some sites use firewalls (like mod_security), CAPTCHAs, or block non-browser user agents.<\/li>\n\n\n\n<li><strong>User-Agent:<\/strong> Set a polite user-agent string identifying your app.<\/li>\n\n\n\n<li><strong>Fallbacks:<\/strong> If one method fails (e.g., API\/Feed disabled), try the next.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Summary Table<\/strong><\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Method<\/th><th>Accuracy<\/th><th>Reliability<\/th><th>Requires Auth<\/th><th>Bypass Limits?<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>RSS\/Atom Feed<\/td><td>Low-Med<\/td><td>Med-High<\/td><td>Rarely<\/td><td>No<\/td><td>Good for recent posts only<\/td><\/tr><tr><td>Sitemap<\/td><td>High<\/td><td>Med<\/td><td>No<\/td><td>No<\/td><td>Best if available<\/td><\/tr><tr><td>Joomla API<\/td><td>High<\/td><td>Low-Med<\/td><td>Often<\/td><td>No<\/td><td>Only on modern, open APIs<\/td><\/tr><tr><td>HTML Scraping<\/td><td>Med<\/td><td>Med-Low<\/td><td>No<\/td><td>Maybe<\/td><td>Fragile, template-dependent<\/td><\/tr><tr><td>DB\/Custom Plugin<\/td><td>High<\/td><td>High<\/td><td>Yes<\/td><td>Yes<\/td><td>Only with owner permission<\/td><\/tr><tr><td>3rd-party Plugins<\/td><td>High<\/td><td>Low<\/td><td>Sometimes<\/td><td>No<\/td><td>If stats page\/API is public<\/td><\/tr><tr><td>Search Engine<\/td><td>Low<\/td><td>Low<\/td><td>No<\/td><td>No<\/td><td>Very rough estimate<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Example: Pseudocode for All Methods<\/strong><\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>function fetchJoomlaPostCount($url) {\n    \/\/ 1. Try API\n    $apiUrl = $url . '\/api\/index.php\/v1\/content\/articles';\n    $apiRes = fetchApi($apiUrl);\n    if ($apiRes &amp;&amp; isset($apiRes&#91;'total'])) return $apiRes&#91;'total'];\n\n    \/\/ 2. Try RSS Feed\n    $feedUrl = $url . '\/index.php?format=feed&amp;type=rss';\n    $feed = fetchFeed($feedUrl);\n    if ($feed &amp;&amp; isset($feed&#91;'totalResults'])) return $feed&#91;'totalResults'];\n    \/\/ ...or iterate paginated feeds (if present)\n\n    \/\/ 3. Try Sitemap\n    $sitemapUrl = $url . '\/sitemap.xml';\n    $sitemapCount = countArticlesInSitemap($sitemapUrl);\n    if ($sitemapCount) return $sitemapCount;\n\n    \/\/ 4. Try HTML Scraping\n    $listPageUrl = $url . '\/blog'; \/\/ or news, articles, etc.\n    $htmlCount = scrapeArticleCount($listPageUrl);\n    if ($htmlCount) return $htmlCount;\n\n    \/\/ 5. All failed\n    return null;\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>TL;DR<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Best case:<\/strong> Use Joomla API or sitemap.<\/li>\n\n\n\n<li><strong>Fallback:<\/strong> RSS feed, then HTML scraping.<\/li>\n\n\n\n<li><strong>Worst case:<\/strong> No way to get accurate count if the site is locked down.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Counting all posts on a Joomla website from an external app can be simple for some sites, but tricky for [&hellip;]<\/p>\n","protected":false},"author":19,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5625","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/posts\/5625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/comments?post=5625"}],"version-history":[{"count":1,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/posts\/5625\/revisions"}],"predecessor-version":[{"id":5626,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/posts\/5625\/revisions\/5626"}],"wp:attachment":[{"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/media?parent=5625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/categories?post=5625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wizbrand.com\/tutorials\/wp-json\/wp\/v2\/tags?post=5625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}