{"id":347193,"date":"2026-08-03T13:28:48","date_gmt":"2026-08-03T13:28:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/ecorp-internal-links\/"},"modified":"2026-08-03T13:57:46","modified_gmt":"2026-08-03T13:57:46","slug":"ecorp-internal-links","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/ecorp-internal-links\/","author":23539999,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2.0","stable_tag":"1.2.0","tested":"7.0.2","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"ECORP Internal Links","header_author":"ECORP","header_description":"Turns chosen keywords into internal links automatically, with a per-post limit and strictly safe HTML handling. Built by ECORP.","assets_banners_color":"141c30","last_updated":"2026-08-03 13:57:46","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/kvngch\/ecorp-internal-links","header_author_uri":"https:\/\/ecorp-agency.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":41,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.0":{"tag":"1.2.0","author":"ecorpagency","date":"2026-08-03 13:57:46"}},"upgrade_notice":{"1.2.0":"<p>First directory release. Settings are stored under new option keys.<\/p>","1.1.0":"<p>Stops posts from linking to themselves.<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3632969,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3632969,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3632957,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3632957,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3632957,"resolution":"1","location":"assets","locale":"","width":1280,"height":938}},"screenshots":{"1":"The settings screen: keyword to URL rules, the per-post link limit, link attributes and the post types automatic linking runs on."}},"plugin_section":[],"plugin_tags":[25078,12539,37125,6681,186],"plugin_category":[55],"plugin_contributors":[274328],"plugin_business_model":[],"class_list":["post-347193","plugin","type-plugin","status-publish","hentry","plugin_tags-anchor-text","plugin_tags-autolink","plugin_tags-interlinking","plugin_tags-internal-links","plugin_tags-seo","plugin_category-seo-and-marketing","plugin_contributors-ecorpagency","plugin_committers-ecorpagency"],"banners":{"banner":"https:\/\/ps.w.org\/ecorp-internal-links\/assets\/banner-772x250.jpg?rev=3632957","banner_2x":"https:\/\/ps.w.org\/ecorp-internal-links\/assets\/banner-1544x500.jpg?rev=3632957","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/ecorp-internal-links\/assets\/icon-128x128.png?rev=3632969","icon_2x":"https:\/\/ps.w.org\/ecorp-internal-links\/assets\/icon-256x256.png?rev=3632969","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/ecorp-internal-links\/assets\/screenshot-1.png?rev=3632957","caption":"The settings screen: keyword to URL rules, the per-post link limit, link attributes and the post types automatic linking runs on."}],"raw_content":"<!--section=description-->\n<p>ECORP Internal Links builds your internal linking silo for you. You define\na list of keyword to URL rules once, and every matching keyword is turned into a\nlink as your content is rendered. Your posts are never modified in the database:\nthe plugin works on output only, so removing it removes every generated link.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li>Links each keyword on its <strong>first occurrence only<\/strong>, so a page never repeats the same link.<\/li>\n<li>Enforces a <strong>global limit<\/strong> of automatically inserted links per post.<\/li>\n<li>Never lets a post link to itself: a rule pointing at the page being displayed\nis skipped, and does not consume the per-post limit.<\/li>\n<li>Optionally opens links in a new tab (<code>target=\"_blank\"<\/code> plus <code>rel=\"noopener\"<\/code>).<\/li>\n<li>Optionally marks inserted links as <code>rel=\"nofollow\"<\/code>.<\/li>\n<li>Runs only on the post types you enable.<\/li>\n<\/ul>\n\n<h4>Where it will never insert a link<\/h4>\n\n<p>Correctness here matters more than coverage, so the matcher skips every context\nwhere an automatic link would be invalid or unwanted:<\/p>\n\n<ul>\n<li>inside an existing <code>&lt;a&gt;<\/code> element, so links are never nested;<\/li>\n<li>inside <code>&lt;h1&gt;<\/code> to <code>&lt;h6&gt;<\/code> headings;<\/li>\n<li>inside <code>&lt;script&gt;<\/code>, <code>&lt;style&gt;<\/code>, <code>&lt;code&gt;<\/code>, <code>&lt;pre&gt;<\/code>, <code>&lt;kbd&gt;<\/code> and <code>&lt;samp&gt;<\/code>;<\/li>\n<li>inside form controls such as <code>&lt;textarea&gt;<\/code>, <code>&lt;button&gt;<\/code>, <code>&lt;select&gt;<\/code>, <code>&lt;option&gt;<\/code> and <code>&lt;label&gt;<\/code>;<\/li>\n<li>inside <code>&lt;iframe&gt;<\/code>, <code>&lt;svg&gt;<\/code>, <code>&lt;noscript&gt;<\/code> and <code>&lt;template&gt;<\/code>;<\/li>\n<li>inside HTML comments;<\/li>\n<li>inside <strong>any HTML attribute<\/strong>, including <code>alt<\/code>, <code>title<\/code>, <code>src<\/code> and <code>href<\/code>.<\/li>\n<\/ul>\n\n<h4>Built for real content<\/h4>\n\n<ul>\n<li>Matching is accent aware and case insensitive, and the original casing of the\nmatched text is preserved in the anchor.<\/li>\n<li>Word boundaries are Unicode aware: a rule for <code>SEO<\/code> never matches inside\n  SEOquencer, and a rule for <code>r\u00e9f\u00e9rencement<\/code> never matches <code>r\u00e9f\u00e9rencements<\/code>.<\/li>\n<li>Longer expressions win over shorter ones, so <code>internal linking strategy<\/code> is\npreferred over <code>internal linking<\/code> when both are defined.<\/li>\n<li>Multi word keywords still match across a line break or a non breaking space.<\/li>\n<\/ul>\n\n<h4>Performance<\/h4>\n\n<p>Rendered output is stored in the WordPress object cache, keyed by a version\nnumber that is bumped whenever you save your settings. On a site with a\npersistent object cache the transformation runs once per post revision; without\none, repeated <code>the_content<\/code> calls within the same request are still served from\nmemory.<\/p>\n\n<h4>Developer filters<\/h4>\n\n<ul>\n<li><code>ecorp_il_should_process<\/code>: decide per post whether automatic linking runs.<\/li>\n<li><code>ecorp_il_filter_priority<\/code>: change the <code>the_content<\/code> hook priority (default 20).<\/li>\n<li><code>ecorp_il_protected_tags<\/code>: adjust the list of protected elements.<\/li>\n<li><code>ecorp_il_link_attributes<\/code>: change the attributes of every inserted link.<\/li>\n<li><code>ecorp_il_link_rel<\/code>: change the <code>rel<\/code> values of every inserted link.<\/li>\n<li><code>ecorp_il_cache_ttl<\/code>: change the cache lifetime.<\/li>\n<li><code>ecorp_il_selectable_post_types<\/code>: change the post types offered in the settings screen.<\/li>\n<\/ul>\n\n<p>This plugin is built and maintained by <a href=\"https:\/\/ecorp-agency.com\">ECORP<\/a>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>, or install it from the Plugins screen.<\/li>\n<li>Activate the plugin.<\/li>\n<li>Go to <strong>Settings &gt; Internal Links<\/strong>.<\/li>\n<li>Add your keyword to URL rules, pick a maximum number of links per post, and select the post types to enable.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20modify%20my%20posts%3F\"><h3>Does this modify my posts?<\/h3><\/dt>\n<dd><p>No. The plugin filters <code>the_content<\/code> at render time. Your post content in the\ndatabase is untouched, and deactivating the plugin removes every generated link.<\/p><\/dd>\n<dt id=\"why%20is%20my%20keyword%20not%20being%20linked%3F\"><h3>Why is my keyword not being linked?<\/h3><\/dt>\n<dd><p>Check the following, in order:<\/p>\n\n<ol>\n<li>The post type of the page is enabled in the settings.<\/li>\n<li>The maximum number of links per post has not already been reached by earlier rules.<\/li>\n<li>The keyword does not appear only inside a heading, an existing link, a code block or an HTML attribute.<\/li>\n<li>The keyword appears as a whole word. <code>SEO<\/code> will not match inside <code>SEOquencer<\/code>.<\/li>\n<li>The rule does not point at the page you are looking at. A post is never linked to itself.<\/li>\n<\/ol><\/dd>\n<dt id=\"will%20a%20post%20link%20to%20itself%3F\"><h3>Will a post link to itself?<\/h3><\/dt>\n<dd><p>No. When a rule targets the page currently being displayed, it is skipped. The\ncomparison ignores the protocol, a leading <code>www.<\/code> and a trailing slash, so the\nrule is recognised whichever form you pasted. A link to an anchor on the same\npage, such as <code>\/my-post\/#section<\/code>, is still allowed.<\/p><\/dd>\n<dt id=\"in%20which%20order%20are%20the%20rules%20applied%3F\"><h3>In which order are the rules applied?<\/h3><\/dt>\n<dd><p>Rules are applied in the order the keywords appear in the content, not in the\norder they are listed in the settings. When two rules could match the same text,\nthe longer keyword wins.<\/p><\/dd>\n<dt id=\"can%20i%20disable%20linking%20on%20a%20specific%20post%3F\"><h3>Can I disable linking on a specific post?<\/h3><\/dt>\n<dd><p>Yes, with a small snippet using the <code>ecorp_il_should_process<\/code> filter:<\/p>\n\n<pre><code>add_filter( 'ecorp_il_should_process', function ( $enabled, $post_id ) {\n    return get_post_meta( $post_id, 'disable_autolinks', true ) ? false : $enabled;\n}, 10, 2 );\n<\/code><\/pre><\/dd>\n<dt id=\"does%20it%20work%20with%20the%20block%20editor%3F\"><h3>Does it work with the block editor?<\/h3><\/dt>\n<dd><p>Yes. The filter runs after blocks and shortcodes have been rendered, so it\noperates on the final HTML.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>First release on the WordPress.org plugin directory.<\/li>\n<li>Renamed to ECORP Internal Links. Option keys, filters and CSS classes now use\nthe <code>ecorp_il<\/code> prefix.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>A post is never linked to itself. A rule targeting the page being displayed is\nskipped, and does not consume the per-post link limit.<\/li>\n<li>Settings screen restyled to the ECORP brand guidelines.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Turn chosen keywords into internal links automatically, with a per-post limit and strictly safe HTML handling.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/347193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=347193"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/ecorpagency"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=347193"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=347193"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=347193"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=347193"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=347193"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=347193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}