Placement of Widgets

Topics: Customizing Orchard
Nov 13, 2014 at 9:40 PM
I was hoping someone could help me understand the placement of widgets within Orchard. I understand there are widget zones defined by the current theme that allow placement of widgets within Orchard, but is there a way to alter the placement of widgets within their zones? I have a flex slider widget from the Tekno.FlexSlider module that I want to place within the Content zone; the same zone as the page's title and body parts. I would like the flex slider to be or at least appear within the bodypart of the page. This way I can have the flex slider wrapped within the text of my page's body part. Is this possible? Thank you.
Nov 14, 2014 at 4:32 AM
Edited Nov 14, 2014 at 4:33 AM
When you say within the body part, do you mean somewhere between one paragraph and the other? If so, that is not possible, unless you implement a token provider that lets you insert this token inside of a body part, and outputs the slider.
Alternatively, a better approach might be to implement the slider as an element and construct your page using the new Layouts feature. This way you have complete control over what appears where within the content zone.
Nov 14, 2014 at 3:20 PM
Edited Nov 14, 2014 at 4:49 PM
Yeah, that is what I meant. Sorry for my ignorance but what are elements as opposed to widgets and how would I go about creating one? Is the layouts feature part of Orchard 1.8.1 and are there any tutorials on how to use it? Thank you.

Edit: I was playing with the files for the Orchard.Widgets module and the Tekno.FlexSlider module but any changes made weren't reflected in the site? Is this because it is a widget? It seems like you should be able to specify where in the zone you would like the widget to appear instead of always placing it at the bottom of the zone. The title part gets placed in Header:5 and the body part gets placed in Content:5 I would like my FlexSlider widget to be placed between these two, but I need to be able to do this without affecting the placement of other FlexSlider widgets. It would be nice if there were a setting when creating a widget for where in the zone you would like the widget placed instead of just a setting for which zone you want it placed in.

Edit: Another thing I don't understand is why the title part for the page content item gets rendered underneath the Navigation zone when its file specifies to place it in the Header zone which comes before the Navigation zone. It seems like in this case the title for the page would be placed way above the body part but it appears right above the body part of the page instead of way at the top of the page like its file suggests.

Edit: Sorry, there is an option for specifying where to place the widget within the zone but it doesn't appear to work properly, at least not with FlexSlider widgets. I tried specifying to place the FlexSlider widget at both position 0 and position 1 within the content zone but it still will not place the widget above the body part of the page content item which is supposedly positioned at Content:5 which meanst the widget should appear above it for values less than 5.

Edit: The placement within the zone works with regards to other widgets but it doesn't work with content items that are being displayed on the page. You can't place the widget above the content item unless you place it in a zone that is above the zone the content item resides in. I don't understand why the page content item's parts are specified to show in different locations such as Header:5 and Content:5 but when the page content item is displayed everything is wrapped up and displayed in the Content zone instead of the zones that are set up in the files.
Nov 15, 2014 at 3:24 AM
No worries, Layouts and Elements are a new feature yet to be released. There is no documentation nor tutorials as of yet, but there will be.

As you correctly observed, you can't control the position of widgets before other shapes within the same zone. This is because those other shapes are actually child shapes of a Content shape (not to be confused with the Content zone). You can't cut up this Content shape, but what you can do is override the Content shape template (found in Orchard.Core/Contents/Views) and render some global zones, for example:

      @*The following line will render the Header local zone called Header, which is a shape on the Content shape (which is Model)*@

   @*The following line will render the BeforeLocalContent global zone, which is a shape on the root Layout shape*@
   @*The following line will render the Content local zone called Content, which is a shape on the Content shape (which is Model)*@

   @*The following line will render the AfterLocalContent global zone, which is a shape on the root Layout shape*@

You would have to update your theme manifest file to include the BeforeLocalContent and AfterLocalContent zones so they become available on the Widgets screen.
I really don't like this solution, but wanted to show you this to try and get a better understanding of where zones live: the root shape of all is Layout, which contains the so-called global zones, such as Navigation, BeforeContent, AsideFirst, Content, etc.
When rendering a content item, a Content shape is created. This is not the same as the Content global zone - it is added to this global Content zone however.
The Content shape itself is a ZoneHolding shape, which means that its shape properties such as Header, Content and Footer are shapes that are zones as well, but local to the Content shape. The driver system uses to place the shapes created by drivers into these local zones of the Content shape. The Content shape itself is always added to the Content "global" zone on the Layout shape.

