Skip to content

[ticket/15538] Twig icon function#5545

Merged
marc1706 merged 25 commits intomasterfrom
unknown repository
Dec 1, 2019
Merged

[ticket/15538] Twig icon function#5545
marc1706 merged 25 commits intomasterfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Mar 8, 2019

PHPBB3-15538

Checklist:

  • Correct branch: master for new features; 3.2.x for fixes
  • Tests pass
  • Code follows coding guidelines: master and 3.2.x
  • Commit follows commit message format

Tracker ticket (set the ticket ID to your ticket ID):

https://tracker.phpbb.com/browse/PHPBB3-15538


For usage in the Chameleon style.

Reference PR's: #5489 & #4765

The only thing to be added from this PR is the twig extension (declaration and class), the rest is for testing purposes and the icon templates should go in the Chameleon style.

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 8, 2019

Couple of things to discuss:

Currently using the DOMDocument approach to manipulate the SVG file, as this is often considered a better approach than using preg_replace(). However, DOMDocument does not like HTML5 and SVG's, as loadHTML() will throw:

An exception has been thrown during the rendering of a template ("Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 1")

Therefore suppression is needed, currently simply done by @, but not sure what the prefered method is?
@ or libxml_use_internal_errors(true) and libxml_clear_errors()?

Moreover, eventhough I am currently using the DOMDocument approach, I would like to point out that the preg_replace approach is a lot faster. I did some timing tests, with a 1000 iterations (time in seconds):

  • DOMDocument:
    • Total time: 0.12599396705627
    • Average time: 0.00012599396705627
  • preg_replace:
    • Total time: 0.0043911933898926
    • Average time: 4.3911933898926E-6

And lastly, currently there are two instances of where I catch \Twig_Error inside the icon() function. Should those errors be logged in the admin/error log?

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 8, 2019

!set WIP 🚧

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 9, 2019

Then I still need to know what elements and attributes to remove / replace for SVG's?
Currently removing any <title> element, along with all its children.
Removing any <svg> element, but preserving its children.
Removing any fill="" attribute, except if its value is none.

Also, in an other comment that you would also like to use this for forum icons, I'm guessing you mean "New Post", "Forum locked", etc with that. Why would they go in a different directory than the theme? It sounds like they are very closely tight to the actual theme and currently a lot of them already use different ones. Instead, perhaps you can just add a class to the icon like o-forum-icon or w/e.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 9, 2019

Any and all fill rules are ok. You not not need to sanitize any of the content other than the svg tag and the title needs to be dynamic as you have done. The rest of the contents just pass through.

This will be used for everything potentially which includes:
Icons = anything currently handled by font-awesome
Forum icons = the icons added when you create a forum currently found in the files folder
Imagesets = the images in front of the forum and topic rows.’
Forum Images = an optional image added in the app to each forum that appears next to the imageset
Contact icons = the icons in the menu that appears when clicking the contact bubble icon in the profile of a post.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 12, 2019

So talking it over as I mentioned on your other PR this would need to be Icon()

@cyberalien
Copy link
Copy Markdown
Contributor

cyberalien commented Mar 14, 2019

Don't add fill rule to css!

  1. Not every SVG has fill. Some rely on stroke. This rule will cause problems to icons that are using stroke.

  2. It won't work for external images anyway, so its useless. If you are embedding each icon as full SVG, it will work, but you are wasting a lot of bandwidth.

  3. Its better to just specify fill="currentColor" on shapes that use fill and stroke="currentColor" on shapes that use stroke.

As for attributes removal: title attribute must be removed because it is used as tooltip in some browsers. It overrides title from parent element, so for example if you have this:

<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%23" title="Link title!"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1.27em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1664 1312" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><title>SVG title!</title><path d="M1408 768v480q0 26-19 45t-45 19H960V928H704v384H320q-26 0-45-19t-19-45V768q0-1 .5-3t.5-3l575-474 575 474q1 2 1 6zm223-69l-62 74q-8 9-21 11h-3q-13 0-21-7L832 200 140 777q-12 8-24 7-13-2-21-11l-62-74q-8-10-7-23.5T37 654L756 55q32-26 76-26t76 26l244 204V64q0-14 9-23t23-9h192q14 0 23 9t9 23v408l219 182q10 8 11 21.5t-7 23.5z" fill="currentColor"/></svg></a>

tooltip will show "SVG title!" instead of "Link title!" as tooltip.

Best option for cleaning up is to run SVGO with all options to clear everything.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 14, 2019

@cyberalien

  • There is no bandwidth lost they are server generated embeded svgs.
  • We do not use parents unless links as wrapping an icon is very poor semantics and leads to bad selector performance which means using the icons toolip is prefered.
  • We are using svgo on our icons but the problem is svgo as far as I know is only available as a js library that requires node to run which does not work for custom icons.

@cyberalien
Copy link
Copy Markdown
Contributor

