HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Please upgrade here. These earlier versions are no longer being updated and have security issues.

Using inline SVG on MeModule

Hi!

I'm experimenting developing a theme for Vanilla (you can see my actual progress on GitHub, it still has my site-specific code that I should clean up by the time I will release it here in the addons directory), and i'm trying to use inline SVG when possible, to a better control of its styles via CSS, but I am actually having some problems altering the views, as me.php and such, to add an include or something like that to “embed” the contents of an SVG file as I can when I'm editing a Smarty file. Can someone help me?

In the case of MeModule specifically, I see where I need to edit it:

    echo '<span class="ToggleFlyout" rel="/profile/notificationspopin">';
    echo anchor(sprite('SpNotifications', 'Sprite Sprite16').wrap(t('Notifications'), 'em').$CNotifications, userUrl($User), 'MeButton FlyoutButton js-clear-notifications', ['title' => t('Notifications')]);
    echo sprite('SpFlyoutHandle', 'Arrow');
    echo '<div class="Flyout FlyoutMenu"></div></span>';

But I'm having problems to replace the sprite function to something that I can actually use to put an SVG icon instead.

Thanks in advance for your help!

Comments

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    it is never recommended to edit core files. But if you must, cloning the file into your theme is the best approach. You can look at my Glass theme or other themes of mine to see an example of how to put it into a theme.

    To replace sprites with images, it will take only editing CSS for your theme and not editing the me.php...

    A sprite is a sheet with several images on it, and css is used to determine the position or coordinates for that specific image on that sprite. If you are going to replace the sprite with images you must change the entire css code for the sprite sheet. And use ::before selector...to make sure it's in the right spot before the text of the link.

    https://www.w3schools.com/cssref/sel_before.asp

    arthrfrts
  • arthrfrtsarthrfrts New
    edited August 2017

    Thanks @vrijvlinder!

    I've actually copied the views to my theme, so I will not affect any core functionality that i can't rollback easily.

    So, I really don't want to use sprite images, but SVG itself in it. My problem is being able to “see” where to put the inline SVG on me.php, because it looks like — to me — that Vanilla functions handles everything that it's printed on screen via its wrap() and sprite, am I correct? I want to be able to do something like this:

    <span class="ToggleFlyout" rel= "/profile/notificationspopin">
        {svg file, maybe via a smarty tag? I don't know if its possible}
    </span>
    

    Do you know if something like this is possible to achieve? I would like to escalate the graphic icons on my forum to make everything in line with the redesign of my site.

    (And, also, I love to work with SVG, haha).

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited August 2017

    You can create an SVG sprite sheet.. the use of a sprite sheet is to minimize http requests and thus make the site load faster. When you add images instead of a sprite with the images, then you add multiple http requests to call each image instead of calling the same image and then telling the browser via css where the icon you want is located on that image.

    In vanilla design , Sp means sprite.

    echo anchor(sprite('SpNotifications', 'Sprite Sprite16').wrap(t('Notifications'), 'em').$CNotifications, userUrl($User), 'MeButton FlyoutButton js-clear-notifications', ['title' => t('Notifications')]);

    This line is telling the browser to use the sprite image called Sprite16 which IS the image with all the icons. These are Class Names, not links to image files. This one is specifically for notifications such as messages or comments or alerts. And it's dynamic. In other words it changes based on the amount notifications.

    I suggest you look at the Sprite sheet image, and create an svg version of it then adjust the CSS.

    here is an example of the sprite image found in applications/dashboard/design/images

    You can create your own version as svg and replace the original via css. Please look at the style,css for vanilla and find .MeBox stuff and .MeMenu stuff..

    Then copy those blocks of code into your theme and edit it there as you need. That is where the sprite images are called.

    arthrfrts
  • R_JR_J Ex-Fanboy Munich Moderator

    You are doing some things the wrong way.

    By altering the html structure of the default.master.tpl in such a massive way, users will get problems with numerous plugins. Those plugins rely on the default structure.

    I also like those descriptive html5 tags, but I'm not sure you should do it all that way.

    You have created a new footer and made the Vanilla footer a section, which is wrong.

    The documentation you look at might not be for the current version of Vanilla. The {mobile_logo} is only introduced in vanilla 2.4, as far as I know. The addon.json file isn't relevant to Vanilla 2.3

    I've forked your theme and made some changes. Those changes will break the layout because I reversed some of your decisions. Almost everything in the default master should be changed back to the default.

    vrijvlinder is completely correct when telling you that you should change the css definitions of the sprites. You can inline SVGs into CSS by encoding them.

    The way you include SVGs by now is not optimal. Read this article: https://css-tricks.com/svg-symbol-good-choice-icons/


    arthrfrts
  • Hello @R_J and @vrijvlinder

    Thanks for the help here!

    Knowing that my proccess to development is slow, I ended up planing to release the theme for Vanilla 2.4, that's why I'm using that addon.json file.

    I'll check your fork R_J, thank you very much for helping me out like this.

    I was actually using these two references by opting for using inline SVG (here and here) — because it makes part of the code, it don't create a new HTTP request for the user.

    But also, I didn't knew that changing the default.master.tpl would have major effects in the functionality of the system/addons. I'll have to see how I'll change my approach for that.

    Thanks for all the help, I'll study a bit more and return here if I have any doubts. :-)

    vrijvlinder
  • R_JR_J Ex-Fanboy Munich Moderator

    You should strive to be least invasive to write a good theme. This is the ranking I think should be used:

    1. Try CSS
    2. Try harder using CSS
    3. Ask if it could be done with CSS
    4. Use Vanillas events with a ThemeHooks file
    5. Override functions
    6. Override views

    You have asked how the view for the me module could be changed. You can override it. Bad idea.

    If only the sprite function is annoying you, you can override only that. Put that in your themehooks file, after the class definition:

    function sprite($name, $type = 'Sprite', $text = false) {
        include_once __DIR__.'design/svg/'.$name.'.svg';
        $sprite = '<svg class="'.$type.' '.$name.'"><use xlink:href="#sprite-'.$name.'" /></svg>';
        if ($text) {
            $sprite .= '<span class="sr-only">'.$text.'</span>';
        }
    
        return $sprite;
    }
    

    That should "inline" a svg file if it hasn't been loaded yet and afterwards create a SVG element instead of the span element which is created right now. But hold on, this is only for the sake of completeness! I don't favor that solution.

    I'm not sure why you favor to inline the SVGs. But if you want to, you can also do that by writing the CSS to the page while it is created. Use the AfterBody event to simply echo a <style>some css rules here</style> part. That way you have all the needed CSS without an extra request (if it is that what you are afraid of)

    I still would say simply replacing the Sprite classes is the best way to go.


    arthrfrtshgtonight
  • Yeah, I understand your points here and I'm considering using sprites now to not be as intrusive as I'm already being on the Vanilla ecosystem.

    The main reason I prefer inlining SVGs (even with the method you presented my, by referencing via <symbol>) is because I could manipulate its properties (like fill color, stroke width, style and color, etc.) via CSS. But I think it's a feature that don't pay for such an extensive amount of changes I would make on the already consolidated structure of the Vanilla addons.

    Again, thanks for all the help! I'm studying using SVG sprites via CSS now to make a better theme!

    hgtonightvrijvlinder
Sign In or Register to comment.