When you use the yet to be released 1.9 version, you'll be able to control the position of elements, so you could for example first place a Paragraph element, then a Slider element (to be created by you and uploaded to the gallery for use by us ;)), and then some more paragraphs as you see fit.
As you can imagine, this will simplify this kind of scenarios.
Nov 15, 2014 at 7:01 PM
Edited Nov 15, 2014 at 7:52 PM
Okay that makes sense, thank you. Would another way around this for the time being be to change the FlexSlider from a widget into a content part that can be added to a page content item? Would there be a way to then make it so the user could specify where within the page content item they want the FlexSlider to appear?

Thank you.

Edit: Would it be possible to alter the code for the FlexSlider to become a plugin for TinyMce instead of an Orchard widget or would that take a lot of rewriting code? Like some way to insert the view into the page with TinyMce instead of as a widget. You would have to somehow get TinyMce to know the parts and views for the FlexSlider exist and then insert the view directly into the body of the page. That way you could keep using Orchard to construct the sliders and their options and then TinyMce will just grab the view and stick it in the body instead of a widget sticking the view into a zone.
Nov 15, 2014 at 8:49 PM
You're right, I forgot to mention the option of simply attaching the FlexSliderPart to your content type. That way you can use to control the shape's position. It wouldn't enable you to place the slider in between paragraphs, but it would allow you to put it in between the various content item shapes.

Turning it into a TinyMce plugin is yet another option, but I suspect this would require some significant coding on your end. I like the idea though. Should you decide to go this route, maybe you could consider implementing it for Layout Elements, so that it would not only work for FlexSlider, but for any element.
Nov 19, 2014 at 6:40 PM
Edited Nov 19, 2014 at 6:47 PM
Okay, so I can get TinyMce to insert the code for a FlexSlider into the page but I'm having a hard time including the FlexSlider.js and FlexSlider.css files in a manner that will allow them to be used by the front end. Currently the FlexSlider doesn't work because its js and css aren't being included correctly. I tried to include them in the theme but that didn't seem to work. Any ideas in how to include the js and css files?

Edit: The best approach from a usability standpoint would be for TinyMce to include the styles and scripts so the user doesn't have to manually include them in their theme or something, but I've no idea how to do this.
Nov 20, 2014 at 5:14 AM
Your best bet to get this to work is to include the required JS and CSS from your theme. You mention that didn't seem to work, but that is most likely because you made a mistake somewhere, which I am sure you can correct.
Nov 20, 2014 at 4:21 PM
Edited Nov 20, 2014 at 4:47 PM
okay, thank you. The last problem is getting the initialization to work. For FlexSliders you have to run an initialization function on your FlexSlider to get it working.

"<script type='text/javascript' charset='utf-8'>$(window).load(function() {$('.flexslider').flexslider();});</script>"

I could just put this in my theme as well and it should initialize all FlexSliders but I need to be able to specifiy which FlexSlider to initialize in order to add customizable features such as speed and direction.

I've set up TinyMce to open a new windowManager when the slider button is clicked this window opens my slidercreator.htm file which has some buttons for adding slides by selecting a picture from the gallery, inserting a slider with the selected images, and closing the window. When the user clicks to insert a slider the html for a FlexSlider is inserted into the editor as well as the script for initializing it. But once you publish the page and go look at it, the script appears to not have run and the css is off because all that shows up is an offwhite line where the slider should be. I've taken some liberties in testing that may be the problem. I have another FlexSlider on the page that is set up as a widget which means the FlexSlider.cs and FlexSlider.js files are already included in the page, but they are included at the footer which may explain why they are not working for the FlexSlider that was inserted via TinyMce.

Edit: I placed the flexslider.css and flexslider.js files in the theme TheThemeMachine for testing and the css is working now but I always get a 404 error for the .js file I've double checked the path for the file which is: http://localhost:5546/Themes/TheThemeMachine/scripts/jquery.flexslider-min.js and it exists there but it can't find it for some reason.
Nov 20, 2014 at 5:15 PM
I was able to get it working by forcing the theme to include jquery and flexslider javascript files at the head of the document and inserting the flexslider html and initialization script into the body of the TinyMce editor. This works, but it seems like bad practice to me to have to include jquery and flexslider.js at the head and in every page instead of just those that have a flexslider. It also seems weird to inject the initialization script into the body of TinyMce. Is there a better way of accomplishing this?