SVGO can be ran before uploading icons. There is also web interface for it: https://jakearchibald.github.io/svgomg/

As for bandwidth, I mean including icons on every page load. If icons are used for all decorations instead of fonts, that could be a lot of icons per page. Its one of reasons why glyph fonts became so popular - fonts use minimal markup, reducing page loading times compared to embedding SVG.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 14, 2019

🤔 calling 💩 on that fonts were introduced because of a lack of support of svg. Massive html pages load way faster than dynamic pages as it’s all cached and gzipped. There is a negative return actually. Let’s say the entire page was 2mb which is massive for an html page. That’s only on initial load subsequent loads would be like 10kb tops with gzip and cache. And there is no way it’s anywhere near that size unless you are trying to load every emoji on a page.

@cyberalien
Copy link
Copy Markdown
Contributor

Please read what I posted again. I said "one of reasons". Lack of support for SVG was definitely main reason though.

Lets do some math. FontAwesome 5 SVG size is between 300 for most basic icon and 1k for most complex icon. So 650b on average. Those are very simple icons. EmojiOne icons are mostly several kb in size up to 11kb. Those are shiny icons used for decorations, such as forum icons. 11kb is extreme icon, on average its about 2-3kb, so 2.5kb.

phpBB.com forum index is currently 66.5kb. Lets calculate replacing icons with SVG embedded in document:

  • Header: 3 feed icons + search placeholder
  • Navigation: 5 in quick links + 3-6 icons depending on permissions + 3 in user menu
  • Forums list: 19 big forum icons, 8 sub-forum icons, 16 last post icons, 6 minimise (and 6 hidden maximize) icons.
  • Footer: 5 icons

Big forum icons should be shiny, so that's similar to EmojiOne icons. Other icons are basic, so similar to FontAwesome 5 icons. That's on average 650b for basic icon, 2.5kb for forum icon. Let's assume minimum permissions, so in navigation only 3 icons.

Header: 4 * 0.65 = 2.6kb
Navigation: (4 + 5 + 3 + 3) * 0.65 = 9.75kb
Forums list: 19 * 2.5 + (8 + 16 + 12) * 0.65 = 70.9kb
Footer: 5 * 0.65 = 3.25kb

That's extra 86.5kb for page that's currently 66.5kb. Download size is more than doubled. Its added to every page load. In forum view there are even more icons. In posts there are lots of buttons in every post.

Today page load is very important. It affects SEO. For me that's a massive no for usage.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 15, 2019

🤔 Well prosilver is an irrelavent exp, will have to build some test I guess inthe new theme to figure everythingout.

@cyberalien
Copy link
Copy Markdown
Contributor

Cool. Please post results, it would be interesting to know how those calculations work for similar size forum with new layout. 🙂

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 16, 2019

done.

Tests run through Chrome Audit 'Sim Fast 3G, 4x CPU Throttle - Mobile'

Note:

  • we do not use the larger icons you speak of with the new theme. I will have to test that still. As all of our icons are very well optimized and monochrome even our imagesets.

I did convert over to use fully inline svgs, using the themes current icon pack

would be better once integrated into the app with actual assets instead of the mock ones I'm using which are all very un-performant. This is also with loading all css and js files via jsdeliver cdn directly from the repo as well.

Results:

New Theme - svg unoptimized (express static gzip)
index.html (11 forums): 123kb 1.6secs (99%)
forum.html (29 topics): 242kb 2.1secs (99%)

New Theme - iconify for non-custom icons (express static gzip)
index.html (11 forums): 98kb 1.6secs (99%)
forum.html (29 topics): 173kb 1.6secs (99%)

phpbb.com (local static tests loaded assets from live sites)
community index (19 forums): 79kb 6.3secs (56%) [express static gzip] 3.2secs (89%) - probably due to static rendering and gzip
community support forum (28 topics): 97kb 5.8secs (66%) [express static gzip] 3.5secs (87%) - probably due to static rendering and gzip

area51 (local static tests loaded assets from live sites)
index (13 forums): 40kb 3.9secs (83%) [express static gzip .com] 2.8secs (98%)
3.0 disscussion forum (21 topics): 68kb 3.9secs (83%) [express static gzip] 2.9secs (93%)

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 18, 2019

ok so finished and updated the above post with the results. sort of as I expected there is not really much tangible difference with static files. would really need to test with phpbb page renders. But the numbers are essentially vacuumed meaning that from a performance gain either way is under 2 sec loads with 10ms interactivity times. Compare this to current static versions of .com and area51 at 3+ secs vs live versions and you see a consistent extra sec for area51 and 2-3 secs for .com

I would not mind entertaining a 3.3 prosilver convert to iconify over font-awesome given these results.

I also put up some tests for that as well

prosilver integration: https://codepen.io/hanakin/pen/oVyvBp?editors=1100
icon list: https://codepen.io/hanakin/pen/GPZvev?editors=1100

