Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello

Need help from Mojo experts. Is it possible to select an alternative html_entities.txt file provided by Mojo at runtime (i.e. dynamically)?

Replies are listed 'Best First'.
Re: Customize Mojo's html_entities.txt
by bliako (Abbot) on Aug 26, 2021 at 16:42 UTC

    In the source (and the ref you provided mentions this) of Mojo::Util html_entities.txt is hardcoded. From this file's contents %Mojo::Util::ENTITIES is constructed. So, it looks to me that without changing the filename in Mojo::Util you will not achieve what you want.

    However, this being Perl and this being Perlmonks, here is a workaround which should be applied to all script parts which use Mojo::Util;. This may not be surely is not practical.

    Mojo::Util provides the wonderfully named monkey_patch() which you can use to alter the only sub therein which uses %ENTITIES, which is Mojo::Util::_entity. And make it use your own (EDIT: e.g. _entity2 which is identical to the original but it uses your locally defined %ENTITIES which you create as you see fit):

    use Mojo::Util; my $str = '&#x3c;foo&#x3E;bar&lt;baz&gt;&#x0026;&#34;'; my $res1 = Mojo::Util::html_unescape($str); my %ENTITIES = (lt => '<<<', gt => '>>>'); Mojo::Util::monkey_patch 'Mojo::Util', _entity => \&_entity2; my $res2 = Mojo::Util::html_unescape($str); print "res1: $res1\n"; print "res2: $res2\n"; sub _entity2 { my ($point, $name, $attr) = @_; print "_entity2 called...\n"; # Code point return chr($point !~ /^x/ ? $point : hex $point) unless defined $nam +e; # Named character reference my $rest = my $last = ''; while (length $name) { return $ENTITIES{$name} . reverse $rest if exists $ENTITIES{$name} && (!$attr || $name =~ /;$/ || $last +!~ /[A-Za-z0-9=]/); $rest .= $last = chop $name; } return '&' . reverse $rest; }

    bw, bliako

      Nice!!!

Re: Customize Mojo's html_entities.txt
by bliako (Abbot) on Aug 26, 2021 at 17:20 UTC

    Here is another workaround, more practical and more down-to-earth:

    In your project's dir I assume you have lib/ with all your mojo code. Create dirs lib/Mojo and lib/Mojo/resources . Copy original Mojo::Util in lib/Mojo/Util.pm . In my linux box I can do whichpm Mojo::Util and get /usr/local/share/perl5/5.32/Mojo/Util.pm (to install whichpm do cpanm -f App::whichpm). Copy /usr/local/share/perl5/5.32/Mojo/resources/html_entities.txt into lib/Mojo/resources/html_entities.txt and edit according to your needs. This will be what Mojo::Util will use as its html_entities.txt. That's the first part.

    The second part is to modify your mojo-app script so that it looks for packages FIRST in your lib/ dir before anywhere else including the Mojolicious installation location. Mine looks like this:

    #!/usr/bin/env perl use strict; use warnings; our $VERSION = '0.01'; #ADD THIS before loading anything else #adjust catdir so that it finds 'lib' from where THIS script resides #mine is scripts/hero that's why I have the '..' use FindBin; use File::Spec; use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); # or just use lib a constant path to avoid loading extra packages ##### use Mojo::File qw(curfile); use Mojolicious::Commands; # Start command line interface for application Mojolicious::Commands->start_app('Hero');

    The caveat is that your local Mojo::Util will not be updated when Mojolicious gets an update. But there are workarounds for this too, I am sure.

    bw, bliako

Re: Customize Mojo's html_entities.txt
by Anonymous Monk on Aug 26, 2021 at 14:10 UTC

    PS: saw this post https://perlmonks.com/?node_id=11133963 but does not really address my issue