MoritzLost Posted November 22, 2018 Share Posted November 22, 2018 This is a textformatter module that will automatically replace titles of other pages on your site with links to those pages. For example, if you have a template glossary-term, and mention the exact title of one page using that template in a textfield, the title will be automatically linked to that page (if the textfield uses that formatter). This is good for SEO, and saves you some manual labour. You can configure which templates should get automatically linked, and of course the formatter is only active for the fields you add this formatter to. Note that if you need more manual control over when and where titles are automatically linked, you're probably better of using Autolink from a Glossary by @mr-fan. Features Allows you to limit the automatic links by template. Only includes published & visible pages by default, with an option to include hidden pages. Automatically excludes the current page, with an option to change that behaviour. Allows you to configure the minimum title length for linked pages. Doesn't overwrite existing links, and detects most edge cases (titles inside other tag's attributes, titles inside existing links et c.). Supports multi-language sites. Titles will only be linked if a title in the current language is set. Can add configurable attributes to all automatically created links. This includes the ability to use page fields as replacement patterns for attributes. For example, you can create CSS classes that include the name of the template of the linked page. Extensive options and hooks to change the generated markup completely. Need <mark> elements with a title attribute based on a page field instead of a link? No problem. See the example project below. Prefer oldest or newest page in the case of duplicate titles. Queries the database directly for improved performance. Has options to switch between case sensitive and case insensitive modes, and force case sensitive behaviour even for case insensitive database collations. Allows you to overwrite the module configuration via the API to call the module with different settings for different requirements on the same site. Download & Documentation The module is now available in the modules directory: https://modules.processwire.com/modules/textformatter-page-title-links/ You can download & install it through the backend using the classname TextformatterPageTitleLinks. To install it manually, download or clone the module from the Github repository into your site/modules folder and install through the backend. The complete documentation can be found in the README in the repository. Make sure to check out the module configuration page after installing the module. Requirements PHP 7.1 or higher ProcessWire 3+ (it will probably work in older versions, I haven't tested those though). This is my first module, I hope it may become useful to some of you ? If you find any errors or have some other suggestions or feedback, let me know! 11 Link to comment Share on other sites More sharing options...
MoritzLost Posted January 17, 2019 Author Share Posted January 17, 2019 (edited) Changelog The changelog can now be found in the module directory itself, see CHANGELOG.md. Edited September 30, 2019 by MoritzLost Added link to repository changelog 5 Link to comment Share on other sites More sharing options...
MoritzLost Posted February 3, 2019 Author Share Posted February 3, 2019 I just pushed version 2.1.0 to Github & the modules directory! Includes a minimum length settings for linkable titles, a preference to link the oldest or most recent page if multiple pages have the same title, and an important bugfix for older MySQL versions. Check out the full changelog above ? Link to comment Share on other sites More sharing options...
MoritzLost Posted September 30, 2019 Author Share Posted September 30, 2019 I just pushed a big update to the textformatter with version 3.0.0! I'm not sure if anyone is actually using this module, but at least for my own projects it has been useful, and it's good training for MySQL intricacies, so I'm still updating it when I think of new stuff to add ? With the updated version, it's now possible to overwrite any option from the module configuration when calling the module manually in your template code. That way, you can automatically link to pages of different templates in different contexts on the same site, or customize the behaviour of the textformatter any way you want! Also, there's now an option to toggle case insensitive behaviour, if needed, as well as an option to force case sensitive queries for case insensitive database collations. The changelog is now included in the repository itself, I also updated the readme with instructions on how to call the module manually. Make sure to check out the full changelog for version 3.0.0, as well as the readme section on manual usage. Let me know if the module is or isn't working for you, and any suggestions you have on how to improve it! 2 Link to comment Share on other sites More sharing options...
MoritzLost Posted August 7, 2020 Author Share Posted August 7, 2020 I just published version 4.0.0 of this module, a large update that makes it possible to completely customize the markup created for detected page titles. For example, let's say you have a glossary and want glossary terms that appear anywhere on your site to display a popover with the term's definition. This update allows you to do that! Previously, the module always created an <a> tag with an href attribute, and always checked if the page was viewable before doing anything. This update comes with configuration options to change the HTML tag, disable the automatic href attribute and disable the visibility check. This allows you to use the module for a wider range of use-cases. If you need even more control, the methods the module uses to create markup are now hookable, so you can customize the output format even further! Here are some additional links to help you get started: There's a new step-by-step guide for a setup with glossary terms with inline definitions. Both new hooks are documented with usage examples in the hooks documentation, learn how to customize the markup generated for titles and how to add attributes to the generated link / HTML tag dynamically. All the new options are available for manual usage, find the list of options here. Check out the CHANGELOG for version 4.0.0 2 Link to comment Share on other sites More sharing options...
MoritzLost Posted September 4, 2020 Author Share Posted September 4, 2020 The new version 4.1.0 includes an important bug fix: The module will now exclude pages in the trash from being linked! 1 Link to comment Share on other sites More sharing options...
wbmnfktr Posted November 10, 2020 Share Posted November 10, 2020 Ahoi @MoritzLost, just installed your module/textformatter again in a new project. I knew it from previous installations but now... I can't get it working as expected. I set up the templates, added the textformatter to my textarea fields but there is no chance internal pages get any links. What would be the best way to debug that? I'm running a 3.0.165 on a PHP 7.4 and MySQL 5.6 environment. I almost know that isn't a bug in the module itself but I really don't know how to trace down the problem. Any ideas are welcome. 1 Link to comment Share on other sites More sharing options...
MoritzLost Posted November 11, 2020 Author Share Posted November 11, 2020 @wbmnfktr Hm, if you're using the latest version (4.1.0), there are a couple of settings you can check (Modules -> Configure -> TextformatterPageTitleLinks). Here's a list of all settings and what they do: https://github.com/MoritzLost/TextformatterPageTitleLinks#all-settings A couple of possible reasons: Have you selected the templates you want to be linkable? With no templates selected, the module does nothing. In your template output, is output formatting turned on? With output formatting disabled, textformatters aren't applied. Since you said "internal pages", are those visible (not hidden) and does the corresponding PHP template file exist? Templates without a template file are not viewable by default, so they won't get linked. In this case, you may need to check both Include hidden pages and Disable automatic visibility check. There are other options that limit which pages may be linked, especially Minimum length for linkable titles and Use case insensitive mode, make sure none of those are the culprit. Is your site multi-language? The module only links titles in the current language and doesn't fall back to the default language if the current language title is empty. So if you're checking in a non-default language and your pages have empty titles in that language, nothing will get linked. If all those settings are correct, I'd start by checking which pages the module selects as candidates for automatic links. If you're using Tracy Debugger, you can check with barDump (otherwise, just use var_dump). Insert this in TextformatterPageTitleLinks.module#L101-L103: // get all pages of the selected templates as an associative id => title array $id_title_array = $this->getTitleIdArrayForCurrentLanguage($template_ids, $options); bd($id_title_array); This should dump the array of pages (keyed by page ID) to the Tracy Debugger bar. If you don't see anything, the textformatter isn't being executed at all. If you see an empty array or the pages you want to link to aren't there, the reason is likely one of the settings above. If the pages you want to link to are included in the array but still don't get linked, it might just be the viewable check (see above). In this case, check what buildTitleMarkup returns in TextformatterPageTitleLinks.module#L147-L148. Hope this helps! If it's still not working, please post the output of the debug statements and preferably a screenshot of your module settings and I'll take a look. Link to comment Share on other sites More sharing options...
wbmnfktr Posted November 12, 2020 Share Posted November 12, 2020 That's awesome @MoritzLost! This will help a lot. I'll dig deeper into the problem today and let you know the results. 1 Link to comment Share on other sites More sharing options...
wbmnfktr Posted November 15, 2020 Share Posted November 15, 2020 So... even though it will embarass me to new heights... I will post the details to this issue and the details to resolve them. I used and tried each and every measure @MoritzLost posted in his previous post BUT... NO RESULTS at all or as Moritz would say The module isn't running at all. His assumption was 100% correct. The module wasn't evoked, triggered or called at all. Lucky me... the jackpot. All debug-measures resulted in zero results. So... I went back to the classic debugging once again (which I should have done before). 1. module setup defaults - fine! 2. field setup defaults - fine! 3. module setup details, each and every possible setup option tried - fine! 4. field setup details, each and every Textformatter enabled/disabled - whooops!!! My body field (textarea, CKEditor) with Hanna, PrivacyWire and ALPT formatter didnt't play well together. Re-Ordering each and every textformatter didn't help. Removing all and re-assinging each of those, one after the other, worked out fine! In my case ... in all setups and versions (based on the non-working setup) this helped: Deleting all Textformatters from field -> save field Adding ALPT -> save field Adding PrivacyWire -> save field Adding Hanna -> save field Everything is working now as expected! I don't know which textformatter might have been the issue or whatever details caused this BUT... if this happens again to me, I will probably reset, remove and add all textformatters to make it work again. Thank you @MoritzLost - for the debugging details and the module again! 1 Link to comment Share on other sites More sharing options...
MoritzLost Posted November 15, 2020 Author Share Posted November 15, 2020 @wbmnfktr Thanks for the update, glad you got it working! Not sure how removing the textformatters and adding them again should change anything, but as long as it's working now ... ? Link to comment Share on other sites More sharing options...
wbmnfktr Posted November 18, 2020 Share Posted November 18, 2020 To be honest... I don't know as well. This kind of behaviour is totally new to me but on the other side... I almost never have to deal with almost any textformatter plugins/modules/extensions. I guess it was a huge hickup or some kind of this as it was the first time ever I had to deal with this kind of problem in any of my setups. Nontheless your module does a pretty good job - as soon as it runs in a setup. 1 Link to comment Share on other sites More sharing options...
mel47 Posted December 4, 2020 Share Posted December 4, 2020 Hi, Thanks for your module. It works really, maybe too much! ? I'm wondering if there a way I can limit to the first occurrence of a link in a page by a hook or something. I like the automatic behavior of the module, however I have pages where I repeat the same word each 2-3 sentences, rendering the paragraph looks as a big link to the same page. Thanks Mel Link to comment Share on other sites More sharing options...
bernhard Posted December 4, 2020 Share Posted December 4, 2020 On 12/4/2020 at 4:00 AM, mel47 said: Thanks for your module. It works really, maybe too much! ? I'm wondering if there a way I can limit to the first occurrence of a link in a page by a hook or something. I like the automatic behavior of the module, however I have pages where I repeat the same word each 2-3 sentences, rendering the paragraph looks as a big link to the same page. Expand Maybe this module would be a better fit then? Link to comment Share on other sites More sharing options...
MoritzLost Posted December 4, 2020 Author Share Posted December 4, 2020 On 12/4/2020 at 4:00 AM, mel47 said: Thanks for your module. It works really, maybe too much! ? I'm wondering if there a way I can limit to the first occurrence of a link in a page by a hook or something. I like the automatic behavior of the module, however I have pages where I repeat the same word each 2-3 sentences, rendering the paragraph looks as a big link to the same page. Expand @mel47 Hi Mel, glad the module is working well for you! You can change the way links are created or prevent them entirely using the hook TextformatterPageTitleLinks::buildTitleMarkup (see the link for the documentation). This method is called for every title found in a text field and returns the HTML to replace the link. You can overwrite this to just return the title in certain conditions, which means no link will be created. Here's a hook that will keep track of which titles have already been linked and prevent more than one link per occurance of each page title: // limit automatic links to one per individual title, even if the title appears multiple times on the page wire()->addHookAfter('TextformatterPageTitleLinks::buildTitleMarkup', function (HookEvent $e) { $title = $e->arguments(0); $page = $e->arguments(1); $options = $e->arguments(2); // keep track of all the titles that have already been linked static $alreadyLinkedTitles = []; if (in_array($title, $alreadyLinkedTitles)) { // if the title has already been linked, overwrite the HTML markup with the plain title $e->return = $title; } else { // otherwise, just add the title to the array of linked titles $alreadyLinkedTitles[] = $title; } }); A couple of caveats: The static array will not distinguish between fields, so this will limit the automatic links to one link per title on the whole page, not one link per title within one field (though it sounds like this is what you want). If you access the same field multiple times in your template, it will only contain links the first time. Another solution, if the word you're repeating multiple times is very short, you can just use the minimum length setting to prevent it getting linked, or use the hook above to prevent automatic links for a few specific pages. I hope this works for you! If you need even more fine control, it might be simpler to create the links manually or use another module as suggested by @bernhard. 2 Link to comment Share on other sites More sharing options...
Pip Posted December 22, 2020 Share Posted December 22, 2020 Hi @MoritzLost Thanks for making the module. It's really handy for sites that have majorly a lot of pages. I'm working on a game site where there are heroes and their special abilities, items, etc. . Was totally delighted that it was working on my test environment but I noticed that (sorry if it feels snobbish but itemizing helps me think lol) hyperlinking only works on the Body textarea it only works on one page template so it seems I have two templates - hero and hero-ability. They're both in the module settings. I've also counter checked that my textarea fields have the same settings as the Body textarea. Did I do something wrong? Or did I misunderstand something? Thanks. 1 Link to comment Share on other sites More sharing options...
MoritzLost Posted December 22, 2020 Author Share Posted December 22, 2020 Hi @Pip, thanks for reaching out, I think I know what the problem is. The module should work with any number of templates and on any number of fields. However, before creating a link for a given title, the module checks if the page the title belongs to is actually viewable. I made this the default because for a "normal" use case it doesn't make sense to create a link to a page the current user can't actually view. Based on your screenshots it looks like you display all hero abilities on the page for that hero, so I'm guessing the hero abilities don't have their own sub-pages in the frontend? If there's no hero-ability.php template, no hero-ability pages will be viewable, so the module will not create any links for those. In version 4.0.0 of the module I added a checkbox to disable the viewable checks for use cases like this one. Your screenshot looks like your site has an older version installed, so make sure to update to the latest version if you don't see the checkbox. After the update the option should appear in the new configuration fieldset Markup and output settings. By the way if my assumption is correct, you may want to use the hook TextformatterPageTitleLinks::buildTitleMarkup to modify the link for hero-ability pages to point to that ability on the hero page instead (using anchor links). See my answer here for details. If that doesn't solve the problem: I've written a bit about how to check what the module is doing in my answer here, use that to determine whether the module (a) is not finding the desired titles or (b) is finding the titles but not creating links for them. This can help you find out what's going wrong. Let me know if you need more help! 2 Link to comment Share on other sites More sharing options...
Pip Posted December 25, 2020 Share Posted December 25, 2020 On 12/22/2020 at 5:41 PM, MoritzLost said: Hi @Pip, thanks for reaching out, I think I know what the problem is. The module should work with any number of templates and on any number of fields. However, before creating a link for a given title, the module checks if the page the title belongs to is actually viewable. I made this the default because for a "normal" use case it doesn't make sense to create a link to a page the current user can't actually view. Based on your screenshots it looks like you display all hero abilities on the page for that hero, so I'm guessing the hero abilities don't have their own sub-pages in the frontend? If there's no hero-ability.php template, no hero-ability pages will be viewable, so the module will not create any links for those. In version 4.0.0 of the module I added a checkbox to disable the viewable checks for use cases like this one. Your screenshot looks like your site has an older version installed, so make sure to update to the latest version if you don't see the checkbox. After the update the option should appear in the new configuration fieldset Markup and output settings. By the way if my assumption is correct, you may want to use the hook TextformatterPageTitleLinks::buildTitleMarkup to modify the link for hero-ability pages to point to that ability on the hero page instead (using anchor links). See my answer here for details. If that doesn't solve the problem: I've written a bit about how to check what the module is doing in my answer here, use that to determine whether the module (a) is not finding the desired titles or (b) is finding the titles but not creating links for them. This can help you find out what's going wrong. Let me know if you need more help! Expand Hi @MoritzLost Tried your recommendation. You're right the hero-ability.php was non existing. Recreated it and is now linking automatically! Thanks so much! Happy Holidays! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now