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.

Any to give users their own selection of homepage layout?

DoyceTDoyceT ✭✭✭
edited June 2014 in Vanilla 2.0 - 2.8

I'm running 2.1 stable, and the default theme.

Basically the pipe-dream version of what I'm looking for is the ability to give each user the ability to make the selections that the admin can make on the Dashboard/Homepage screen, where we decide whether the site will default to showing Discussions or Categories, and Modern/Table/Mixed layouts.

BUT, barring that, I'd love if I could somehow provide working urls for each option. Something like this:

  • domainname.com/forum/discussions
  • domainname.com/forum/discussions/modern
  • domainname.com/forum/discussions/table
  • domainname.com/forum/category
  • domainname.com/forum/category/modern
  • domainname.com/forum/category/table
  • domainname.com/forum/category/mixed

... which would at least let them make bookmarks to the view they prefer, regardless of what the official setup is.

I suspect this is probably a horrible amount of work - so I guess my question is, how horrible?

Note: I don't really want to change any of the layouts I have - I'm fine with each - I just want a way to generate them (meaning the modern/table/mixed layouts) even when they aren't selected. If each user had their own defaults in this regard, that would just be icing on the cake.

My situation: I'm currently using a layout everyone likes, except for a couple visually- and/or developmentally-impaired users, whose needs push us to use a less-well-liked layout. I'd love to give those users what they need, while still providing the option of the more detailed layout for everyone who wants it.

Tagged:
«134

