Monday, March 27, 2006

How to show a picture library as links using frontpage and web services

I saw the request for this in MSD2D and people are always asking for similar stuff, so I guess I can start with some code samples, and if anyone wants something more specific they can ask...

The request was to make a view of a picture library, but have every picture point to a different url. this can be to the picture itself or to a url in the intranet\internet.

The following is an example of how the result will look like (I used sample icons instead of nifty looking gifs...sorry - I am not a graphical designer). The two images each link to different pages. The web part links to the picture library in a site - either a remote one or the current one.

What I suggest to people who dont want to write their own web parts using Visual Studio is to use frontpage data views and connect them using web services. This is usefull to show the data from the list in another site as well (so you can have a picture library in a master site and web parts in other sites showing it as a link list or a picture list).

The recommended best practice for this is to create a stub web part page to be edited frontpage so that no important page gets unghosted. then you can export the web part to a dwp file and import it into every page you want. If you want more information, search the internet (I will post some links when I have more time)

anyway, here is the process:

First, create an image list for your images.

If you want to use that as a link list, you will have to add a column that will hold the link each picture will point to:

  1. Go into “modify settings and columns” and click “add a new column”
  2. Name the new field and set the type to hyperlink
  3. Go back to the list.
  4. Upload a few images and set the hyperlinks so that they point to different sites.

Now, to create the view for the list (or the web part if you will).

  1. Create a dummy site or a web part page (to pervent unghosting)
  2. Open the page in frontpage and stand on a web part zone (otherwise frotnpage will just embed the new view into the page instead of having it as web part that is movable...I made that mistake preparing the screen shots - dont follow my lead on this one!)
  3. Expand the "data" menu and select "Insert Data View"
  4. Click "Add to Catalog" (we need to add the image list as a data source) select "web services" (and not sharepoint list. that option wont allow the web part to work from remote sites).
  5. Write the path to the site with the list, followed by "_vti_bin/lists.asmx" and click "connect"
  6. From the operations list select "GetListItems"
  7. Double click the "listname" variable
  8. Set the value to the name of the list you created and click ok twice to go back to the frontpage main page.
  9. In the pane you now see the new data source. open the menu for the source and choose "Show Data"
  10. Select the colunms you want to show. in this example I selected the column that holds the link to the image and the one that holds the link we entered seperatly. If you want the click on the image to open the image, you can select only the one field.
  11. In my example I first clean up the headers of the table. You dont have to do that, but at the very least you are going to want to change the text there as by default it shows the field's internal name (ows_something). Switch to code view, and run a search for the field name. We are looking for where it is inside a "<th>" tag. if you find it, delete the entire bit as shown in the following image.

    You should save the page and then open it in internet explorer to make sure the change took effect and the headers are gone with no error.
  12. Next, is the actual change to the code to make the image a link. Switch to code view again, and scroll down in the page to located the xsl code that renders the data. This may vary, depending on the style frontpage selects for you when you inserted the data view. Basically what you have to look for is a tag (a row) with some tags inside and a "<?xml:namespace prefix = xsl />xsl:value-of"
  13. Change the text inside to render each image as a link. the following are two examples for how to do that - in one the image is a link to itself, and in the other it is a link to the page the link field we added is pointing at.

Code Example 1 - Image is a thumbnail pointing to the bigger image

<xsl:variable select="@ows_link_x0020_to_x0020_open" name="linkText"></xsl:variable>
<xsl:variable select="@ows_RequiredField" name="linkImage"></xsl:variable>
<tr>
 <td class="ms-vb">
  <a>
   <?xml:namespace prefix = xsl />
   <xsl:attribute name="href">
    <xsl:value-of select="substring-before($linkText,', ')"></xsl:value-of>
   </xsl:attribute>
   <xsl:attribute name="title">
    <xsl:value-of select="substring-after($linkText,', ')"></xsl:value-of>
   </xsl:attribute>
   <img border="0" />
    <xsl:attribute name="src">http://demo02:8081/<xsl:value-of select="substring(string-length(substring-before($linkImage,substring(normalize-space($linkImage),1,1)))+1)">
    </xsl:value-of>
    </xsl:attribute>
   </img>
  </a>
 </td>
</tr>
Code Example 2 - Image is a link to a page specified in the custom field

 <tr style="display:{$GroupStyle}">
 <td class="ms-vb">
  <a>
   <xsl:variable name="linkText" select="@ows_link_x0020_to_x0020_open"/>
   <xsl:variable name="linkImage" select="@ows_RequiredField"/>
   <xsl:attribute name="href">
    <xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="substring-before($linkText,', ')"/>
   </xsl:attribute>
   <xsl:attribute name="title">
    <xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="substring-after($linkText,', ')"/>
   </xsl:attribute>
   <img border="0">
    <xsl:attribute name="src">http://demo02:8081/<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="substring(
$linkImage,
string-length(substring-before($linkImage,substring(normalize-space($linkImage),1,1)))+1)"/>
    </xsl:attribute>
   </img>
  </a>
 </td>
</tr>

Liked the tip? kick it on SharePointKicks.com

Tuesday, March 21, 2006

Content index is stuck with no (or few) documents

Just had a problem in a customer site, where the search index for non_portal_content was always on 3 documents, even though the customer had about 17 site collections, all with documents and lists with items. No matter how many times I reset the index, or tried setting up new ones, nothing was added to the index! If this happens to you, I recommend the following troubleshooting stages:
  1. Check that the sites are crawled. In "Site Settings" > "Manage crawls of Site Directory" make sure the sites you want are approved. didnt help me - they were all approved.
  2. Make sure you are running SPS SP2. Some search issues are resolved after installing SP2. To determine you are running SP2, go to the "control panel" > "add\remove programs" and check the "about" of SPS. the version should be 11.0.8126.0 (for the english version anyway). this improved matters for me - the portal index suddenly worked better, but still empty non_portal_contents
  3. Do a "Hard Reset" of the index Ok - last resort: 3.1. First stop the "Microsoft SharePointPS Search" service. 3.2. Now, go to where you installed sharepoint (or if you set the indexes to be in a different location) for example - "C:\Program Files\SharePoint Portal Server\DATA\01b905a4-6f4b-4f3b-bab9-0702d5d86968" and you should see there the "Non_Portal_Content" folder. 3.3. Rename the "Non_Portal_Content" folder to "Non_Portal_Content_Old". 3.4. Start the "Microsoft SharePointPS Search" service again. 3.5 Go to the search administration screen and make sure the index is starting a crawl

Thats it! the last thing solved my problem. the "stuck" index was fully crawled and search works as expected.

Hopes this helps anyone...if not - dont blame me!

Monday, March 13, 2006

Search Highlighting

Hey, I just have to let everyone know about this one. You know how google (and other search engines) highlights the words you searched for in the results? well, now you can do that in sharepoint! I wrote this application for Kwizcom (friends of mine). Its a sharepoint portal server search that highlights the searched words in the search page and inside the documents (doc, rtf and pdf). You also can configure how the highlighting will appear (bold? blue? blinking? just configure your own!) and how it will work (case sensative? search whole word or part of a word?). Oh yeah... a bonus feature (one that customers always ask me for) is that when you click a word document from the search results - it will open up in word and not in the internet explorer window (which is annoying!). Now your users dont have to click "back" to get from the word document back to the search results. I find it fantastic value... check it out!

Thursday, March 09, 2006

Automatically applying a theme to a site when it is created

WSS site definitions dont support setting a default theme. This leave the administrator with three options, none of them recommended:
  1. Have users manually set a theme after creating a site (ugly!)
  2. Set the company theme to a site, and save it as template and deploy the template globaly in the server (complicated, and also disconnects the sites from the file system templates, making it hard to change in the future)
  3. Change the default css files and not use the theme (extremely ugly - why are the themes for??? also does not support multiple templates with different themes)

The solution I found for the problem (thanks to Kalmberg) is to add in the site definition a link to a custom page that will run code when the site is created. the code will apply the theme to the new site.

Kalmberg example was instructive, but allow me to take you through the proccess step by step:

Step 1 - Changing The Site Definition

  1. Create the site definition that you want
  2. Go into the "xml" folder and open the "onet.xml" file in notepad or visual studio (or any editor)
  3. Find the "Configurations" tag at the bottom, and for every configuration you want to change add the following in the "Configuration" tag (where it says "THEMENAMEHERE" write your theme name. This may be case sensative): <ExecuteUrl Url="_layouts/1033/ThemeSetter.aspx?Theme=THEMENAMEHERE" />

Step 2 - Creating the ThemeSetter ASPX Page

  1. Open "C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\LAYOUTS\1033"
  2. Create a new text file, rename it to "ThemeSetter.aspx"
  3. Open the file for editing, and paste the following code into it:
    <html dir="ltr">
    <%@ Page Language="C#" ValidateRequest="False" %>
    <%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%
    
    SPWeb myNewWeb = SPControl.GetContextWeb(Context);
    myNewWeb.AllowUnsafeUpdates = true;
    myNewWeb.ApplyTheme(this.Page.Request["Theme"].ToString());
    myNewWeb.Update();
    Response.Redirect(myNewWeb.Url);
    
    %>
    </html>

Step 3 - Reset the IIS

for the changes to take affect, you will need to reset the IIS.

Now, create a site from the site definition, and the site should automatically be with the theme.

Liked it? kick it on SharePointKicks.com

Wednesday, March 01, 2006

Formatting links properly in a frontpage dataview

When creating a dataview for a list using the getlistitems function of the “lists” web service you can display a list from a remote site in your site, without having to develop a custom web part. However, inserting a link list from a web service shows the links in full text - for example : "www.msd2d.com, msd2d" This is because sharepoint stores the link's title and link in a single field with a comma and a space seperating the title and the link. What you need to do to solve this, is change the xsl of the dataview so that the link will only show the title, while the link will include only the link. In frontpage, click the dataview and switch to code view. The selected area is the entire dataview defenition. You will need to scroll down and locate the tag definition inside (location may change depending on your list and view). Change the tag using xsl “substring-before” and “substring-after” functions: Add an xsl variable that will hold the full link text : Change the xml of the href attribute to insert the text before the comma: Change the xml of the text to insert the text after the comma and the text: This can be confusing, so use my sample code below - just copy and paste it over the existing tag. You should note that the link field may be named differrently in your list. in a default links list it is named “ows_URL” but in your list you may need to check what the name is. just look in the dataview code before pasting over it. Code Sample:
<a> <xsl:variable name="linktext" select="@ows_URL"/> <xsl:attribute name="href"> <xsl:value-of select="substring-before($linktext,', ')"/> </xsl:attribute> <xsl:value-of select="substring-after($linktext,', ')"/> </a>