Users running a non-download version of Vanilla (pulled from github), on branch release/2019.016 or master from the last 2 weeks should upgrade to release/2019.017 or latest master for security reasons. Downloaded official open sources releases are not affected.
Please upgrade here. These earlier versions are no longer being updated and have security issues.

[Solved] Does anyone know how to install Masonry to work with your theme?

kirkpa31kirkpa31 ✭✭
edited November 2013 in Vanilla 2.0 - 2.8

I've been toying around with this for a few hours now and have made no progress.

Can someone possibly guide me as I try to install http://masonry.desandro.com/#install so that my columns are organized vertically, rather than horizontally?

utilizing vanilla v 2.0.18.8

«1

Comments

  • x00x00 MVP
    edited November 2013

    It depend what you mean, it doesn’t make for a more vertical layout it won't change the width or height, it orients things in the y axis that is all. They would all need to be direct descendent of the same containers, and you would need to to use appropriate selectors.

    You would need a custom, theme depending on what you are hoping to achieve.

    Basically you would need to find a basic unit of width, either fixed or percentage. Then make all widths multiples of that.

    I would say such a script has limited application, such as a magazine feed. if you know exactly what is going to be displayed then you don't really need it, it can be done purely in css. If you are getting random item can use it, but it still need the different with to be set as multiple of a a basic unit to get any kind of consistency.

    It is not really masonry like a dry wall, where you really have different sized pieces.

    grep is your friend.

    kirkpa31
  • kirkpa31kirkpa31 ✭✭
    edited November 2013

    The forum receives random items as the users input the content.

    I have created a themehooks.php file in my theme and within it I have put the following code as suggested by the http://masonry.desandro.com/#install instructions

    class ThemeHooks implements Gdn_IPlugin { public function Setup() { } public function OnDisable() { } public function Base_Render_Before($Sender) { if (($Sender->MasterView == 'default' || $Sender->MasterView == '')) { $Sender->AddJsFile('masonry.pkgd.min.js', 'themes/danca/js'); } } }

    I have added the masonry.pkgd.min.js file within a js folder I've created within my theme. Do I now need to call the themehooks.php file somehow using jQuery(document).ready(function($){ or another type of code? Or does my theme automatically pickup the themehooks.php file?

    Sorry for the vagueness - I'm trying to describe my process as best as possible.

  • x00x00 MVP
    edited November 2013

    Huh? read the documentation of masonry.

    You can't just load library and expect it somehow work, you have to apply to a container, and have child elements that are going to be your bricks. it doesn't know you want to do anything.

    Btw don't call you themekook theme hooks it has to be class.somethingthemehooks.php with a class name SomeThingThemeHooks. Best not use implements Gdn_IPlugin, use extends Gdn_Plugin.

    grep is your friend.

    kirkpa31UnderDog
  • Ok - here's what I've applied:

    to my default.master.tpl within my custom theme I've added the following:

    {literal} <script type="text/javascript"> src="/themes/danca/js/masonry.pkgd.min.js"></script> {/literal} {literal} <script type="text/javascript"> $(document).ready(function() { $('#content').masonry({ columnWidth: 320, itemSelector: '.item' }).imagesLoaded(function() { $('#content').masonry('reload'); }); }); </script> {/literal}

    at the bottom of the page, and this gives masonry the container of #content and the class of masonry which I reference in the following part of the default.master.tpl:

    <div id="Body"> <div id="Content" class="masonry"> {asset name="Content"} </div> <div id="Panel">{asset name="Panel"}</div> </div>

    I'm still playing around with this as I have not had success changing anything thus far...

  • For the life of me I can't figure this out - I've snooped around and coded my test website as follows:

    At the bottom of my default.master.tpl file:

    {literal} <script type="text/javascript" charset="utf-8" src="/themes/danca/js/masonry.pkgd.min.js"></script> <script type="text/javascript" charset="utf-8"> $(document).ready(function(){ $(".Item").masonry(); }); </script> {/literal}

    Within custom.css:

    li.Item { width: 300px; display: inline-block; }

    And the before and after is as follows:
    image

  • and what do you want?

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

    [Deleted User]
  • For it not to overlap as it does in the picture on the right - for it to accept the varying heights of the different items and position it vertically rather than horizontally

  • kirkpa31kirkpa31 ✭✭
    edited November 2013

    Wait a sec - if I switch the js to read $(".DataList").masonry(); instead of $(".Item").masonry(); it seems to be working better

    UnderDog
  • see how they have done it here:

    http://vanillaforums.org/bestof/everything

    There have a container .Tiles and items .Tile

    Note that .Tile are direct descendants of .Tiles

    var selector = '.Tile', $container = $('.Tiles');
    // var $items = $('.Tiles .Tile:not(.Wide)');
    // if ($items.length == 0) $items = $('.Tiles .Tile');
    // var width = $items.outerWidth() + 15;
    // $(selector).css({opacity: 0});
    $container.imagesLoaded(function() {
      $container.masonry({
          itemSelector: selector
          // columnWidth: width
       });
       $(selector, $container).removeClass('Invisible');
    }); 
    
    // After images are resized, we gotta recalculate the tile heights
    $(window).bind('ImagesResized', function() {
        $container.masonry({ itemSelector: selector });
    }); 
    

    Note they are waiting for the images to loaded an also resized. In order to tile it has to know the height as well as widths.

    grep is your friend.

    kirkpa31
  • kirkpa31kirkpa31 ✭✭
    edited November 2013

    edited**see comment below...CSS issue is what remains

    I've utilized this code within my default.master.tpl as referenced above:

    {literal} <script type="text/javascript" charset="utf-8" src="/themes/danca/js/masonry.pkgd.min.js"></script> <script type="text/javascript" charset="utf-8"> $(document).ready(function(){ $(".DataList").masonry(); }); </script> {/literal}

    and the CSS:
    .Discussions.index .Item { width: 307px; }

  • kirkpa31kirkpa31 ✭✭
    edited November 2013

    My test site currently looks as follows: http://idenitties.com/index.php?p=/

    Some content within each li.Item gets cut off but the masonry seems to be working slightly

    I'm hoping that all is left is a small CSS issue........something to keep the content from flowing outside of each item container

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    I am not too sure but based on what they say on the website http://masonry.desandro.com , there are several ways to implement it.

    If you want to simply call the js script you can place it in the head of the document.
    Just put the masonry.js file in your theme folder and add the link to it in the head of the doc. Or make a plugin like they suggest to add it to the head.

    You then need to wrap in a class whatever you want to be affected by this

    div id="DataList" class="js-masonry"

    the bellow might work to wrap the data list with the class js-masonry.

    $(document).ready(function() {
    $(this).find("DataList").not('.js-masonry').each(function(){
       $(this).addClass("js-masonry");
       js-masonry();
    }); 
    });

    You still need to add css to adjust for the sizes.

    The example they give in the website assumes you can write a new class or that you are writing this from scratch. Since you are working on something that is already made, you simply need to find the name of the container, it could be data list or it could be Body, or Content or Box , those are all containers.

    So you can experiment which one to affect with masonry . Remember the content and container are also ruled by what contains them.

    peregrinekirkpa31hgtonight
  • x00x00 MVP
    edited November 2013

    You didn't read what I said, in order to position vertical it need to know the height. It can't know the height if everything is not loaded. You need to wait or detect if the height changes.

    grep is your friend.

    peregrinekirkpa31hgtonight
  • also if you are using the same width you could cut out masonry altogether.

    In the themed view, you could loop through all the even post an put them in one div (column), all the odd

    The column psuedo code would be

    NumberOfColumns = 2;
    
    for (ColumnNumber = 1; ColumnNumber <= NumberOfColumns; ColumnNumber++){
     print '<div class="MyCollumn MyCollumn'.ColumnNumber.'">';
     foreach(Posts As PostIndex => Post){
        if(PostIndex-ColumnNumber+1 % NumberOfColumns == 0){
            print Post;
        }
     }
     print '</div>';
    }
    

    You could even do this with some JavaScript an not have to rely on absolute positioning of masonry.

    grep is your friend.

    kirkpa31R_J
  • x00x00 MVP
    edited November 2013

    What recommend is put the columns in DataList.That way you are less likely to have compatibility issue with other plugin that use the jquery selectors. You might have some issue with those that use direct descendancy rules. Though this is rarer.

    grep is your friend.

    kirkpa31
  • hgtonighthgtonight ∞ · New Moderator

    @x00 said:
    also if you are using the same width you could cut out masonry altogether.

    In the themed view, you could loop through all the even post an put them in one div (column), all the odd

    The column psuedo code would be

    > NumberOfColumns = 2;
    > 
    > for (ColumnNumber = 1; ColumnNumber <= NumberOfColumns; ColumnNumber++){
    >  print '<div class="MyCollumn MyCollumn'.ColumnNumber.'">';
    >  foreach(Posts As PostIndex => Post){
    >     if(PostIndex-ColumnNumber+1 % NumberOfColumns == 0){
    >         print Post;
    >     }
    >  }
    >  print '</div>';
    > }
    > 

    You could even do this with some JavaScript an not have to rely on absolute positioning of masonry.

    You can do this with straight CSS using :nth-child() selectors (which are well supported). You can use the following selectors to skip the JS all together.

    li {
      /* Base styles for all li items/first column */
    }
    
    li:nth-child(2n) {
       /* Styles for the 2 column */
    }
    
    li:nth-child(3n) {
     /* Styles for the third column */
    }
    

    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.

    kirkpa31R_J
  • x00x00 MVP
    edited November 2013

    You can do this with straight CSS using :nth-child() selectors (which are well supported). You can use the following selectors to skip the JS all together.

    not really it wouldn't position each item vertically very well.

    grep is your friend.

  • hgtonighthgtonight ∞ · New Moderator

    @x00 said:
    not really it wouldn't position each item vertically very well.

    Re-reading this thread, it seems I have fallen victim to thinking "I know what is being talked about and have a solution."

    My bad.

    Still, nth child selectors are awesome!

    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.

    peregrinekirkpa31UnderDog
  • kirkpa31kirkpa31 ✭✭
    edited November 2013

    Thank you guys for your support and advice on this topic -- @hgtonight @vrijvlinder @x00 i appreciate the help

    However - for whatever reason I've realized that the problem I have in CSS is not a problem in IE, it works perfecly in Internet Explorer but doesn't work in the other browsers (it appears as the screenshot I've attached above).

    If I was more adept at CSS/html I'm sure this is an easy answer involving one line of code I'd be able to fix myself - but I'm still new at all of this unfortunately.

Sign In or Register to comment.