Comments

  • peregrineperegrine MVP
    edited June 2014

    a very simple solution: (that may work)

    if you had just one option for everyone who is not visually- and/or developmentally-impaired

    • and another for for everyone who is visually- and/or developmentally-impaired

    then you could install two versions of vanilla - each pointing to the same database with different them config options in their config.php

    domainname.com/forumx
    domainname.com/forumy

    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 have a better idea, a toggle that will select the css file from a variety of styles.

    The toggle would remove the custom.css and add another one based on the available choices.

    For this idea to work , the styles must be compatible with the master used at the time. Unless you can also switch master template by toggle , by the same process of removing a file for another or creating a theme with a variety of views.

    I have managed to do the switching of custom.css. with my own themes. It is only a matter of changing the css file being used at the time but not making it permanent just for the user. The theme or css file does not get stored as the main theme in config but as a value in the user preferences .

    You can make a plugin that uses RemoveCssFile then AddCss file by form options with given possible themes installed.

  • try this and put the impaired vs non-impaired users in different roles

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

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

  • Rather than change the theme (which requires maintaining two separate themes) or change the CSS (which won't change the underlying markup), I would store the preference in the User Meta table and temporarily modify the layout config item.

    The layout is determined via the 'Vanilla.Discussions.Layout' and 'Vanilla.Categories.Layout' config items. Plug in to the session start and change them accordingly:

    public function UserModel_AfterGetSession_Handler($Sender) {
      $User = $Sender->EventArguments['User'];
    
      // override the default controller route temporarily
      $Controller = $this->GetUserMeta($User->UserID, 'DefaultController', 'discussions', TRUE);
      Gdn::Router()->SetRoute('DefaultController', $Controller, 'Internal', FALSE);
    
      // override the default layout temporarily
      $DiscussionsLayout = $this->GetUserMeta($User->UserID, 'DiscussionsLayout', 'modern');
      $CategoriesLayout = $this->GetUserMeta($User->UserID, 'CategoriesLayout', 'modern');
    
      SaveToConfig('Vanilla.Discussions.Layout', $DiscussionsLayout, array('Save' => FALSE));
      SaveToConfig('Vanilla.Categories.Layout', $CategoriesLayout, array('Save' => FALSE));
    }
    

    Then you need to have an easy way for user's to pick their preferences. We will plug into the edit profile page, and add a new link:

    public function ProfileController_EditMyAccountAfter_Handler($Sender) {
      $ControllerOptions = array(
        'discussions' => 'Discussion List',
        'categories' => 'Category List'
      );
    
      $LayoutOptions = array(
        'modern' => T('Modern non-table-based layout'),
        'table' => T('Classic table layout used by traditional forums')
      );
    
      echo '<li class="Homepage">';
      echo $Sender->Form->Label('Homepage View', 'DefaultController');
      echo $Sender->Form->DropDown('DefaultController', $ControllerOptions);
      echo $Sender->Form->Label('Discussions View', 'DiscussionsLayout');
      echo $Sender->Form->DropDown('DiscussionsLayout', $LayoutOptions);
      $LayoutOptions['mixed'] = T('All categories listed with a selection of 5 recent discussions under each');
      echo $Sender->Form->Label('Categories View', 'CategoriesLayout');
      echo $Sender->Form->DropDown('CategoriesLayout', $LayoutOptions);
      echo '</li>';
    }
    

    Then we need to hook in and actually save this data:

    public function UserModel_AfterSave_Handler($Sender) {
      $FormValues = $Sender->EventArguments['FormPostValues'];
      $UserID = val('UserID', $FormValues, 0);
    
      // Require valid user ID
      if(!is_numeric($UserID) || $UserID <= 0) {
        return;
      }
    
      $DefaultController = val('DefaultController', $FormValues, FALSE);
      if($DefaultController) {
        $this->SetUserMeta($UserID, 'DefaultController', $DefaultController);
      }
    
      $DiscussionsLayout = val('DiscussionsLayout', $FormValues, FALSE);
      if($DiscussionsLayout) {
        $this->SetUserMeta($UserID, 'DiscussionsLayout', $DiscussionsLayout);
      }
    
      $CategoriesLayout = val('CategoriesLayout', $FormValues, FALSE);
      if($CategoriesLayout) {
        $this->SetUserMeta($UserID, 'CateogoriesLayout', $CategoriesLayout);
      }
    }
    

    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.

  • DoyceTDoyceT ✭✭✭

    This looks very achievable, and exactly what I'm looking for, but - if I'm brutally honest - all my followup questions are so ridiculously basic ("where am I putting this?"), that I start to wonder if I should be futzing with it in the first place. Doesn't feel fair to ask for a step by step, and unfortunately that's pretty much what I need.

    To steer the the conversation away from my own shortcomings as an admin, do you see this sort of thing working as a plugin, or is that thinking about it entirely wrong? Maybe that's the first question I should have asked.

  • This is designed to be a plugin.

    Learn how to write a basic one here: http://vanillawiki.homebrewforums.net/index.php/Hello_World_Plugin

    Asking questions when you get stuck is the best way to learn!

    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.

  • DoyceTDoyceT ✭✭✭

    Awesome.

    Okay, so having already done that "WhereDidMyDefaultCategoryPermissionsGo" plugin, I was ready to take this on and unleash my wicked cut-and-paste ability.

    <?php if (!defined('APPLICATION')) exit(); ?>
    
    <?php
    $PluginInfo['CustomHomepage'] = array(
       'Name' => 'Custom Homepage',
       'Description' => 'This plugin allows users to set their own choices for which homepage they will see when they connect to the forum.',
       'Version' => '0.1',
       'Author' => "Doyce Testerman",
       'AuthorEmail' => 'doyce.testerman@gmail.com',
       'AuthorUrl' => 'http://nila.edu'
    );
    ?>
    
    <?php
    class CustomHomepagePlugin extends Gdn_Plugin {
    
    public function UserModel_AfterGetSession_Handler($Sender) {
        $User = $Sender->EventArguments['User'];
        // override the default controller route temporarily
        $Controller = $this->GetUserMeta($User->UserID, 'DefaultController', 'discussions', TRUE);
        Gdn::Router()->SetRoute('DefaultController', $Controller, 'Internal', FALSE);
        // override the default layout temporarily
        $DiscussionsLayout = $this->GetUserMeta($User->UserID, 'DiscussionsLayout', 'modern');
        $CategoriesLayout = $this->GetUserMeta($User->UserID, 'CategoriesLayout', 'modern');
        SaveToConfig('Vanilla.Discussions.Layout', $DiscussionsLayout, array('Save' => FALSE));
        SaveToConfig('Vanilla.Categories.Layout', $CategoriesLayout, array('Save' => FALSE));
        }
    
    public function ProfileController_EditMyAccountAfter_Handler($Sender) {
        $ControllerOptions = array(
        'discussions' => 'Discussion List',
        'categories' => 'Category List'
        );
        $LayoutOptions = array(
        'modern' => T('Modern non-table-based layout'),
        'table' => T('Classic table layout used by traditional forums')
        );
        echo '<li class="Homepage">';
        echo $Sender->Form->Label('Homepage View', 'DefaultController');
        echo $Sender->Form->DropDown('DefaultController', $ControllerOptions);
        echo $Sender->Form->Label('Discussions View', 'DiscussionsLayout');
        echo $Sender->Form->DropDown('DiscussionsLayout', $LayoutOptions);
        $LayoutOptions['mixed'] = T('All categories listed with a selection of 5 recent discussions under each');
        echo $Sender->Form->Label('Categories View', 'CategoriesLayout');
        echo $Sender->Form->DropDown('CategoriesLayout', $LayoutOptions);
        echo '</li>';
        }
    
    public function UserModel_AfterSave_Handler($Sender) {
        $FormValues = $Sender->EventArguments['FormPostValues'];
        $UserID = val('UserID', $FormValues, 0);
        // Require valid user ID
        if(!is_numeric($UserID) || $UserID <= 0) {
        return;
        }
        $DefaultController = val('DefaultController', $FormValues, FALSE);
        if($DefaultController) {
        $this->SetUserMeta($UserID, 'DefaultController', $DefaultController);
        }
        $DiscussionsLayout = val('DiscussionsLayout', $FormValues, FALSE);
        if($DiscussionsLayout) {
        $this->SetUserMeta($UserID, 'DiscussionsLayout', $DiscussionsLayout);
        }
        $CategoriesLayout = val('CategoriesLayout', $FormValues, FALSE);
        if($CategoriesLayout) {
        $this->SetUserMeta($UserID, 'CateogoriesLayout', $CategoriesLayout);
        }
        }
    }
    ?>
    

    Result: Seems to work! Kinda!

    I get a plugin in my Plugins list, which I can (and do) enable, and when I then go to the forum and edit my profile, I get this:

    This

    And I can change those values and save the profile...

    but then nothing actually happens - despite the 'universal' settings being set otherwise, everyone's now seeing the layout for whatever the first value in the options is (modern) for Discussion and Category layouts, though each user can change whether the default front page is Category or Discussions.

    So... what did I miss? I suspect I need to add some fields to the database, so this information is actually saving somewhere, but that might just be crazy talk.

  • as an aside. its a good idea NOT to add the bottom line closing ?> , it can kill your rss feeds. and you don't need to close it. Just leave out the closing ?>

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

  • DoyceTDoyceT ✭✭✭

    Interesting. Thanks for the tip!

    That reminds me that my RSS is being generated, but since it's a private forum, my RSS readers don't seem to be able to actually see any of it. I'm fine with that, but I thought it was interesting.

  • it happens mostly in views where you are outputting html, but its a good habit everywhere, (kind of counterintuitive).

    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 June 2014

    So... what did I miss? I suspect I need to add some fields to the database, so this information is actually saving somewhere, but that might just be crazy talk.

    it is actually saved already in your UserMeta Table take a look with phpmyadmin and you will see info matched with UserID.

    should happen in the UserModel after Save routine when you Setusermeta ,

    now you've got to use the stored information upon login, I leave that to the master explainer hgtonight.

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

  • DoyceTDoyceT ✭✭✭

    @peregrine said:
    now you've got to use the stored information upon login

    Ah ha! Yeah, that's what I'm missing.

  • perhaps do something with

    public function Base_AfterSignIn_Handler($Sender) {

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

  • Ah!

    I made a poor assumption. I defaulted all user's that have not specified their preferences to the discussions controller with the modern layout.

    We need to change the UserModel_AfterGetSession_Handler() method to retrieve the defaults from the current configuration:

    public function UserModel_AfterGetSession_Handler($Sender) {
      $User = $Sender->EventArguments['User'];
      // override the default controller route temporarily if it has been set
      $Controller = $this->GetUserMeta($User->UserID, 'DefaultController', FALSE, TRUE);
      if($Controller) {
        Gdn::Router()->SetRoute('DefaultController', $Controller, 'Internal', FALSE);
      }
    
      // override the default layout temporarily
      $DiscussionsLayout = $this->GetUserMeta($User->UserID, 'DiscussionsLayout', C('Vanilla.Discussions.Layout', 'modern'));
      $CategoriesLayout = $this->GetUserMeta($User->UserID, 'CategoriesLayout', C('Vanilla.Categories.Layout', 'modern'));
      SaveToConfig('Vanilla.Discussions.Layout', $DiscussionsLayout, array('Save' => FALSE));
      SaveToConfig('Vanilla.Categories.Layout', $CategoriesLayout, array('Save' => FALSE));
    }
    

    Now we only change the route if it has been specified, and default the layout to the configured dashboard option.

    Sorry about that mixup!

    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.

  • peregrineperegrine MVP
    edited June 2014

    I think you should disregard my answer: cross posted with hgtonight's answer.

    not sure about 3rd argument. you have to see how it is returned.

    look in applications/dashboard/models/class.usermodel.php

    UserModel::GetMeta($this->User->UserID, Plugin.CustomHomepage.%', 'Preferences');

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

  • you need to change this as well

    $this->SetUserMeta($UserID, 'CateogoriesLayout', $CategoriesLayout);

    to

    $this->SetUserMeta($UserID, 'CategoriesLayout', $CategoriesLayout);

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

  • DoyceTDoyceT ✭✭✭
    edited June 2014

    Damn, I can almost follow everything.

    I've made the change hg posted. There doesn't seem to be any effect, however.

    Right now:

    • Plugin does override the default homepage settings in the dashboard.
    • Everyone sees modern layouts for both Category and Discussions, regardless.
    • Users can successfully set whether their default is Discussions or Categories.
    • No one can change the views from Modern.

    So it feels really close, and also feels like peregrine's 2nd most recent reply (applications/dashboard/models/class.usermodel.php) is part of the solution. I'm just too novice to see how to put the pieces together. :persevere:

  • I think it still needs more work though as you say. but hgtonight is the master controller on this. I'm just running interference :)

    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 June 2014

    try this ...

    class CustomHomepagePlugin extends Gdn_Plugin {
        public function UserModel_AfterGetSession_Handler($Sender) {
        $User = $Sender->EventArguments['User'];
        // override the default controller route temporarily if it has been set
        $Controller = $this->GetUserMeta($User->UserID, 'DefaultController', FALSE, TRUE);
        if($Controller) {
        Gdn::Router()->SetRoute('DefaultController', $Controller, 'Internal', FALSE);
        }
    
    
        // override the default layout temporarily
        $DiscussionsLayout = $this->GetUserMeta($User->UserID, 'DiscussionsLayout', C('Vanilla.Discussions.Layout', 'modern'));
        $CategoriesLayout =  $this->GetUserMeta($User->UserID, 'CategoriesLayout', C('Vanilla.Categories.Layout', 'modern'));
    
        $DiscussionsLayout = array_values($DiscussionsLayout);
        $CategoriesLayout  = array_values($CategoriesLayout);
    
        SaveToConfig('Vanilla.Discussions.Layout',GetValue(0,$DiscussionsLayout) , array('Save' => FALSE));
        SaveToConfig('Vanilla.Categories.Layout', GetValue(0, $CategoriesLayout), array('Save' => FALSE));
        }
    

    or this might be better.

        class CustomHomepagePlugin extends Gdn_Plugin {
            public function UserModel_AfterGetSession_Handler($Sender) {
            $User = $Sender->EventArguments['User'];
            // override the default controller route temporarily if it has been set
            $Controller = $this->GetUserMeta($User->UserID, 'DefaultController', FALSE, TRUE);
            if($Controller) {
            Gdn::Router()->SetRoute('DefaultController', $Controller, 'Internal', FALSE);
            }
         // override the default layout temporarily
            if($DiscussionsLayout =$this->GetUserMeta($User->UserID, 'DiscussionsLayout')) {
                 $DiscussionsLayout = array_values($DiscussionsLayout);
                 SaveToConfig('Vanilla.Discussions.Layout',GetValue(0,$DiscussionsLayout) , array('Save' => FALSE));
             }
    
            if($CategoriesLayout  =$this->GetUserMeta($User->UserID, 'CategoriesLayout')) {
                  $CategoriesLayout  = array_values($CategoriesLayout);
                  SaveToConfig('Vanilla.Categories.Layout', GetValue(0, $CategoriesLayout), array('Save' => FALSE));
            }
    
         }
    

    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 June 2014

    @DoyceT

    both the above worked for me.

    just make sure you change this as well..

    .http://vanillaforums.org/discussion/comment/210215/#Comment_210215

    learned something new about in-memory configs today from hg today :)

    cool design hgtonight - thinking outside the box.

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

Sign In or Register to comment.