Overriding Widget View in Orchard - orchardcms

I setup a custom content definition, query and projection inside Orchard (1.8) and just about everything with it works great, including overriding the display view on the projection page's URL. The only issue I'm running into is when I put that same projection in a widget, I can't seem to figure out how to override the view for it. The automatically generated HTML is this:
<p class="text-field"><span class="name">Name:</span> <span class="value">/** Title from content item **/</span></p>
<p>more</p>
<p>asdfasdfasdrerfwerqaq324f421 more</p>
<p class="date-time-field date-time-field-date">
<span class="name">Date:</span>
<span class="value">/** Date from content item **/ </span>
</p>
I've tried using the Shape tracer to create an alternate view, but even when I only have #Display(Model.Content) in the new view, it still puts all of that extra stuff in it which is more than I need to show on this view. The shape tracer says the active template is my new one with only that value in it, so I'm not sure where all the extra HTML is coming from here (though it does show on the HTML tab of the Shape tracer).
How can I override the view for this widget?

If the extra HTML is only appearing when you post the projection as a widget it is probably due to wrapper tags added through code or through the widget wrapper template. Try either of these methods:
Check Widget.Wrapper.cshtml to see if that view template contain the extra HTML. I don't remember if this shape shows up in the shape tracer, it might show up under the wrappers section.
You can also try the trick below - this can remove unwanted markup in some cases, I use it for the menu navigation widget. It removes any wrappers that were added through code. Make your widget template look like this:
#Display(Model.Content)
#{
Model.Metadata.Wrappers.Clear();
}

Related

Orchard CMS ContentShapes - can I add a wrapper?

I have a resource in OrchardCMS that I'm displaying through a number of smaller shapes (so that I can adjust the layout order in placement.info).
In the Driver I am returning these parts through the use of returning a Combined(ContentShape(...), ContentShape(...), ContentShape(...)) etc
However I would like the HTML of each of the smaller shapes to appear within an HTML wrapper (such as a div or article or suchlike)
How do I go about doing this?
Thanks
I understand what you are trying to achieve but it isn't really a feasible scenario. A wrapper is applied to a shape and combined returns several shapes. As you say, each shape has an entry in the placement.info file, so you could easily have these shapes within different content zones or zones spread around your page, where a wrapper would just not work. Make sense?
The answer is probably that you need to create an override for the content view of the content type you are displaying and add the stuff you want to put in your wrapper in there. e.g. if your content type is called MyType and the displayed type was detail, your view would be called Content-MyType.Detail.cshtml.
Do you mean an Orchard wrapper (whole new cshtml file), or just a HTML element?
In the latter case you can do in your part view:
#{
var tag = Tag(Model, "article");
}
#tag.StartElement
stuff
#tag.EndElement
If you want to wrap a (common) wrapper around your elements, you can do the following in your placement.info:
<Place Parts_MyPart="Content:1;Wrapper=MyWrapper" />
<Place Parts_MyOtherPart="Content:2;Wrapper=MyWrapper" />
And create a MyWrapper.cshtml:
<article>
#Display(Model.Child)
</article>

Add Body Part to Custom Widget - Placement

This time I'm struggling with my custom widget for Orchard.
It's a simple content part with two fields:
- Background Color
- Size
I want to be able to add HTML content to this widget; so I added the Body Part. This part must be displayed within my widget. The result should be something like this:
<div class="size-small bg-color-red"> BODY PART HTML CONTENT </div>
But unfortunately, the Body Part is always displayed before or after my widget.
<Placement>
<Place Parts_ContentTile="Content"/>
<Place Parts_ContentTile_Edit="Content:7.5"/>
</Placement>
Not so nice 'solution':
A way to resolve this is to remove the body part and replace it with a simple text field. This text field is rendered at the desired position. But then the TinyMCE Editor is not available.
Update after comment from Ivan:
I tried to change both (Content Type and Content Part (separate)) but unfortunately, both times, the TextField content is displayed after the widget. Should that be fixed in the Placement.info?
Another option is to add a String field to my Widget Model. But then it is not possible to show the TinyMCE editor. Am I right?
So I've got the feeling that my expectations about widgets, content parts and placements are incorrect. Hopefully somebody here can point me in the right direction.
When using TextField, you can use TinyMCE by specifying HTML flavor in the settings of the field.
To do that you can go to Content → (Content Types or Content Parts depending on which you are trying to change) → Select your ContentType or ContentPart → Expand the definition of the TextField you're using → Select HTML from the drop down menu next to Flavor → Click on Save button.
This post on SO from Mark Z was really helpfull to me!
I added a String property to my Model and added a new Database Migration:
public int UpdateFrom3()
{
// Adds a new Content column
SchemaBuilder.AlterTable("ContentTileRecord", table => table.AddColumn("Content", DbType.String));
return 4;
}
After that I added the field to the Editor Part View:
#Script.Require("OrchardTinyMce")
<div class="editor-label">
#Html.LabelFor(model => model.Content)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Content, new { #class = "html tinymce" })
</div>
The Content Property is now displayed as a TextArea. Because of the classes 'html and tinymce' the TinyMCE editor is instantiated. (Don't forget the Script.Require call)
Because of the fact that the Content property contains HTML, it is required to use the #Html.Raw helper to display the value of this property.
#Html.Raw(Model.Content)

Override part template Orchard

I starting with orchard. I want to override MenuWidgetPart to render as i want. I've created Parts.MenuWidget-MenuWidget.cshtml into Views folder of current theme. But i do not know, how to i can get list menu from Model. Please look my code below:
<nav>
<ul>
#foreach(var m in listMenu){
<li>#m.Text</li>
}
</ul>
</nav>
How to i can get listMenu from Model ?
Templates for Menu and MenuItem are Menu.cshtml and MenuItem.cshtml. You can start by copying those files from /Core/Shapes/Views/ directory to your theme directory. You can modify them as you wish afterwards.
This will, actually modify all your menus on the site. If you want it to be specifically for your widget (Parts.MenuWidget-MenuWidget.cshtml) you can start by copying the contents from Menu.cshtml to your widget template and continue with modifications from there.
EDIT:
To iterate over items you can use the following syntax:
#foreach (var item in Model.Menu.Items){
#Display(item)
}

