Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0] Created a HTMLHelper to render an icon #30792

Closed
wants to merge 44 commits into from

Conversation

hans2103
Copy link
Contributor

@hans2103 hans2103 commented Sep 28, 2020

Pull Request for Issue # .

Summary of Changes

This PR will make it possible to use a HTMLHelper to place an icon.
Just like there is a HTMLHelper to place an anchor and an image.

Testing Instructions

  • Joomla 4 Administrator
  • See the quick icons on the dashboard
  • Apply patch
  • See the quick icons on the dashboard ... it is still the same. Only to be implemented by the HTMLHelper now

Actual result BEFORE applying this Pull Request

placing an icon would be:

<span class="icon-joomla" aria-hidden="true"></span>
<span class="icon-joomla icon-white" aria-hidden="true"></span>
<span class="icon-joomla icon-white" aria-hidden="true" tabindex="0" title="Hello World"></span>
icon-joomla
<span class="fab fa-joomla" aria-hidden="true"></span>

Expected result AFTER applying this Pull Request

echo HTMLHelper::_('icons.icon', 'joomla', TEXT::_('HELLO_WORLD'));

Documentation Changes Required

most likely...

@hans2103 hans2103 changed the title Created a HTMLHelper to render an icon [4.0] Created a HTMLHelper to render an icon Sep 28, 2020
@SharkyKZ
Copy link
Contributor

This looks pointless and counter-intuitive.

hans2103 and others added 2 commits September 28, 2020 13:31
Co-authored-by: Richard Fath <richard67@users.noreply.github.com>
Co-authored-by: Richard Fath <richard67@users.noreply.github.com>
@HLeithner
Copy link
Member

Can you please remove $iconPrefix = 'icon-', $iconSuffix = null, $html = true, $elem = 'span',

  • We shoudn't support custom prefixes (make no sense)
  • Don't know why the suffix should be an extra parameter, also php should not be used for styling
  • html parameter makes no sense if you supply the complete icon "class" (without icon-)
  • $elem should not be provided by php because it's a design/template decision, if I override the icon function because I want to use svg I have a problem if someone provides an unexpected markup.
  • Children, don't know if this is a good idea, this would limit us by changing the iconmark to another format (which maybe can't support child elements)

@dgrammatiko
Copy link
Contributor

dgrammatiko commented Sep 28, 2020

@hans2103 If you want to introduce a helper to render an icon then you should probably render the icon as an SVG image instead of the outdated, inefficient and mostly inaccessible font Icon. BTW there was a PR doing exactly that some time ago: #28351

EDIT: Just reading the code and quite frankly I don't like what I see, sorry.

A cleaner approach (more like the typo3 or my code in the #28351) would be:

function(

$icon = "",      // $icon the icon name
$as = "svg",   // $as either svg (default) or font
$params = [  //  $params array of parameters eg
  'provider'   => 'fontawesome-free',
  'group'      => 'solid',
  'classes'    => ['fa', 'demo-class'],
  'attributes' => [
   'data-foo' => 'bar',
   'id'       => 'foobar'
  ]
]) {}
  • Since you're introducing an API for icons it seems that you're missing the most important aspect: decouple the assets. Right now template are dictating the behaviour (eg loading the font always) which -A. it's not template'e responsibility -B. the API should load any assets required. Eg. If my landing page doesn't have any icons why does the template should enforce the loading of unneeded css and fonts? (the template has no clue what each layout is using thus the only safe place to add assets in in the layouts NOT IN the template as these are globally loaded [monolithic approach, really outdated])

PS. Don't get me wrong here, I'm trying to suggest improvements to your code not to shame your work.

@HLeithner
Copy link
Member

@dgrammatiko if I'm write there is no way to use svg and icon fonts at the same time (override each other with css) at least I didn't find a html markup for such a case.

Using SVG sprites doesn't seem to work or only works if the svg is inline? Loading 30 svg separated doesn't seems to be the best way.

Your PR uses inline SVG sprites right and build the svg dynamically right? doesn't sound like a smart way

@dgrammatiko
Copy link
Contributor

Loading 30 svg separated doesn't seems to be the best way.

There aren't extra Http requests, th icons are inland in the html output, read the code/comments there

@HLeithner
Copy link
Member

Loading 30 svg separated doesn't seems to be the best way.

There aren't extra Http requests, th icons are inland in the html output, read the code/comments there

That's what I mean with 'inline SVG sprites' you create a svg on the fly and reference them in another svg at the icon position.

That doesn't sound efficient at least you disable any caching

@dgrammatiko
Copy link
Contributor

dgrammatiko commented Sep 28, 2020

That doesn't sound efficient at least you disable any caching

Caching is useless if your rendering of the initial page is extremely slow but sequential loads are faster (generally speaking, for some sites this might be tolerated, eg all content is behind a login)

Anyways there are ways to do the API so you can have Icon fonts and SVG, a great example is Typo3:
https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Icon/Index.html

doesn't sound like a smart way

@HLeithner sure it's not very smart, thus everybody (GitHub, YouTube, Facebook, etc) using this approach because they are also dumb. Joomla using the outdated icon fonts is right here and the only clever... 🤷‍♂️

@hans2103
Copy link
Contributor Author

Can you please remove $iconPrefix = 'icon-', $iconSuffix = null, $html = true, $elem = 'span',

  • We shoudn't support custom prefixes (make no sense)

We are working towards action named icons. An icon should be named save. When using this HTMLHelper it needs the icon_prefix/iconPrefix. Akeeba adds a ToolbarTitleIcon with name = akeeba. The iconPrefix is needed.

  • Don't know why the suffix should be an extra parameter, also php should not be used for styling

Currently Joomla core has multiple implementations of extra parameters in the icon. Think about icon-spin, to let the icon-spinner icon animate and rotate. Think about icon-fw to give an icon a specific width.

  • html parameter makes no sense if you supply the complete icon "class" (without icon-)

I agree and will remove the $html

  • $elem should not be provided by php because it's a design/template decision, if I override the icon function because I want to use svg I have a problem if someone provides an unexpected markup.

I agree and will remove the $elem

  • Children, don't know if this is a good idea, this would limit us by changing the iconmark to another format (which maybe can't support child elements)

