I'm currently working on a SharePoint project which requires deploying multiple custom pre-configured pages. These are pages that have web parts, but aren't the standard "configure this page however you want" pages in SharePoint.
I've found that the best way to achieve this is to create a "web part page" through the SharePoint web interface, add and connect all web parts on the page, open it for editing in SharePoint designer, and copy the code into my custom aspx page in Visual Studio.
There are multiple blogs that discuss doing this, and most of them do it in such a terrible way (I think that SharePoint walkthroughs in general suck because people doing them are less often programmers and more often business users who need a slightly more complex solution). MSDN even has a post about doing it this way.
In any case, the real reason for doing it this way, instead of simply coding up the page in Visual Studio, is because SharePoint adds a whole bunch of HTML and ASPX structure to pages that would be ridiculous to code by hand. The other reason is that there is no "toolbox" of controls for Visual Studio to add web parts and web part sections, etc.
There are some other things I do in this process to complete it:
- Any web parts added get strange IDs. Change these to something human reable so you can reference them in the code behind more easily.
- Web parts for lists get hard coded GUIDs for the lists, which won't resolve if the List gets re-deployed (which probably happens every time you deploy from Visual Studio). You'll need to resolve the list Id, Url, ViewGuid, and WebId. The Id and ViewGuid are both GUIDs but the ViewGuid is a string type (sigh). I created a little utility method to resolve these:
- The web part connections you set up will get the strange auto-generated web part IDs I mentioned above, so make sure to change those to match. They have a source and a definition.
Adding a title to the page is pretty straightforward. Just add it in the
<asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server"></asp:Content> element, which may or may not already be on your page. Oddly, when I copied in the page from the SharePoint-created Web Part Page, it had a ListItemID element, which resulted in No Title, so I just deleted it and added my own title.
I haven't yet figured out how to set up my own MasterPage, which would be useful, since I' m putting the same sidebar on a lot of my pages, but the simplest way is to just create that as a user control and drop it onto each page. Not quite ideal, but that's what I've got so far.
Adding scripts to the page is wonky.
Scripts go in a
<SharePoint:ScriptLink/> tag, and there's supposed to be a property that adds support for cache invalidation -
Localizable="False", but I haven't had luck with that, so I've been tacking a
?v=1 onto the script tag whenever I change the file. Clearly this is not good for a dev environment process, so I'm only using this for plugins, and putting script directly on the pages. There are a lot of things like this that I would never do in a custom application, but that I just don't really have a choice about in SharePoint.
Linking to a page with relative Urls
If you're linking to a page, you can avoid hard coded urls by using:
Url.Resolve? No. A weird that that I don't even know what to call. Here's what it looks like:
<%: $SPUrl:~site/_Layouts/MyPage.aspx %>
$SPUrl:~site part does is prevent the URL from resolving to the application root, because SharePoint has multiple nested sites. For example, I have a SharePoint instance at
localhost and an site at
localhost/mysite but could conceivably have
localhost/mysite/mysubsite/mysubsubsite and wouldn't want to have any of those hard coded into urls.