Difference between SPFile and PublishingPage class - sharepoint

What are the difference between SPFile class and PublishingPage Class? I am trying to manipulate a SharePoint Page and I see that both SPFile and PublishingPage classes can be used and the only difference I see if PublishingPage is used for aspx file and SpFile can be used for anyfiles in a SharePoint site. I also see that there are few extra properties like ContactEmail etc in PublishingPage.
Is there anything important I am missing here?

You pretty much answered your own question. the PublishingPage class is used to represent pages authored by end-users in a publishing site. It has information about the page layout used, the content type upon which the page layout was based, when the page should be published, and so on. The SPFile object is used to represent any file in a library.

Related

SharePoint WebPart zoneId

I am using SharePoint online.
I want to use this CSOM code to add a WebPart to a page:
SP.File oFile = _web.GetFileByUrl(SiteUrl + "/SitePages/" + pageName);
oFile.CheckOut();
LimitedWebPartManager limitedWebPartManager = oFile.GetLimitedWebPartManager(PersonalizationScope.Shared);
var importedWebPart = limitedWebPartManager.ImportWebPart(webPartSchemaXml);
var webPart = limitedWebPartManager.AddWebPart(importedWebPart.WebPart, zoneid, zoneIndex);
oFile.Update();
await SiteCtx.ExecuteQueryAsync();
oFile.CheckIn(String.Empty, CheckinType.MinorCheckIn);
The problem is how to assign correct values to the zoneid string variable,
which is the name of the Web Part zone to which to add the Web Part.
When I run this code nothing happens!
(it doesn't add the WebPart to the page and I am suspecting it is related to the wrong zoneId).
I have read various post, ranging from accessing the code behind of the .aspx page trying to find the WebPartZone, accessing the WebPartManager class (which should list the ZoneId's but I don't know how to get it, since that I am using the LimitedWebPartManager class).
I have tried various values for zoneId, but at the moment none of them work:
Zone 1 (just a guess!)
Zone 2 (i see it in the right tab when manually editing the webpart through Edit page)
Body (with this the code worked some days ago! but now it doesn't anymore)
Header
Left
Bottom
What is the proper method of findind zoneId's?
EDIT
The page is the homepage, I have read somewhere that it is a wiki page so maybe it has different ZoneId's.
ZoneIDs might be different depending on the page layout, but usually out-of-the-box SharePoint layouts use the following ID's for webpart zones:
TitleBar
Header
LeftColumn
MiddleColumn
RightColumn
Footer
Make sure that you invoke the update() method on your file object and executeQueryAsync() method on your context after importing the webpart - the latter function especially is responsible for sending the request to server and applying your changes.
Here's a nice article about adding webparts to pages programatically: How to programmatically add a ClientSide Web Part to a SharePoint page

How to retrieve NavItem in liferay freemarker base theme in liferay 7?

i had used below code but it is not working.
<#assign navItem = objectUtil("com.liferay.portal.kernel.theme.NavItem") />
it give below error.
Caused by: freemarker.core._TemplateModelException: Java constructor "com.liferay.portal.kernel.theme.NavItem.com.liferay.portal.kernel.theme.NavItem(javax.servlet.http.HttpServletRequest, com.liferay.portal.kernel.model.Layout, Map)" takes 3 arguments, but 0 was given.__----_FTL stack trace ("~" means nesting-related)
I had also used below code it is also not working.
<#assign navItemClass = portal.getClass().forName("com.liferay.portal.kernel.theme.NavItem")>
Basically i want to retrieve NavItem object in theme and want to use it.
The scripting context gets a large part of its variables injected by TemplateContextHelper. In there you can find several relevant values for the underlying problem that you describe in the comment to your question:
layout is representing the current page (layout is the technical name)
layouts is a collection of all pages
the same values can be retrieved through themeDisplay
navItems is a collection of all navItems, but you'll have to find the one relating to the current page yourself. It might be easier to go through layout
Browsing through the TemplateContextHelper sourcecode might give you the hints you need.

Is there documentation for the #Model type in Orchard?

I'm customizing my father-in-law's Orchard site and trying to create a .cshtml file to control the display of a Containable content type, but I'm having a bugger of a time finding the data in the #Model field. Is there any documentation on it anywhere?
So far I've found #Model.Slug and #Model.Title. What I'd really like is access to the custom fields on the Content Type.
The Model object is of a dynamic type so it's properties are dynamically added depending on what modules are being used.
If you are using the new 1.1.30 version of Orchard you can use the new Shape Tracing tool which is part of the Deisgner Tools module which can be installed through the modules gallery. This will add a panel to the bottom of your website page that will allow you to see and navigate through the Model object.

Programmatically enumerating Web Part Zones of a Publishing Page Layout

I have a situation where a class I have is passed a PublishingPage instance and I want to enumerate any and all web part zones that are used in the Layout Page for this page.
This is proving tough.
PublishingPage has a property called Layout, which is of type PageLayout. This is different from PublishingLayoutPage which inherits (eventually) to Page which has the Zones property. This PageLayout type does not have any reference to the normal ASP.NET Page type which has the Zones property I need.
I can get an SPListItem and a SPFile from the PublishingPage.Layout property, and get the contents of the page layout in raw text form, but this can't be parsed with XmlReader as it's not valid XML (has <% tags which are invalid).
I can get an SPWeb from PublishingPage.ListItem.Web, and this can get me an SPLimitedWebPartManager, where I can get a collection of LimitedWebParts (which has Zone information) - but this won't help because at this stage of my code I have no web parts.
I'm pretty stuck, it looks like the Publishing Infrastructure is quite detached from both ASP.NET and SharePoint.
UPDATE:
I can use the SPLimitedWebPartManager to add a dummy web part (like a new ContentEditorWebPart) to a web part zone (I have the names of the zones that are used), but when I save this out and check the page back in (and get a new SPLWPM), I can get the WebParts back but the Zone property is null (the ZoneID property is populated and correct).
The posts from Wayne Fan on this thread seem to cover what you're trying to do. Hope this helps.

Sharepoint web parts Rendering html and controls

I have a webpart that displays HTML output within the RenderWebPart method and also creates controls within the CreateChildControls both methods are declared as overridden in the webpart.
My question is how to I control the order of the display of the controls and html output?
At the moment I call EnsureChildControls() within the RenderWebPart mthod to ensure all controls within the CreateChildControls are created and then the html out is rendered.
What if I wanted to display a control on the page then html output and then another control below in that order?
I would recommend moving all of your static HTML out of the Render function and into the CreateChildControls function. If you need to, you can add regular old HTML using Labels, WebControls, or even better... LiteralControls. Then you can just add them to your Controls collection.
Example:
WebControl container = new WebControl(System.Web.UI.HtmlTextWriterTag.Div);
StringBuilder sb = new StringBuilder();
sb.Append("<ul>");
foreach (Node child in this.Children)
{
sb.AppendFormat("<li>{1}</li>", url, name);
}
sb.Append("</ul>");
LiteralControl l = new LiteralControl();
l.Text = sb.ToString();
container.Controls.Add(l);
I'm actually relatively new to SharePoint and I was very astounded initially that one had to create individual controls manually, without a GUI interface like any normal ASP.NET web development involves. However, I had a very very good tip that allowed me to still use a GUI interface, and use it to create webparts for Sharepoint. It involves wrapping WebUserControls in webparts.
The link I used is here: http://www.a2zdotnet.com/View.aspx?id=95
You basically create WebUserControls (.ascx file) in a website, and so you can just add your controls like any normal .aspx page. You can also have a normal code-behind file (.ascx.cs). You then drag the .ascx file onto an .aspx file, so that it will then use your WebUserControl. When your .ascx files are ready and built, you copy them to the Layouts directory in the 12-Hive of your SharePoint Server. Best to create a sub-directory in there, to avoid clashing with other files in there already.
You then need to create a separate class Library project, that will have your WebPart code on. You then tell your WebPart to use your .ascx files in the layouts directory. Something like this:
protected override void CreateChildControls()
{
base.CreateChildControls();
try
{
this.Controls.Clear();
_myControl = this.Page.LoadControl("\\_layouts\\MyFolder\\WebUserControl.ascx");
this.Controls.Add(_myControl);
}
catch (Exception e)
{
err = e.Message;
}
The link I provided above provides more information, but basically you compile the webpart project and then add the DLL to the BIN directory of your sharepoint server (c:\inetpub\wwwroot\wss\ etc). You don't have to compile it to the GAC, by the way.
Then you add a entry to the web.config of your sharepoint server:
<SafeControl Assembly="MyWebUserControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="MyWebUserControl" TypeName="*" Safe="True" />
If you didn't compile the DLL to the GAC, but the BIN instead, you just need:
<SafeControl Assembly="UserControl" Namespace="UserControl" TypeName="*" Safe="True" />
Again, the link I posted above has it written in the code, a reference to the GUID, which is only needed if you placed the DLL in the GAC. You don't need the GUID part of the code if you only placed in the BIN directory.
Hope that helps.
Ash

Resources