I agree and will remove the $children

@hans2103
Copy link
Contributor Author

hans2103 commented Oct 1, 2020

@dgrammatiko I prefer using svg icons too... but first things first... a HTMLHelper for the icon. Adjusting the HTMLHelper to use svg is a next step I think. The impact of this PR would be too big I think.

Looking at a11y perspective an icon should always have a text. This can be a styled label or this can be a piece of text hidden from sighted people. With the last example I mean <span class="sr-only"></span>.
With commit a3d7b64 I have added the ability to add both icon and hidden text. Example implementation can be seen on 3babe70

@brianteeman
Copy link
Contributor

Looking at a11y perspective an icon should always have a text.

Like all blanket statements this is not correct

@hans2103
Copy link
Contributor Author

hans2103 commented Oct 1, 2020

Looking at a11y perspective an icon should always have a text.

Like all blanket statements this is not correct

thank you for your comment. Can you rewrite it so it is correct?

@dgrammatiko
Copy link
Contributor

dgrammatiko commented Oct 1, 2020

but first things first... a HTMLHelper for the icon

Again IF you're about to introduce an new API endpoint make sure that

Looking at a11y perspective an icon should always have a text.

This is a remedy. A class that hides the icon for anyone using an screen reader is a hack, svg icons don't need that and thus it's the de facto best practice for 5 or so years...

@hans2103
Copy link
Contributor Author

hans2103 commented Oct 1, 2020

This is a remedy. A class that hides the icon for anyone using an screen reader is a hack, svg icons don't need that and thus it's the de facto best practice for 5 or so years...

Take a look at the code please. I'm not hiding the icon, I am adding a <span class="sr-only">some text here that is not visible for sighted people, but is for screenreaders</span>
Even svg icons need text. How often do I see that svg icons are optimized so much that the title element with a descriptive text has been removed from the svg. In our current Joomla code we accompany an icon with a sr-only span with the descriptive text.

The arguments could be expanded if needed (eg icon($name = 'default', $options = [])

@dgrammatiko am I not doing that with $attribs = []?

Properly deal with the static files, icons (either svg or font) are not responsibility of the template, should be handled here in this API

can you give me an example how this should be done properly?

Move the code in https://github.com/joomla/joomla-cms/blob/4.0-dev/libraries/src/HTML/Helpers/Icons.php or create a new file icon.php

that sounds good... I was not aware of the existence of this file.

@dgrammatiko
Copy link
Contributor

@dgrammatiko am I not doing that with $attribs = []?

Read again my first comment, you should not spread a bunch of arguments in the function, use just 2: the icon name and then the params (an array with anything associated to with the icon you want to present). I already provided a link that explains very nicely why this is the right way...

can you give me an example how this should be done properly?

Will do

@HLeithner
Copy link
Member

I already provided a link that explains very nicely why this is the right way...

Maybe I missed it why is this the right why? for every static code analyser it's a pain because it can not check if a parameter is valid or not and since PHP 8.0 has named parameters this shouldn't be a problem at all. But maybe I'm wrong.

And why is it not the job of the template if the icon is a svg or an icon? I mean it's easy to override this icon function with your own and replace all icon fonts with svg icons (not possible with only the template you need a plugin). But I think it's not the decision of the component if the icon is a svg icon or a font.

@dgrammatiko
Copy link
Contributor

Maybe I missed it why is this the right why?

Argue with Uncle Bob (his book clean code is a must read for every dev): https://www.matheus.ro/2018/01/29/clean-code-avoid-many-arguments-functions/

And why is it not the job of the template if the icon is a svg or an icon?

Simply because the icons are mostly existing in layouts and layouts should take care of their dependencies (proper modularisation). Template is essentially the orchestrator, echoing the layouts in the right order, it doesn't need to have knowledge of the specifics of every or any layout. If it does it means it is enforcing things to layouts, which is not good (a very good example is #23742 )

@HLeithner
Copy link
Member

Argue with Uncle Bob (his book clean code is a must read for every dev): https://www.matheus.ro/2018/01/29/clean-code-avoid-many-arguments-functions/

So my conclusion from this text is, that I did it right ;-) I requested to reduce the parameter count (see $html and so on). But it seems you missed the important part, if i'm not wrong he uses Java as an example in refactoring "name, phone, street..." to an Object. Your suggest was to add it to an assoc array that's not the same and error prone. The Object he created is "Address" which likely knows exactly at compile time which parameters can be added. We can do the same by creating an class "iconObject" which hold the needed information so the runtime or a static code analyzer can print an error if you have a typo. Which is not so easy to do with an assoc array.