@mrgoldy to do all this I ending up building a nunjucks filter for all the icon loading in current chameleon repo

environment.addFilter('icon', (icon, type, classlist, hidden = false)

and called it like so

{{ 'sort-ascending'|icon('inline', 'o-icon c-toolbar-action-icon t-toolbar-action-icon')|safe }}

seems to work fairly well but its all hardcoded

@cyberalien
Copy link
Copy Markdown
Contributor

That is not real forum test, it is missing what forums actually have - content. You didn't replace forum icon, which is biggest icon and you've made only 2 rows. Those are conditions of a dead forum. Real forums use 20 rows, not 2. That's 10 times more replication of big icons. Try replacing forum icon with svg, which will happen in new theme and add more rows to see conditions of actual forum.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 18, 2019

That was not the test that is a planning environment I put up.

The tests can be seen in branch 0.2.0 of chameleon on my account https://github.com/hanakin/chameleon/tree/0.2.0

@cyberalien
Copy link
Copy Markdown
Contributor

Oh, ok. Now it makes sense ☺️

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Mar 18, 2019

@mrgoldy check out this
https://stackoverflow.com/questions/52855116/twig-auto-import-macros-by-environment
Thks to @Nicofuma

Seems macros are still able to be used

@marc1706 marc1706 added this to the 4.0.0-a1 milestone Apr 11, 2019
@ghost
Copy link
Copy Markdown
Author

ghost commented Sep 30, 2019

I am not sure if this approach will work.. Will investigate some more.

Fatal error: Uncaught Twig\Error\RuntimeError: Accessing \Twig\Template attributes is forbidden

$web_path = $board_url ? generate_board_url() . '/' : $environment->get_web_root_path();
$style_path = $this->user->style['style_path'];

return "{$web_path}styles/{$style_path}/template/icons/png/{$icon}.png";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in theme folder

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, btw this will not handle 'style inheritance'. Is that correct behaviour?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the icon is not present in the user's style it will display the 'No image'.
It will not inherit from any parent style (eg. Chameleon).

@ghost
Copy link
Copy Markdown
Author

ghost commented Oct 21, 2019

I tried to rebase, resolve conflicts and force push.
But somehow managed to double my own commits, yet the master commit message are still in there as Travis is failing on them.
Any chance somebody could help me out here?

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Nov 10, 2019

pending the test looks good

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Nov 10, 2019

ill work on the icon rework for prosilver pr based off this tomorrow probably so we can merge both together.

@hanakin
Copy link
Copy Markdown
Member

hanakin commented Nov 12, 2019

@mrgoldy just noticed that you have all the templates in the template folder. This is not right the icons folder needs moved to all/templates/macros

Copy link
Copy Markdown
Member

@hanakin hanakin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticed some minor changes that need to be made to facilitate using different icons.

@ghost ghost requested a review from hanakin November 26, 2019 14:18
@ghost ghost requested a review from hanakin November 27, 2019 20:02
@@ -0,0 +1,4 @@
{% spaceless %}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think these are supposed to be in template not templates

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they should also be twig files not html files

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean .. #5545 (comment)

@mrgoldy just noticed that you have all the templates in the template folder. This is not right the icons folder needs moved to all/templates/macros

If you let me know where you want them I’ll adjust it. Along with the twig file extension.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it belongs in the current folder that exsists in the software https://github.com/phpbb/phpbb/tree/master/phpBB/styles/all/template

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

templates was a typo so just move the macros/iocns folders into the template folder

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll get there eventually :)

@marc1706 marc1706 removed the WIP 🚧 label Dec 1, 2019
@marc1706 marc1706 merged commit 8ee56d7 into phpbb:master Dec 1, 2019
@ghost ghost deleted the ticket/15538 branch December 1, 2019 11:49
* {'data-ajax': 'mark_forums'} results in ' data-ajax="mark_forums"'
* @return string
*/
public function icon(environment $environment, $type, $icon, $title = '', $hidden = false, $classes = '', array $attributes = [])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, currently you need to explicitly define icon type to render it. Can we add some auto mode to automatically detect icon type and render it then? Or even split such code into a function and then use it here instead of switch.

Copy link
Copy Markdown
Member

@hanakin hanakin Mar 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No that makes no sense and defeats the purpose. How would you even automatically detect an icon type? There are too different. I suppose you could make one a default? If it finds an svg use it unless defined

Copy link
Copy Markdown
Author

@ghost ghost Mar 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automatically detecting will also not return one definitive result, as a lot of the icon sets use the same names. So, that would only be possible indeed if some 'default' was configured. And then you can just use that variable in the template instead: {{ icon(DEFAULT_ICON, 'user') }}, which perhaps then can moved to the back-end indeed. Just a thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Chameleon 🦄 New Default Theme

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants