Two more “How To” documents for SharePoint
Here are two more “How to” documents…
Here are two more “How to” documents…
Most CorasWorks’ web parts have a hidden property called Display which can be added to the DWP file which will change the basic display behavior of the web part so that it emits the specific output that you’re looking for. Because the display tag is hidden it’s not available from the tool pane and must be added to the DWP file directly.
The first step is to configure the CorasWorks component so that it is correctly returning the right data and export that web part as a DWP so there will be a file that is correctly configured. To do this, make sure that the title bar for the web part is shown. If the title bar isn’t shown, enter Design mode by clicking on Modify Shared Page–Design this Page. Next, click the down arrow on the right hand side of the web part title bar. On the context menu select Export…, save the file when prompted.
The next step to customizing the output is to create the format for the replacement. The basic format for the replacement is a set of HTML fragments each terminated with a <END> “tag”. The orders of these elements is header, item (non-selected), footer, and (when appropriate) a final section for selected items. The Special Site Navigation component is the only component which has a section for selected items at this point.
In each of these sections there are several replacement strings which will be replaced with the value contained in the associated field or property. An example of the content to make a spreadsheet roll up look like a linked list appears below:
<!–Header//–>
<table border=”0″ width=”100%”>
<END>
<!–Body//–>
<tr><td style=”padding-bottom: 5px” class=”ms-vb”><img src=”/_layouts/images/square.gif”></td><td style=”padding-bottom: 5px” class=”ms-vb”><a HREF=”<%Link%>”><%Display%></a></td></tr>
<END>
<!–Footer//–>
</table>
<END>
For a list the replacement strings are the field names surrounded by a <% and %>. You can see this in the above example of <%Link%> and <%Display%> — these are both fields in the lists being rolled up by CorasWorks’ web part.
For special site navigation, there are only three replacement strings that are valid:
Adding the tag to the XML is simple, but is very specific. First, the value must be encoded or placed in a CDATA section so that it is not interpreted as a part of the XML. The best way to do this is the CDATA section so the Display property will still be readable.
First, add a new <Display></Display> tag set prior to the closing </WebPart> tag in the DWP file. Next copy the xmlns attribute from the last tag prior to the new display tag you just added and add that attribute to the display tag. Each web part uses it’s namespace for the Display tag. You must provide this xmlns attribute for the Display node or it will not work.
In the middle of the <Display></Display> tag set add a CDATA node by adding <![CDATA[ ]]>. In the middle of the two brackets ‘[ ]’ add the content that you created above.
Save the DWP file.
The next step is to import the modified DWP file. From the Modify Shared Page menu select Add Web Parts and Import. Click the browse button and locate the DWP file that you modified. Click the Upload button to upload the control. Drag the control on to the page from the tool pane.
The display of the links or navigation should reflect the updated HTML that you provided.
If for some reason you don’t see any modified display make sure that your <Display> tag has the correct xmlns attribute. It should match the other xmlns attributes in the file.
Adding a reference to a shared library from a web part is not as simple as using visual studio to add a reference to a project output or a fixed DLL on the file system. In addition to adding the reference to the project itself, you must add the DLL to the cab file and modify the manifest.xml so that the referenced DLL is deployed with the web part. This How To shows you what must be done for the web part to deploy correctly when referencing another assembly.
Adding the reference to the project can be done with the following steps:
Now you have added the reference to the project. Next is adding the DLL to the CAB file.
The process of adding the referenced DLL to the CAB file is easy. Simply follow these steps:
Now that you’ve added the DLL to the Cab file it’s time to add the file to the manifest.xml.
The final step is to add the file to manifest.xml so that STSADM will deploy the DLL for you when the web part is deployed. You can do this by following these steps:
Now you have completed the changes necessary for the web part project to deploy the referenced DLL along with your web part.
Here’s the other bit of code having to do with the pesky created/modified dates. This is just a function and not a whole program. It deletes all of the items in a destination list and then copies all of the items from the source list. The interesting bit is that the created/modified fields hold up to this mechanism. You can create a new list item that maintains the created/modified dates of the original item. As with the previous code — this is not intended for direct use. It’s designed to show you how you might copy the created/modified fields from one list to another.
/// <summary>
/// Copy list data from one list to another
/// </summary>
/// <param name=”spListRef”>The source of the list data</param>
/// <param name=”spListTarget”>The target (destination) of the list data</param>
public static void CopyListData(SPList spListRef, SPList spListTarget)
{
if (spListRef.BaseType == SPBaseType.DocumentLibrary)
{
CopyDocumentData(spListRef, spListTarget);
return;
}
SPListItem spListItemTarget;
// Delete all Items
while (spListTarget.Items.Count > 0)
{
spListTarget.Items.Delete(0);
}
foreach(SPListItem spListItemRef in spListRef.Items)
{
spListItemTarget = spListTarget.Items.Add();
foreach(SPField spFieldRef in spListItemRef.Fields)
{
if (spFieldRef.Type != SPFieldType.Attachments &&
spFieldRef.Type != SPFieldType.Calculated &&
spFieldRef.Type != SPFieldType.Computed &&
spFieldRef.Type != SPFieldType.Counter &&
spFieldRef.Type != SPFieldType.CrossProjectLink &&
spFieldRef.Type != SPFieldType.Error &&
spFieldRef.Type != SPFieldType.File &&
spFieldRef.Type != SPFieldType.Invalid &&
spFieldRef.InternalName != “owshiddenversion” &&
spFieldRef.InternalName != “InstanceID” &&
spFieldRef.InternalName != “Order” &&
spFieldRef.InternalName != “GUID”
)
{
spListItemTarget[spFieldRef.InternalName] = spListItemRef[spFieldRef.InternalName];
}
}
foreach(string attachmentUrl in spListItemRef.Attachments)
{
string fullUrl = string.Format(“Lists/{0}/Attachments/{1}/{2}”, spListRef.Title, spListItemRef.ID,
attachmentUrl);
SPFile srcAttach = spListRef.ParentWeb.GetFile(fullUrl);
spListItemTarget.Attachments.Add(attachmentUrl, srcAttach.OpenBinary());
}
spListItemTarget.Update();
}
}
Apparently, I hit a sore spot for the community with my discussion about created and modified fields. The code that follows is a very rough hack at how you can get a file into WSS while setting the created and modified dates. I didn’t bother making the code lookup the users’ ID for the site from the name on the file — but that could be done with another half a dozen lines of code or so. So here’s a command line utility to upload a file to WSS with the same created/modified dates as the original file… Remember this is a hack… it’s definitely not designed to be used for anything more than realizing how it can be done…
using System;
using System.IO;
using Microsoft.SharePoint;
namespace TESTCREATED
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
if (args.Length < 3)
{
Console.WriteLine(“TESTCREATED siteUrl ListName FilePath FileName”);
}
string paramSite = args[0];
string paramList = args[1];
string paramPath = args[2];
string paramName = args[3];
SPSite spSite = new SPSite(paramSite);
SPWeb spWeb = spSite.OpenWeb();
SPListCollection spLists = spWeb.Lists;
spLists.IncludeRootFolder = true;
SPList spList = spLists[paramList];
SPFolder rf = spList.RootFolder;
FileInfo fi = new FileInfo(paramPath);
FileStream fs = File.OpenRead(paramPath);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int) fs.Length);
SPUser createdBy = spWeb.Users[0];
SPUser modifiedBy = spWeb.Users[0];
SPFile file = rf.Files.Add(paramName, bytes, createdBy, modifiedBy, fi.CreationTimeUtc, fi.LastWriteTimeUtc);
}
}
}
Through some email conversations I’ve got a bit more detail on those pesky created and modified fields. You can set them when you’re adding a new record — and the values hold. However, it doesn’t appear that you can set them on an update… I love wandering around the depths of uncharted (undocumented) SharePoint.
One of the frustrating things about SharePoint 2003 is that the developer documentation is still a bit weak. The way that we see the impact of this is that well meaning folks end up accidentally saying that something is or isn’t supported. I’m quite guilty of it myself — although thankfully I’ve not written down any of these errors that I know of yet.
Bil Simser was noodling on the idea of updating the created and modified fields in a list and mentioned that they’re read only. (ListFormWebPart and Tzuanmi SharePoint Designer). The interesting thing is that I’ve updated these fields in a list. I did it for some technology POC code I was generating around copying list data from one list to another. I didn’t even pay attention to the read only field and I got the results I wanted. I copied the Created By, Created (date), Modified By, and Modified (date) fields.
This wouldn’t be so interesting except Adam Macaulay from CorasWorks and I had a similar discussion on the fields not two weeks ago. Their Data Migrator tool (a great tool by the way) didn’t preserve Created/Modified dates. So, I forwarded him along my POC code so hopefully he’ll be able to figure out why they initially had problems with getting the Created/Modified dates to copy from one list to another.
I wonder how many other things about SharePoint that we collectively have wrong.
I’ve mentioned through the last few posts that I’m working on another custom site definition and that I’m wandering through SCHEMA.XML definitions. Well, one of the things that I decided to do since making changes to Schema definition file is so monotonous is to automate the addition or removal of web parts in all of the appropriate schema.xml files within a site definition.
So I have yet another tool… SPSiteDefUpd — it updates site definitions to add, remove, or enumerate web parts in the various schema.xml files for the list definitions under a site definition. It has a few limitations …
OK, now that you know what it won’t do, here’s what it does do:
I think it will be very handy as I work on new site definitions and want to do a quick add of my global header, footer, and navigation. It will be trivial to get these pushed through all of the pages now. It will also be good since I will be able to allow clients to create their own new site definitions based on a site definition that I leave with them.
If anyone else is interested in trying the tool out let me know via feedback or comment, I’ll be looking for a few beta testers by the end of the week. (That will give me time to write the documentation and do a bit more testing.)
At the client I’m at we’re doing some customization of the SCHEMA.XML files for the list templates. Basically, we’re adding some web parts into the pages since our header, footer, and navigation is driven from web parts. I was over with one of the developers and noticed he was looking at the SCHEMA.XML as a text file. When I asked why he showed me, VS.2003 wasn’t able to show a XML view.
So I fired up my copy of Stylus Studio (which tells me why something isn’t valid XML in addition to just blowing up.)… I found that there were a few lines in the schema.xml which look like they were “continued.” They had an exclamation point and a carriage return at the 990th position on a line. I’ve checked through the other SCHEMA.XML files and can’t find the character … so I don’t know how it got there, but if you run into a schema.xml that won’t load, perhaps some utility has decided to add a line continuation character…