And I think for this utility functions is a bigger pain to have an object instead of 2 additional parameters (which I would remove anyway, still don't understand why we have a suffix)

Simply because the icons are mostly existing in layouts and layouts should take care of their dependencies (proper modularisation). Template is essentially the orchestrator, echoing the layouts in the right order, it doesn't need to have knowledge of the specifics of every or any layout. If it does it means it is enforcing things to layouts, which is not good (a very good example is #23742 )

so what's the suggestion on this? I have the "idea" or some thoughts that if this PR is finished and the icon pr is finished (and if it will be merged) we should be possible to simply switch all (at least core icons) simple to svgs (which a variant of your last pr).

@Quy
Copy link
Contributor

Quy commented Oct 28, 2020

I have tested this item ✅ successfully on b1660ab


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/30792.

1 similar comment
@N6REJ
Copy link
Contributor

N6REJ commented Oct 30, 2020

I have tested this item ✅ successfully on b1660ab


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/30792.

@Quy
Copy link
Contributor

Quy commented Oct 31, 2020

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/30792.

@joomla-cms-bot joomla-cms-bot added the RTC This Pull Request is Ready To Commit label Oct 31, 2020
@dgrammatiko
Copy link
Contributor

@Quy please remove Rtc from this there are a number of issues I pointed in my comments that are not addressed yet

@hans2103
Copy link
Contributor Author

@dgrammatiko please describe them again.
Or can they be fixed in a new PR?

@dgrammatiko
Copy link
Contributor

It's really bad idea to merge a half done API so it cannot be done in a new pr, needs to be fixed here. Read my comment about handling the related assets and also the api needs to be able to either echo font icon or svg icon html

@hans2103
Copy link
Contributor Author

@dgrammatiko
do you mean this part of the comment copied from #30792 (comment)

  • Since you're introducing an API for icons it seems that you're missing the most important aspect: decouple the assets. Right now template are dictating the behaviour (eg loading the font always) which -A. it's not template'e responsibility -B. the API should load any assets required. Eg. If my landing page doesn't have any icons why does the template should enforce the loading of unneeded css and fonts? (the template has no clue what each layout is using thus the only safe place to add assets in in the layouts NOT IN the template as these are globally loaded [monolithic approach, really outdated])

@Quy Quy removed the RTC This Pull Request is Ready To Commit label Oct 31, 2020
@hans2103
Copy link
Contributor Author

hans2103 commented Nov 26, 2020

Adjusted icons.icon to get triggered by type = svg
Added the FontAwesome SVG icons

HELP WANTED
How to call for the FontAwesome SVG icons?
Should a reference to /media/vendor/fortawesome-free/svgs/regular be made within the function icon? => I hope not... it is not up to this function to know where the svg icons are.
Or should this be done via a JLayout where an easy override can be chosen for another library? => makes sense to me.

@hans2103 hans2103 marked this pull request as draft November 26, 2020 10:33
build/build-modules-js/settings.json Outdated Show resolved Hide resolved
*
* @since __DEPLOY_VERSION__
*/
public static function icon(string $icon, string $srOnly = '', string $type = '', array $attribs = []): string
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the srOnly or move it as a param to attribute. Actually please bring the logic from my PR https://github.com/joomla/joomla-cms/pull/28351/files#diff-1f3d4b0ff411d275d94c1538ef487ef75d4450d772ad2cf712b5796467917f6dR214-R246
That allows any type of attributes to be attached to the inserted svg...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

applied your changes... some of them.
I don't want to use svg-sprite at this moment... out of scope for this change.

But.. I need some help to get provide the correct path to the function icons.svg

suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't want to use svg-sprite at this moment... out of scope for this change.

You're missing the point my friend, if you're not controlling the output (eg current implementation) you're essentially allowing broken HTML to be applied in any page. Let me explain: the svg helper will echo each fragment every time you call it, meaning it can inflate the output but worse than that it could echo multiple svgs with the same id which is invalid HTML. Unfortunately if you want to do SVGs correctly you need somehow to take control of the fragments you're inserting or the API you're introducing is prone to undesired side effects

@SharkyKZ
Copy link
Contributor

This PR makes even less sense now.

@hans2103
Copy link
Contributor Author

@SharkyKZ

This PR makes even less sense now.

could you explain me why?

@hans2103
Copy link
Contributor Author

closing this for now... will create a new PR when time feels good, wind is blowing from the right direction, sun is shining and such. :-)

@hans2103 hans2103 closed this May 11, 2021
@hans2103 hans2103 deleted the htmlhelper-for-an-icon branch September 10, 2021 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Language Change This is for Translators
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet