Re: Ordering meta tags with HTML::Element
by Anonymous Monk on Jun 14, 2016 at 20:28 UTC
|
html doesn't care about ordering, so neither does HTML::Element, and neither should you ... but if you want to change it start by copy/pasting the source of as_HTML and changing it fit your desires | [reply] |
|
|
This is partially true. There are two? three? more? meta tags that are required to go first including some display related stuff and the always #1, since it affects everything that follows, <meta charset="UTF-8">.
| [reply] [d/l] |
|
|
Elements are ordered. Attributes are not.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] |
|
|
| [reply] |
|
|
|
|
|
|
|
Re: Ordering meta tags with HTML::Element
by codiac (Beadle) on Jun 15, 2016 at 11:15 UTC
|
Generally sub-classing is the way to go, but sub-classing HTML::Element can be pretty ugly, so not such an easy decision in this case.
If you aren't opposed to dirty little hacks, you could modify the attribute names you make to take advantage of the "sort keys" used in the starttag sub to order the attributes.
e.g. instead of
$m_el->attr('name',$m);
$m_el->attr('content',$meta{$m});
you write
$m_el->attr('aa01_name',$m);
$m_el->attr('aa02_content',$meta{$m});
Then you just post process $out to substitue in the real attribute names. e.g. $out =~ s/aa01_name/name/g
I only feel a little dirty ;)
| [reply] [d/l] [select] |
|
|
$m_el->attr(' name',$m);
$m_el->attr(' content',$meta{$m});
This way, the output would create the attribute "names" with their leading whitespace, but in the correct order. And hopefully, the receiving side won't care about the additional whitespace. | [reply] [d/l] |
Re: Ordering meta tags with HTML::Element
by tangent (Parson) on Jun 15, 2016 at 12:45 UTC
|
I am not able to reproduce your results. When I run your script it outputs in the correct order. When I change the case of the names the output changes as expected.
my %meta = (
"Author"=>"J K Rolling",
"title","Harry Potter and the Philosopher's Stone"
);
Sorts: Author, title
<meta content="J K Rolling" name="Author" />
<meta content="Harry Potter and the Philosopher's Stone" name="title"
+/>
my %meta = (
"author"=>"J K Rolling",
"Title","Harry Potter and the Philosopher's Stone"
);
Sorts: Title, author
<meta content="Harry Potter and the Philosopher's Stone" name="Title"
+/>
<meta content="J K Rolling" name="author" />
If I use an Array of Arrays to ensure the correct order I also get expected results:
my @meta = (
["Author"=>"J K Rolling"],
["title","Harry Potter and the Philosopher's Stone"]
);
Sorts: Author, title
<meta content="J K Rolling" name="Author" />
<meta content="Harry Potter and the Philosopher's Stone" name="title"
+/>
my @meta = (
["author"=>"J K Rolling"],
["Title","Harry Potter and the Philosopher's Stone"]
);
Sorts: author, Title
<meta content="J K Rolling" name="author" />
<meta content="Harry Potter and the Philosopher's Stone" name="Title"
+/>
The docs state that push_content "adds the specified items to the end of the content list of the element". Nothing about sorting, and in your case the element is the head. There is also an unshift_content.
I used this loop for the AoA:
for my $m ( @meta ) {
my $m_el = HTML::Element->new('meta');
$m_el->attr('name',$m->[0]);
$m_el->attr('content',$m->[1]);
$head->push_content($m_el);
}
| [reply] [d/l] [select] |
Re: Ordering meta tags with HTML::Element
by HeadScratcher (Novice) on Jun 15, 2016 at 07:33 UTC
|
Thanx for your input so far
I think I should clarify the the problem it's not browser, they don't care what order the meta data is or charset
The output is read by an automated process this is failing because it requires the meta tags to be name content eg
<meta name="Author" content="J K Rolling" />
<meta name="title" content="Harry Potter and the Philosopher's Stone"
+ />
This is a mok up of the problem the actual script is over 6000 lines so just not practical to upload here | [reply] [d/l] |
|
|
The output is read by an automated process this is failing because it requires the meta tags to be name content
In that case you have a problem because this "automated process" is not accepting valid HTML and pretty much any of the pre-written modules you might use (HTML::Element included) will not care about attribute ordering as has been discussed by my fellow monks already.
The real fix here is to change the "automated process" to avoid the insistence on attribute ordering. Failling that, I guess you will need to abandon HTML::Element and fall back on hand-rolling the HTML. Good luck.
| [reply] |
|
|
I have no control over the automated process
The only solution I have come up with is to do this but not very elegant I was hopping someone would have a better idea
for my $m (sort keys %meta)
{
my $m_el = HTML::Element->new('meta');
$m_el->attr('0name',$m);
$m_el->attr('1content',$meta{$m});
$head->push_content($m_el);
}
my $out = $body->as_HTML('<>&',' ',{});
$out=~s/0name/name/g;
$out=~s/1content/content/g;
print $out;
| [reply] [d/l] |
|
|
|
|
|
|
|
|
| [reply] |
|
|
6,000 lines. I am new here. Can't you use pastebin?
| [reply] |
|
|
6,000 lines. I am new here. Can't you use pastebin?
How would that help? No one reads 6000 lines. And it's off-site, probably getting lost over time. Not to mention confidentiality.
Generally, it is much more helpful to post a short, self-contained example right here.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] |
Re: Ordering meta tags with HTML::Element
by anonymized user 468275 (Curate) on Jun 21, 2016 at 12:52 UTC
|
You can control sorting by putting a sort routine after the sort keyword, e.g.:
for my $m (sort nameFirst ('fred', 'alf', 'tom', 'bert', 'name', 'pete
+')) {
print "$m\n";
}
sub nameFirst {
if ($a eq 'name') {
-1;
}
elsif ($b eq 'name') {
1;
}
else {
0;
}
}
sort calls your routine to test a pair which arrive in your routine as $a and $b. You can return the values explicitly although it is customary to just auto-evaluate for sort routines. Returning -1 or 1 tells sort what relative position to use for a given pair. 0 means 'evaluate equal or don't care, so leave as is'. The above produces:name
fred
alf
tom
bert
pete
update: if you have more complex rules than this, you can drill down to an evaluation subroutine or hash. For example, suppose the order should be name first and aref lastsub nameBlahAref {
naeval($a) <=> naeval($b);
}
sub naeval {
$_[0] eq 'name' and return 1;
$_[0] eq 'aref' and return 3;
return 2;
}
The <=> operator compares what is either side of it numerically and returns the required -1, 0 or 1 accordingly.
| [reply] [d/l] [select] |
Re: Ordering meta tags with HTML::Element
by Cow1337killr (Monk) on Jun 21, 2016 at 20:44 UTC
|
Here is a program I threw together after surfing the Internet.
#!/usr/bin/perl
# html_indenting2.pl perl html_indenting2.pl HTML indenting wit
+h Perl.
# From http://stackoverflow.com/questions/8225194/html-indenting-with-
+perl best answer
use strict;
use warnings;
use HTML::HTML5::Parser qw();
use HTML::HTML5::Writer qw();
use XML::LibXML::PrettyPrint qw();
print HTML::HTML5::Writer->new(
start_tags => 'force',
end_tags => 'force',
)->document(
XML::LibXML::PrettyPrint->new_for_html(
indent_string => "\t"
)->pretty_print(
HTML::HTML5::Parser->new->parse_string(
q[<meta content="J K Rolling" name="Author" />
<meta content="Harry Potter and the Philosopher's Stone" name="title"
+/>
]
)
)
);
# This prints:
# <!DOCTYPE html><html>
# <head>
# <meta content="J K Rolling" name=Author>
# <meta content="Harry Potter and the Philosopher's St
+one" name=title>
# </head>
# <body></body>
# </html>
__END__
The order of the meta content is the way you want it. | [reply] [d/l] |
|
|
The order of the meta content is the way you want it. No it isn't, its same problem as in the OP, not the order that "it should be"
| [reply] |
|
|
| [reply] |