Display content part in Orchard

I would like to be able to specify exactly where a ContentPart is rendered in a view.
For example, in my Content.Summary.cshtml I want to wrap my title and first image from the gallery (I'm using ZenGallery) in an anchor tag. I thought I would be able to do it like this but the gallery template is not rendered.
<a href="#Url.ItemDisplayUrl((IContent)Model)">
<h2>#Model.ContentItem.TitlePart.Title</h2>
#Display(Model.ContentItem.ZenGalleryPart)
</a>
But if I do the following then the gallery template (ZenGallery.Summary.cshtml) is shown along with all other parts.
#Display(Model.Content)
I understand that the recommended way to do this is probably using Placement.info, is that right? But this way makes more sense to me and would allow for more fine grain control of the end markup. How could I achieve the markup I'm looking for?
This should give you a pretty good start on doing precisely what you want: http://weblogs.asp.net/bleroy/archive/2011/07/31/so-you-don-t-want-to-use-placement-info.aspx

Is it possible to format a NumberField in a page layout?

I'm developing a SharePoint publishing site and setting up its content types and page layouts. I need to display the value for a Year field with type Number. The markup currently is:
<SharePointWebControls:NumberField FieldName="Year" runat="server" id="Year" />
The problem with the default behaviour is that it shows each number with a comma, e.g. "2,009" instead of "2009". Is there a way I can set some sort of String.Format syntax on the field to make it display correctly?
I tried creating a new rendering template which looks like this:
<SharePoint:RenderingTemplate ID="YearNumberField" runat="server">
<Template>
<SharePoint:FormField ID="TextField" runat="server"/>
</Template>
</SharePoint:RenderingTemplate>
... but there doesn't appear to be any 'Format' property on the FormField object.
Thanks for any help.
Update:
I tried wrapping the SharePoint:FormField tag inside SharePoint:FormattedString. Unfortunately the field was not formatted, same results as this question.
The issue is that the rendering template must use FormField. This always renders the value in the format: 1,989 . To resolve this the rendered text needs to be trapped and altered to get the desired output. Here are two approaches to resolving this:
1. Write a custom control inherited from NumberField
The RenderFieldForDisplay and RenderFieldForInput methods can be overridden to provide the desired output. Additional properties can be added to the control to describe additional behaviour.
Pros: No changes to rendering templates required.
2. Write a custom control for use in the rendering template
A control that (for example) uses regular expressions to alter text can wrap around the FormField control.
<SharePoint:RenderingTemplate ID="YearField" runat="server">
<Template>
<RX:RegexManipulatorControl runat="server"
Mode="Replace"
Expression=","
Replacement="">
<SharePoint:FormField runat="server"/>
</RX:RegexManipulatorControl>
</Template>
</SharePoint:RenderingTemplate>
Pros: Generic solution can be used for any type of field.
from Just Another SharePoint Blog
Open the list view in SharePoint
Designer.
Right click on the data view web part.
(the list)
Select Convert to XSLT Data View
Click on the number field you would
like to format
A > will appear showing Data Field,
Format As
Click on the link below Format As -
Number formatting options
Under Options deselect Use 1000
separator
Click OK
Save your changes and hit F12 to
preview

Resources