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

Accessing the body class

AccentAccent
edited August 2014 in Vanilla 2.0 - 2.8

Hello folks :)

Today I'm trying to add a class to the <body> (which usually has many classes already), by adding some PHP in a view.
Problem is, I'm not sure what 'some PHP' would be...

After some searching, I found this very interesting post:

Smarty

{$BodyClass}

PHP

$this->CssClass

but $this->CssClass doesn't seem to work for me. I tried echoing it in a view and nothing at all was displayed, even though the body class wasn't empty at all.
Also, would that be useful to _add _a class to the <body>, as well as just reading the existing classes?

Cheers.

edit: this discussion is kinda related too, but it's very old :P It would be good if a class like User-xxx was added to the <body> when viewing user xxx's profile...

Another bit of info: dashboard/views/modules/me.php has this bit of code at the beginning:

if ($this->CssClass)
   $CssClass .= ' '.$this->CssClass;

and then
echo '<div class="MeBox'.$CssClass.'">';

but I can't think of a single situation where the 'MeBox' has any other class besides that... so it would seem $this->CssClass doesn't work in that file either?

Tagged:
«1

Comments

  • peregrineperegrine MVP
    edited August 2014

    Can you state what you want to do ultimately.

    what element do you want to to append a class and what class do you want to add and under what conditions.

    and perhaps why you need to do it?

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • AccentAccent
    edited August 2014

    I would modify a page's CSS depending on the body class.
    Specifically, the page added by the Van2Shout plugin adds the Van2ShoutPage class to the body, so I'd like to change some CSS lines depending on whether that class is present or not.

    Also, I'd like to do what I previously suggested — adding User-xxx to the body class — and then apply CSS tweaks if the User-xxx class matches the names of the active user.

    edit: I just realised all the instances of < body > had been erased so my first post is pretty confusing, oops... whenever I said 'adding classes to the' or something similar I meant adding classes to the < body > tag.

  • peregrineperegrine MVP
    edited August 2014

    if you want to add the logged in user name to the <body> tag id (why make it a class.)

    edit the .tpl

    <body id="{$BodyID} {$User.Name} " class="{$BodyClass}">
    

    e.g. this is what you get.
    <body id="vanilla_discussions_index peregrine " class="Vanilla Discussions index Section-DiscussionList}">

    I would modify a page's CSS depending on the body class. Specifically, the page added by the Van2Shout plugin adds the Van2ShoutPage class to the body,

    couldn't use css to zero in on class and change it accordingly.

    the thing I have trouble with is your ultimate goal. if you gave exact example and screenshot of exactly what you want to do perhaps it could all be done in css itself without adding anything except to the .css files.

    Sometimes your questions aren't as detailed and you provide info, and some one gives you a solution, but because it is so general, it may be the wrong process in the first place.

    you could also add css via jQuery.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • I don't really know how I could be more specific... I can provide screenshots if you want, but I don't see how they'd help. I have a link to the Van2Shout page on my forums, and I want to take advantage of that fact that the Van2Shoutpage class is added to < body > when on that page, in order to alter the colour of the link. It's that easy.

    Same for the user link: I want the link to a user's profile in the MeBox to change colour when you're already on that page.
    This is the MeBox:

    When viewing my own profile, I want the link 'Accent' to be in a different colour. Your suggestion wouldn't work because it adds the class everywhere, even when you're not viewing the profile.

    This is how I got it to work right now:
    In views/modules/me.php, I added

    echo '<div class="MeBox'.$CssClass;
    if(strpos($_SERVER['REQUEST_URI'],'/'.$User->UserID.'/')!==false){
       echo ' Active';
    }
    echo '">';
    

    This adds the 'Active' class to the MeBox when the current URL matches the user's ID. Then, in custom.css:
    #Head .MeBox.Active a { color: #A3E3E2; }
    If the MeBox has the 'Active' class, the colour changes.

    However this tests against the URL and I'm sure there's a more efficient, elegant and flexible way to do it using the < body > class.

  • By the way one of the elements I would like to style is the 'Row' inside of Body. Basically the template goes like this:

    < body >
      < div id="Frame" >
        < div id="Head" >
        < div id="Body" >
          < div class="Row" >
        < div id="Foot" >
    

    So as you can see I don't have much choices. The only elements I can target in CSS are the body class, the id=Frame and the id=Body, and the last two don't seem to be intended for that purpose.

  • peregrineperegrine MVP
    edited August 2014

    I don't know what $User refers to in your case , but you would get different results

    http://vanillaforums.org/profile

    http://vanillaforums.org/profile/54734/Accent

    but if it works the way you want thats cool.

    By the way one of the elements I would like to style is the 'Row' inside of Body.

    to what under what conditions.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited August 2014

    You can add class to any element even if it already has a class using jquery

    http://api.jquery.com/addclass/

    You can add specific styles to pages using css. You can add specific styles to elements in specific pages.

    body.Profile tells the page then add the element

    body.Profile #Content or whatever you want to affect on that page only.

    body.Van2Shout .UserBox,body.Van2Shout .MeBox{
    background:red;
    }
    
  • @peregrine said:
    if you want to add the logged in user name to the <body> tag id (why make it a class.)

    There should only ever be one id.

    grep is your friend.

  • peregrineperegrine MVP
    edited August 2014

    I guess you are right. I thought a single tag appearing once could have multiple id's.

    I stand corrected

    http://stackoverflow.com/questions/192048/can-an-html-element-have-multiple-ids

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • The id attribute cannot contain a space, it must be absolutely unique, there is no standard that support the notion of multiple ids per element like class.

    http://www.sitepoint.com/web-foundations/id-html-attribute/

    since #Body may already be used in style and scripting, it is not a good idea to change it, just becuase some browser may support a non-standard behaviour doesn't mean you can expect consistent results.

    Class is exactly for this purpose. There is no rule that says you have to use a class more than once.

    grep is your friend.

  • @peregrine said:
    I don't know what $User refers to in your case , but you would get different results

    $User->UserID gives me the ID of the currently logged in user. What I do is test if that ID is present in the current URL, and if it is I add a specific class which I can then style using CSS. It would be easier if this was a base function of Vanilla, like it is with categories (the current category is added to the body class, for instance when you're browsing the 'Help' category the < body > will have class="..... Category-help"

    @vrijvlinder said:
    You can add class to any element even if it already has a class using jquery

    http://api.jquery.com/addclass/

    You can add specific styles to pages using css. You can add specific styles to elements in specific pages.

    body.Profile tells the page then add the element

    body.Profile #Content or whatever you want to affect on that page only.

    I know I can add classes via jQuery, but since I'm modifying php views and css files, I don't think that helps... does it? Can I add some script in a php file?
    Anyway; even if I could, I wouldn't know how to use addClass(), since I don't know what to target. As I said, $this->CssClass doesn't work most of the time (I'd like to understand why).

    And using body.Profile or something else is useful for CSS, actually it helped me solve one problem (thanks!) but it's not in PHP. I still don't know how to access the body class from a custom view. Doing that would allow me to perform comparisons with other values and to modify the class accordingly, or add dynamic values. (For instance, when viewing a user's profile, adding that user's name or role or whatever to the < body > could be useful for user- or role-specific css rules...)

  • hgtonighthgtonight ∞ · New Moderator
    edited August 2014

    @Accent $CssClass is a member of the Gdn_Controller class. Hook into the profile controller, do your logic, and modify the CssClass as necessary.

    public function ProfileController_Render_Before($Sender) {
      // Is the logged in user the same as the current profile user?
      if($Sender->User->UserID == Gdn::Session()->UserID) {
        $Sender->CssClass .= ' Active';
      }
    }
    

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    Can I add some script in a php file?

    Of course you can, that is where it would have to go.Or in a plugin.

    I don't see why you are obsessing over body, body is the page, body is the controller as hg said.

    I think you are making it complicated when it is really easy.

  • @vrijvlinder‌ maybe I am, but I really don't see how :( If I want to style the Row, as I said, the only elements I can target are the .Row itself, its direct parent #Body, the #Frame or the class in the < body >. Only the latter seems to be used for adding classes depending on what page is being viewed, so I assumed that was what I should be looking for. Look at the example I gave: let's say I am looking at a user's profile. If I want to style the .Row depending on that user's role — for instance, I could change the background to red if the user is and administrator — currently nothing allows me to do this. The way I'd assume you would have to do it is by tweaking a view in dashboard/views/profile so that it adds a class to the < body > tag depending on the user's role.

    Anyway! Yeah I guess I can do <script> $( "body" ).addClass( "whatever" ); </script> in a php file. :)

    @hgtonight‌ by 'hoot into the controller' do you mean, do something like this? $Controller = Gdn::Controller(); and then modify $Controller->CssClass; ?

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited August 2014

    If you want to style the .Row just use that and create a css rule for the elements.

    If you want the .Row in a specific page be different just add the body, #Body is not the same as body . body is the page and #Body is a container of asset #Content and asset #Panel

    All of those have other elements inside them.

    What Hg means is you can add the controller php inside the theme hooks or create a themehooks file or make a plugin.

    body is the page it is also called controller and it already has a class which is the name of the page.

    body.Profile = ProfileController which is the profile view.

    You can change the colors based on the roles by getting the class of that role. There are several role type plugins. Role Badges is a good one to modify for this purpose.

    It adds an icon to each role. Look at how it does that and then modify it to add background color.

    http://vanillaforums.org/addon/rolebadges-plugin

  • if you explained if you want to style a particular row or all rows. and where and which rows on which page.

    you would get specific help. still to general and we weave around with answers.

    its much easier to provide a solution absolute specificity, because we are not as close to the issue you are thinking about as you are.

    screenshot with arrowing pointing to what you would like to do.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited August 2014

    From what I gather they want to give specific background color on some element to specific roles when they are logged in.

    They want to be able to change anything they want according to the role's class. On this forum the class of the role is determined by the rank .

    I thought the rolebadges is a good one because it tests for the user. Then you just add more css to do the changes you want.

  • peregrineperegrine MVP
    edited August 2014

    you're right he did say role.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • peregrineperegrine MVP
    edited August 2014

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • AccentAccent
    edited August 2014

    The user role thing was just an example. I stay general because I want general help, I don't want anything that I could point an arrow to in a screenshot. I want to learn how to do things so I can be flexible and tweak the appearance of my forums in several ways, some of which I might not have thought of yet. My specific question was 'how do I read and/or write the class associated to the < body > html tag ?', and I explained why I thought this exact way was necessary... I'm not really interested in workarounds that would only lead me to ask another question in a week and make me end up with tons of additional lines and tiny adjustments for things that could have all been done in one way.

    But I think I got all the answers I needed. I'll look at the various links and try to figure it out. Thanks all!

Sign In or Register to comment.