HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Does addcssfilefunction work within the plugin setup?

The scenario is a bit complex so please bear with me.

The plugin configuration has a button that invokes an "editform" piece of code through the use of the mini controller:
The button uses the URL parameter:

Url('/plugin/pluginname/editfeedform/')

So far all seems fine and control is indeed given to:
public function Controller_editform($Sender)

That code, in turn displays a form which works fine and to my delight recognizes the CSS from the plugin configuration setup that was declared/added via:
$Sender->addCssFile('pluginname.css', 'plugins/pluginname');

That statement was added in the following hooks:

  • public function assetmodel_stylecss_handler($Sender)
  • public function Controller_editform($Sender)

As I mentioned, so far it all works just fine and I know from the visual effects as well as web inspector that the CSS is active.

I wanted to affect a small change - to have the form popup on top on the configuration screen so that when the admin clicks the button that routes to the mini controller "editform" code, the additional form is in a popup rather than replace the previous screen. All I did was to add "Popup" to the button class and as expected the form is displayed in a popup, and when the admin submits the form or closes it the underlying configuration screen is displayed.

The only problem is that the visual effects created by the CSS disappeared. I checked with the web inspector and indeed the CSS is not in effect.

I decided to try to add another addcss to the form itself in the view folder - it didn't help. I actually tried both ways:
$Sender->AddCssFile('pluginname.css', 'plugins/pluginname');
and just for fun:
$this->AddCssFile('pluginname.css', 'plugins/pluginname');

So clearly something in the popup process makes this AddCssFile function ineffective.

I welcome all suggestions. Apologies for not being able to share our intranet confidential code.

Best Answer

  • R_JR_J Admin
    Answer ✓

    If your question remains open, it is unanswered. No need to discuss that.

    But let me make some more attempts :wink:

    1. "Does addcssfilefunction work within the plugin setup"
      In the plugin setup? If you mean in "public function setup()", then the answer is "no".

    2. assetModel_styleCss_handler
      Stylesheets added with this method are attached to each and every page that Vanilla renders. I have not the equipment right now to test that but I'm 99.9% sure. So if you have a Vanilla popup window, the style sheet is loaded regardless if you click on the link to your plugins method.
      But if you simply echo to the screen instead of calling the render method, it might be that the head module isn't processed and therefore there wouldn't be any common stylesheets.

    3. pluginController_somePlugin_create
      If you add a stylesheet in this method, it would only be attached to the current page if you open /plugin/someplugin in a dedicated window. In a Vanilla popup, that style wouldn't be loaded.


    If attaching the css with assetModel_styleCss_handler doesn't work, please try base_render_before instead (you could also use e.g. dashboardController_render_before if your plugin is only opened from within the dashboard)


    It's a pity that you cannot share the code because of your approach :wink:

Answers

    1. The addCssFile() method adds your file to an array.
    2. All entries in that array are handled in the HeadModule which creates the html head section.
    3. In the html head tag, those entries of 1. are added as references to style sheet files
    4. When a popup is loaded, its content is loaded with ajax.
    5. Adding anything to the array of css files after the page is rendered, doesn't do anything, since the head section isn't changed. That would only be possible with JavaScript and addCssFile() works on PHP level

    You can include it in any request by using
    base_render_before or
    assetModel_styleCss_handler


    You can manually include the link to the css directly in your view:

    <style>
    <!--
      @import url(<?php echo asset('plugins/yourplugin/design/some.css') ?>);
    -->
    </style>
    

    Last but not least, you can inline it completely. I guess it is even considered best practice now for not too big chunks of css code.

  • Thanks @R_J, will try these options. Note however that I already use the assetModel_styleCss_handler to no avail... That's why I thought something is working different with the configuration controller...

  • rbrahmsonrbrahmson ✭✭✭
    edited August 2017

    I agree, I have:

    public function assetmodel_stylecss_handler($Sender) {
            $Sender->addCssFile('pluginname.css', 'plugins/pluginname');
    }
    

    And as I reported, that works elsewhere in my plugin.
    So I still face mystery and admit that without looking at my code no one can discover my mistake (or perhaps a Vanilla issue). That said, I'll try the other approaches you suggested and as is my habit, once the plugin works in our intranet I'll convert it for public use and perhaps the mystery would be solved. I am of course assuming that the other approaches would work;-)

    If you concur, I'll refrain from marking this as solved until I/we get to the bottom of it.

    As usual, thanks for your great support!

  • R_JR_J Admin
    Answer ✓

    If your question remains open, it is unanswered. No need to discuss that.

    But let me make some more attempts :wink:

    1. "Does addcssfilefunction work within the plugin setup"
      In the plugin setup? If you mean in "public function setup()", then the answer is "no".

    2. assetModel_styleCss_handler
      Stylesheets added with this method are attached to each and every page that Vanilla renders. I have not the equipment right now to test that but I'm 99.9% sure. So if you have a Vanilla popup window, the style sheet is loaded regardless if you click on the link to your plugins method.
      But if you simply echo to the screen instead of calling the render method, it might be that the head module isn't processed and therefore there wouldn't be any common stylesheets.

    3. pluginController_somePlugin_create
      If you add a stylesheet in this method, it would only be attached to the current page if you open /plugin/someplugin in a dedicated window. In a Vanilla popup, that style wouldn't be loaded.


    If attaching the css with assetModel_styleCss_handler doesn't work, please try base_render_before instead (you could also use e.g. dashboardController_render_before if your plugin is only opened from within the dashboard)


    It's a pity that you cannot share the code because of your approach :wink:

  • OK, mystery solved. The CSS was indeed loaded, but the specific CSS style definitions did not occur because they were not in the right level and while they worked without the popup, it appears that a popup adds to the specificity of the styles.

    So if you use the web inspector to point to an \<H1> heading text, the H1 definition outside a popup window shows:

    #Content h1, #Content h3 {
        text-shadow: 0 1px 0 #fff;
        color: #222;
        background: #dbf3fc;
        border-top: 1px solid #8bc1de;
        border-bottom: 1px solid #8bc1de;
        padding: 10px 20px;
        font-size: 14px;
        margin: 0;
    }
    

    But if you look at the same text under a popup you will see:

    div.Popup h1, div.Popup h2 {
        padding: 6px 9px 4px;
        border-radius: 4px 4px 0 0;
        font-size: 14px;
        font-weight: bold;
        margin: 0 0 5px 0;
        color: #f8fdff;
        background: url(images/dashboard-bg.png) top center repeat-x #014687;
        border-bottom: 1px solid #000;
        text-shadow: 0 1px 0 #000;
    }
    

    Obviously, it is not sufficient to add the Popup parameter to the button, I'll have to change my plugin style to match the above change.

  • Personally I find it quite messy when I look at html which has a lot of classnames, but that is how you should write your markup. If you use classnames, you avoid specificity. Styling should be done based on classnames, not on identifiers and not on elements

Sign In or Register to comment.