Contents tagged with Sharepoint
So in a recent SharePoint implementation, I was required to allow users to create links in web parts that performed server side functions. Most of the functions were known quantities but they were almost all external systems. Most of the requirements were to just display security trimmed links to Oracle and other external systems. I had envisioned a single sign-on, BDC system but it turned out the client didn't have the infrastructure to support getting the external data in that way.
My solution was to create an Xml file describing the kinds and order of calls for each web part and place all the Xml files in a document library for extraction and processing. That allows future users to pull the file, edit it and replace it as appropriate. I had a single web part with a custom text property set to the name of the Xml file. So the user added this generic web part to as many pages as necessary and set the property to the flavor they wanted to show on that page in that position. Pretty simple.
So I needed to open a file in memory from a document library and operate on it as a normal Xml document. Here is the basic structure of one of the files. There are a lot more options in the structure but this gives you the idea.
Easy to read and easy to parse. I'm no whiz at parsing Xml but I built a data object to wrap this structure and it seemed to perform pretty well. Here is the code I used to get the Xml file from the library into an Xml document object. This project required VS 2005 so I had no option for using Linq to get the data. Season to taste. Caveat Emptor.
I've seen another way of doing this but this worked best for my situation. I'd be interested in any pointers from others who have a different tack.
So in the farm I'm trying to deploy to, the tracing service starting logging some "failed to write template" messages. Thousands of them. Nobody was on the machine at the time. It wasn't available to anyone so it was internal to SharePoint, whatever it was. Then it suddenly turned into the "Tracing Service lost trace events" log entries. Finally, it stopped logging altogether.
I found in a forum post on MSDN that when this happens, you need to restart the Windows SharePoint Service Tracing service.
SharePoint immediately started logging the events appropriately.
I love SharePoint and I also hate it.
Go to the list settings page. Right click on "Title, description and navigation" and copy the URL. Paste that into notepad and copy everything after "List=" in the string. That's your URL Encoded GUID for the list. All you need to do is decode it. I found this php page that does it for you so you don't have to whip up a quick program to do it. I'm sure there are zillions of others around.
Or maybe there is a URL decoder somewhere in the MS stack that I'm not aware of. Anyone? Anyone?
There are lots of articles on the net about doing this but there were some things that I found really problematic in my efforts to get an update out.
My Business Problem
My company uses Scrum (generally) for project management. Therefore, we have planned "Sprints" that break down into tasks. These sprints have start and end dates and a status value. There is a specific project that is quite large and will involve a number of sub-projects that will be managed individually. So, naturally, we set up sub-sites from the top level project portal (MOSS). Now, the PM needs to see a listing of sprints across all sub-projects (sub-sites' sprint lists). The requirement here is that the sprint lists need to all have the same column names but they do not have to be built from a site template, though that would help speed their creation.
So in a portal page the PM wants to see each project with each sprint across all sub-sites. He wants to see sprint name, start date, end date, current status and an icon that corresponds to that status value.
This solution involved importing a customized .webpart file and updating the ItemStyle.xsl file with a new template element.
I'll do a longer blog if I have time of how I did the complete solution but for now, here are the things that I found that didn't show up on the other site's tutorials.
In the ItemStyles.xsl file, the name and match values cannot include spaces.
If you copy the Default template, make sure you modify the match="*" to be the name of the template. Otherwise, any testing stuff you put in will show up for every web part that uses the default template. Could suck big...
Unlike HTML, the ItemStyles.xsl file is absolutely syntax-sensitive. I accidentally put in a duplicate element. Thud! I put in an HTML image tag with no "alt" tag. Splat!
To format a date:
If you add HTML tags to your item template and it bombs, put it into an HTML file in VS 2008 and see if you get squigglies indicating a "standards" issues with the element. (e.g. img tags require an alt element)Divs seem to always take up an entire row even if their styles have hard widths set. Try nesting spans in divs and setting the styles there. Not sure how this will fly with FireFox but it works in IE. Nobody uses FF anyway, right ;)Find the style templates by going to the portal page --> View All Site Content --> Style Library -- XSL Style SheetsIn the .webpart file, if you use the ListOverride property, the lists indicated by the GUID's appear to be available across the site collection no matter where you place the webpart in that collection.
add this to the top of the ItemStyles.xsl - xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
Then this to the xsl variables - <xsl:variable name="StartDate"><xsl:value-of select="ddwrt:FormatDateTime(string(@Start_x0020_Date), 1033, 'M/d/yyyy')" /></xsl:variable>
Then this to render it: <div><xsl:value-of select="$StartDate"/></div>
In the .webpart file, using the CommonViewFields property, don't put any spaces anywhere in the property value.In the .webpart file, using the CommonViewFields property, use this link to see what the SPFieldTypes available are. If you don't put the correct field type string, it will not work and it will not error out.When you're constantly importing and re-importing the .webpart file, try appending an integer to the title. This will tell you if your update worked and when you get back from lunch you'll remember whether or not you actually deployed the last changes.For all files that you work with, before you edit them, MAKE A COPY!!!
I imported my web part into a sub-site and it saw all the lists from sites that were at the same web-level as that site. So it looks like it was looking from the site-collection down no matter where in the collection you place the web part. Not sure if this is exactly true but its what worked on my MOSS VPC. Caveat emptor..
Hope this helps a bit...
This is what my finished web part looks like in test:
Note to self, you'll need this later...
So one of the issues with SharePoint is the fact that the tasks you need to complete anything are pretty straight forward as long as nothing goes wrong. Case in point: I tried to deploy one of the "Fab 40" templates on a VPC and forgot that I had not previously deployed the application core template on that machine. The solution deployment went fine and the site template was available for creating a new site. Good to go except the site creation failed. Whoops. Look up the GUID of the feature that the error message listed and realized my error. No problem: delete the site (url is important in this case), deploy the application core wsp and start over.
After doing my thing, I get an error saying "The web site "/MyURL" address is already in use." How can that be since I deleted the site? Turns out I deleted the site but not the URL leaving the URL an orphan. I don't know if this is absolutely correct and appropriate but these steps were tested by me and they worked.
Navigate to the home site
Select View All Site Content and find the site in the Sites and Workspaces list
Click on the link for the site
Click Site Actions --> Site Settings
Click Site Administration --> Delete this site
Click Delete and confirm
You should have just deleted everything but you need to back check. If you encountered an error in provisioning the site, the above may not work. So go look at the site hierarchy.
Navigate to the hom esite
Select Site Actions --> Settings Settings --> Modify All Site Settings
Under Site Collection Administration, click on Site hierarchy
If the URL is not there, you're done, if it is there, click on Manage
Under Site Administration, click Delete this site
Click Delete and confirm
That should actually kill the site and the URL.
So here's my current plan for firing up these new technologies. As background, I gave a 15 minute presentation at a user group last night on the generalities of data abstraction and although I think I did ok, I also think that there are a lot more questions than answers in the developer community right now with regard to how to get data back into SQL Server through Linq.
I'm going to start out doing just Linq as I think its a little deeper than EF and more appropriate as a starting point. I also am concerned about how well EF will perform in the enterprise but that's for another day.
So I'm going to take the database I built for this presentation and put some data in it. Here's the current plan.
1. Explain where to find SQLMetal.exe and how to use it to generate an entity layer.
2. Take a look at normalized data in a real world scenario that includes things like null values and empty foreign keys (candidates for left join in SQL).
3. Figure out how to send an anonymous type to a business object so that I don't have to store the Linq query in my business object.
4. Get data from a business object back into the database for an update via Linq to SQL.
5. Get new data into the database from a business object via Linq to SQL.
6. Build and deploy a web part that allows the insert/update/viewing of all this data in VS 2008.
Wherever I find another blog or article that helps me move ahead I'll post that too.
Not sure if I'll have time to do all this as I believe a new project is on my horizon but I'll do as much as I can. I'm also not sure how much of this has been done elsewhere or whether its even worthwhile. I think it will be a fun evolution though.
Along with part 1, I'll post a script to create and populate the database I'll be using.
I've posted on a couple of forums for SharePoint development and haven't received a response yet. The bottom line appears to be that regardless of whether or not you have WSS or MOSS loaded onto your machine, you will not get project or item templates for web parts. If someone knows what I'm missing, please post a comment.
In VS 08, I was able to pull in an existing web part and it did compile but I have to make my own wsp, manifest.xml, elements.xml and solution.xml files. I'll also have to take an existing batch file for easing deployments to client machines. Not a huge deal but a little painful. I hope to see some support offered soon from MS.
The configurations I tried are: MOSS + VS 08 and MOSS + VS 05 + VS 08. Interestingly, the msi for the SharePoint extensions CTP 1.1 installed without a hitch on a VM that didn't have VS 05. hmmm
So no matter what you do, you are going to need to drop and modify things in the "12 hive" in SharePoint. I navigated to it exactly 3 times before I decided my best move would be to just create a shortcut. I made the shortcut to this folder:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ADMISAPI
because I wanted to have the entire 12 hive automatically opened up. I put the shortcut in My Documents so its always available when I explore the hard drive. I think this has already saved me a lot of time in the way of navigation.
Create a warmup.bat file based on this blog post:
This will allow you to get all the appropriate services running as soon as you fire up your virtual machine. You are developing on a MOSS VM, right?
So the requirement presented to me for a client was to take an existing page layout and change a few of the properties to allow it to use some custom styles implemented at the site collection level. To do this, I needed to create a new page layout based on an existing layout, make this part of a feature and pull in all the bits and pieces necessary to deploy this as a feature. Finally, I had to deploy it to the client's testing environment.
Here is how I did it...
First, I was instructed that the Search Main Page was to be used as the starting point. A developer on my team told me the best way to go would be to load up SharePoint Designer, navigate to the appropriate document library and export the file. This didn't work. My requirement was to have the search web part already on the page, the same as the existing search main page. SharePoint Designer killed this web part tag so it came up empty.
Getting a copy of the page layout
1. Better is to go to the site collection you're starting with
2. Select "Site Actions" -> "Site Settings" -> "Modify All Site Settings"
3. Under "Galleries", select "Master pages and page layouts"
4. Find the page layout from the list and open its context menu, select "Send to" -> "Download a Copy"
5. Save the file to the solution location. We won't be using Visual Studio because its not necessary for this evolution.
6. Once the file is saved, reopen the context menu for the page layout file and select "View Properties".
7. Click on the Preview Image and when it appears, right click and save the image to the same location as the aspx file.
Now you have the basic aspx files you will modify and put back into SharePoint as a feature. Open the aspx page in an appropriate editor. I'm assuming you understand enough about aspx to do what you need to do. Make the appropriate modifications and save the file.
IMPORTANT NOTE: If you are like me, you have a desire to 'clean up' the file declarations so you can see what's going on. Don't do this. I haven't figured out why but when I introduced hard returns in the second line (the really long one) of declarations between <% %> sections, it bombed when I reimported it into SharePoint. A guy on the team here thinks there may be a checksum on that line to head off tampering. Dunno but I know when I leave it it works, when I touch it it bombs.
You can also use any editor (Paint.Net works) to change the page layout to look the way you want it to. Change the folder of this file to your feature folder + "\Images". It's required for the page layouts and master pages.
So you should have two files and a subfolder for your feature ready to go.
Now we need to set up the feature to deploy it.
1. Create two new files in any editor: "feature.xml" and "layoutfiles.xml"
2. Here are the contents of my feature.xml file:
Title="Custom Formatted Search Page Layout by Jim"
Description="Search page with customized style inclusions"
2.1. Id is a new GUID you generate from Visual Studio.
2.2. Scope means the level where this will be used, not the level at which it becomes available for items below it. So "Site" scope means it will be installed at the site collection level and used at the site level.
3. Here are the contents of my layoutfiles.xml file:
<Module Name="CustomSearchMain" Url="_catalogs/masterpage" Path="" RootWebOnly="TRUE">
<File Url="CustomFormattedSearch.aspx" Type="GhostableInLibrary">
<Property Name="Title" Value="$Resources:spscore,SearchMainTitle;" />
<Property Name="MasterPageDescription" Value="$Resources:spscore,SearchMainDescription;" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
<Property Name="PublishingAssociatedContentType" Value=";#$Resources:cmscore,contenttype_welcomepage_name#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D4;#" />
<Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/Preview Images/customsearchpage.gif, ~SiteCollection/_catalogs/masterpage/Preview Images/customsearchpage.gif" />
<AllUsersWebPart WebPartZoneID="TopZone" WebPartOrder="1">
<Assembly>Microsoft.SharePoint.Portal, Version=220.127.116.11, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Module Name="LayoutPreviewImages" Url="_catalogs/masterpage/Preview Images" Path="Images" RootWebOnly="TRUE">
<File Url="customsearchpage.gif" Type="GhostableInLibrary"/>
3.1. I took most of this from a coleague and from the net. The CData portion gives you the embedded web part already in the top web part zone.
3.2. Notice the gif image parts of the xml. These are whatever the new name is for the gif you edited earlier.
3.3. Notice also the part that says: "contenttype_welcomepage_name". This means that your layout will appear under the "Welcome Page" templates when you go to use it in your site collection. I haven't found much about this on the web yet but I believe if you search on content types and master page libraries, you may find additional options.
Your feature is complete!
Now its time to deploy.
1. Copy your aspx, gif (in its folder) and 2 xml files to the server where you want to deploy and into a new temporary folder.
2. Copy from the temp location to the 12 hive \Template\Features\ folder.
3. Open a command line and run: stsadm.exe -o installfeature -name MyNewPageLayoutFeature -force
3.1. Use the -force option if you've already installed previously.
3.2. the -name value is the name of the folder where the your feature now exists in the 12 hive.
4. Execute iisreset
5. Browse the the appropriate site collection on your server and back to "Site Actions" -> "Site Settings" -> "Modify All Site Settings"
6. Under "Site Collection Administration" select "Site Collection Features"
7. You should see your new feature/page layout. Click to activate.
Use your new layout.
Now, when you go to create a new page, you should see your additional layout. When you select it, you should get your custom layout gif to show users what it will look like.
I can imagine really intricate uses of this for creating custom CRM dashboards or for magically including SilverLight applications in your system. Good Luck!