Google Search using Page Viewer Web Part on SharePoint 2010

If you ever tried adding Google Search code that will search your site to a SharePoint page using the HTML Form web part, you might get an error like this:

Unexpected System.NullReferenceException: Object reference not set to an instance of an object.   at Microsoft.SharePoint.WebPartPages.WikiPageWebPartSaver.SaveWebPartsInRichText(SPWebPartManager wpmgr)

A simple way to add the Google Search for your site is to use the Page Viewer Web Part and reference an HTML file with the Google Search form code:

 <!-- Search Google --> 
<font color="#006633" size="+1" face="Times New Roman">Search</font> 
<center> 
<FORM action=http://www.google.com/u/ursite method=GET target="_blank"> 
<!--mstheme--></font>
<TABLE bgcolor=#FFFFFF cellspacing=0 border=0><tr valign=middle><td><!--mstheme--><font face="Times New Roman"> 
<A HREF=http://www.google.com/ > 
<IMG SRC="http://www.google.com/logos/Logo_40wht.gif" border=0 ALT=Google width="128" height="53"></A> <!--mstheme--></font></td> 
<td><!--mstheme--><font face="Times New Roman"> 
<INPUT TYPE=text name=q size=31 maxlength=255 value=""> 
<INPUT type=submit name=sa VALUE="Google Search" > 
<input type=hidden name=hq value="inurl:www.YourSite.com/subsite" > 
<font face=arial,sans-serif size=-1><br><input type=hidden name=sitesearch value="YourSite.com" checked> 
</font><br> 
<!--mstheme--></font></td></tr></TABLE>
<!--mstheme--><font face="Times New Roman">    
</FORM> 
</center> 
<!-- Search Google --> 

Add the file to the sub folder under LAYOUTS:  \Web Server Extensions\14\TEMPLATE\LAYOUTS\Custom\google.html

Then, add a Page Viewer Web Part (Under Media and Content) to a page and set the Web Page property to http://ServerName/_layouts/custom/google.html

image

Note: You may have to allow the search to open in a new window.

Leave a Comment

SharePoint 2010 Architectures Overview Article

When someone asks, “What is SharePoint?” it is difficult to give a comprehensive answer, but this excellent article about SharePoint on MSDN does a pretty good job.

Leave a Comment

Change the Sort order for ContentByQueryWebPart (CQWP)

In a custom version of the ContentByQueryWebPart, the items that were displayed from a list were not being sorted in any meaningful way.  The default sort is the created date.  To fix this, there are a few properties that needed to be added in the implementation using the object model approach.  The properties are “SortBy”, “SortDirection”, and “SortByFieldType.”  Here is how this is done in code and note that the “SortBy” field is not the title of the field name but the item ID:

public class CoolNav : ContentByQueryWebPart
    {
            static string listGuid = String.Empty;
            static string url = String.Empty;
            static string itemStyle = "LinkList";
            static SPList list; 

            public CoolNav() : base()
            {
                if (listGuid == String.Empty)
                {
                    listGuid = SPContext.Current.Site.RootWeb.Lists["Cool Navigation"].ID.ToString();
                    list = SPContext.Current.Site.RootWeb.Lists["Cool Navigation"];
                }

                if (url == String.Empty)
                {
                    url = SPContext.Current.Site.ServerRelativeUrl;
                }
            }
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                this.ListGuid = listGuid;
                this.WebUrl = url;
                // Sort Properties
                this.SortBy = list.Fields["Order"].Id.ToString();
                this.SortByDirection = SortDirection.Asc;
                this.SortByFieldType = "Number";
                String ServerURL = SPContext.Current.Site.ServerRelativeUrl;
                //Fix the URL Path
                if (!ServerURL.EndsWith(@"/"))
                    ServerURL += @"/";
                this.MainXslLink = ServerURL + @"Style Library/XSL Style Sheets/CoolNav.xsl";
                this.ItemXslLink = ServerURL + @"Style Library/XSL Style Sheets/CoolNav_ItemStyle.xsl";
                this.ItemStyle = itemStyle;
                this.CommonViewFields = "URL,text";
            }
     }

Leave a Comment

How to verify that a SharePoint List exists

Two ways to do check if a SharePoint list exists (that I know of)…

1. Put it in a Try/Catch block

        /// <summary>
        /// Utility function to check if a list exists
        /// </summary>
        private static bool DoesListExist(SPWeb web, string listName)
        {
            try
            {
                SPList list = web.Lists[listName];
            }
            catch
            {
                return false;
            }
            return true;
        }

2. Use the TryGetList function from SPListCollection:

if (SPContext.Current.Site.RootWeb.Lists.TryGetList(ListName) != null)
{
     DoStuff();
}

 

Leave a Comment

PowerShell Script tips: Writing to a log file and checking for a PSSnapin

A couple of tips that I gleaned while writing PowerShell scripts:

    1. To write output to a file, use the “Write-Output” command like this: “Write-Output $log_text” and when executing the script, pipe the output to a file like so:

PS C:\> psscripts\coolscript.ps1 | Out-File C:\psscripts\ps.log

2. Sometimes I run scripts from within the Windows PowerShell Integrated Scripting Environment (ISE) and other times from the SharePoint 2010 Management Shell.  To avoid the error of re-adding the SharePoint snapin, I use this code to check if it has already been loaded:

$powershellSnapin = “Microsoft.Sharepoint.Powershell”
if ((Get-PSSnapin -Name $powershellSnapin -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin $powershellSnapin
}

Leave a Comment

Content and Structure Report for All Checked Out pages

Under Content and Structure (_layouts/sitemanager.aspx) there are a set of views that allow you to filter items in your site.  For instance, “Checked Out To Me”, “Pending Approval” are just two of the out of the box views.  One report that is not there, but should be, is a view for all checked out pages by all users.  Happily, you can add your own custom views by editing the “Content and Structure Reports.”

From Site Actions, select “View All Site Content”

image

Click on “Content and Structure Reports”

image

You’ll see all of the canned reports listed:

image

Click “Add New Item” and enter the Report Title and CAML Query:

<Where><Geq><FieldRef Name=”CheckoutUser” LookupId=”TRUE”/><Value Type=”Integer”>0</Value></Geq></Where>

image

Save and close

image

To use the report, go to Site Actions > Manage Content  and Structure and change the View to the new “All Checked Out” report:

image

Leave a Comment

SharePoint Central Admin error – “The specified user or domain group was not found”

While working with SharePoint Central Admin, I tried to access the Service Applications page (“Manage Service Applications” from Application Management).  Before getting to the page, I received the error “The specified user or domain group was not found.”  I checked the SharePoint logs and found this exception:

“SPAce PrincipalName domain\test.user cannot be resolved. This ACE will not be effective. System.Security.Principal.IdentityNotMappedException: Some or all identity references could not be translated.”

(For blogging, purposes, I am using the name “domain\test.user”)  The Principal Name, “domain\test.user” happened to be an actual user that was no longer at the company.  It appeared that this user, was being used for one of the service application administrators.  I checked with Operations and indeed, “test.user” was purged from Exchange the day before.  Working with operations, we recreated the same user name.  We were unsure that this would work since the unique identifier of that user would be different, but it was worth a shot.  After that user was added, I was able to access the Service Applications page again.  Success! 

The next step was to remove the user as an admin from the service application.  For this situation, the User Profile service application was the problem.  I accessed the Administrators dialog and removed the user from the list of admins.

image

The same user was also listed in the “Connections Permissions for User Profile Service Application.” I removed the user from that list as well.

image

With the user removed from the service application, Operations purged that user again.  Afterward, I was able to access the Service Applications page without the error.

2 Comments

Powershell script for updating a publishing page Page Layout in a site collection

One of the page layout templates was changed in a SharePoint 2010 site collection that I was working on.  There were already over 300 pages that were creating using the old Page Layout.  Enter… Powershell!  It took about two hours to write this script (with help from The Google) but it will probably save a day of work updating all those pages individually through the UI.

The script takes three parameters, the old or current page layout name, the new page layout name and an optional –all parameter which will traverse all the sites of a site collection.  Enjoy.

# Description:
# Update the layout page for all matching pages of the current page layout
# Checkout, Change layout, Check-in pages in a site collection
#
# Syntax:
# ./UpdateLayoutPages [-PageLayoutCurrent] [-PageLayoutNew] [-all]
#
# Parameters:
# -PageLayoutCurrent     - The page layout that is currently in use and will be updated
# -PageLayoutNew        - The new page layout that pages will be updated to
# -all                     - Update subsites in the site collection
#
# Modifications:
# v1.0 - April 5th, 2011
# Initial version
#
# Settings
set-variable -option constant -name url  -value http://localhost   # Site collection
set-variable -option constant -name comment -value "Batch PageLayout Update"   # Publishing comment

# Function: Update-SPPagesPageLayout
# Description: Update a single page in a Publishing Web
# Parameters: publishingPage, pageLayout, comment
function Update-SPPagesPageLayout ([Microsoft.SharePoint.Publishing.PublishingPage]$publishingPage,
    [Microsoft.SharePoint.Publishing.PageLayout] $pageLayoutNew, [string]$comment)
{
    Write-Host "Updating the page:" $publishingPage.Name "to Page Layout:" $pageLayoutNew.Title
    $publishingPage.CheckOut();
    $publishingPage.Layout = $pageLayoutNew;
    $publishingPage.ListItem.Update();
    $publishingPage.CheckIn($comment);
    if ($publishingPage.ListItem.ParentList.EnableModeration)
    {
        $page.ListItem.File.Approve("Publishing Page Layout correction");
    }
}

# Function: Update-AllSPPagesPageLayouts
# Description: Loop through all the pages in a Publishing Web and update their page layout
# Parameters: web, pageLayoutCurrent, pageLayoutNew, comment
# comment Comment to accompany the checkin
Function Update-AllSPPagesPageLayouts ([Microsoft.SharePoint.SPWeb]$web, [Microsoft.SharePoint.Publishing.PageLayout]$pageLayoutCurrent,
    [Microsoft.SharePoint.Publishing.PageLayout]$pageLayoutNew, [string]$comment)
{
    #Check if this is a publishing web
    if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web) -eq $true)
    {
      $pubweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web);
      $pubcollection=$pubweb.GetPublishingPages()
      #Go through all pages checking for pages with the "current" page layout
      for($i=0; $i -lt $pubcollection.count; $i++)
      {
        if($pubcollection[$i].Layout.Title -eq $pageLayoutCurrent.Title)
        {
            Update-SPPagesPageLayout $pubcollection[$i] $pageLayoutNew $comment
        }
      }
    }
    $web.Close();
}

# Check Parameters
if(($args[0] -ne $null) -and ($args[1] -ne $null))
{
    Write-Host "** Update Layout Pages from-" $args[0] "-to-" $args[1] "-on URL" $url
    $pageLayoutNameCurrent = $args[0];
    $pageLayoutNameNew = $args[1];

    $site = new-object Microsoft.SharePoint.Publishing.PublishingSite($url)

    Write-Host "Checking if both page layouts exist in the site..."
    # Check if the current pagelayout exists in this site collection
    $pageLayouts = $site.GetPageLayouts($true);

    $pageLayouts | ForEach-Object {
        if ($_.Title -eq $pageLayoutNameCurrent)
        {
            Write-Host "Found CURRENT page layout: " $pageLayoutNameCurrent
            $pageLayoutCurrent = $_;
        }
    }

    # Check if the new pagelayout exists in this site collection
    $pageLayouts | ForEach-Object {
        if ($_.Title -eq $pageLayoutNameNew)
        {
            Write-Host "Found NEW page layout: " $pageLayoutNameNew
            $pageLayoutNew = $_;
        }
    }      

    # Do not continue if the either pageLayout does not exist
    if(($pageLayoutCurrent -ne $null) -and ($pageLayoutNew -ne $null))
    {
        # Update all subsites
        if($args[2] -eq "-all")
        {
         $site.Site.allwebs | foreach {
            Write-Host "Checking Web: " $_.Title
            Update-AllSPPagesPageLayouts $_ $pageLayoutCurrent $pageLayoutNew $comment
            }
        }
        else
        {
         $site.rootweb | foreach {
            Write-Host "Checking Web: " $_.Title
            Update-AllSPPagesPageLayouts $_ $pageLayoutCurrent $pageLayoutNew $comment
            }
        }
    }
    Write-Host "**Done"
}
else
{
    Write-Host "Missing arguments.  Please check your parameters"
}
#End

6 Comments

Error occurred in deployment step ‘Recycle IIS Application Pool’: The local SharePoint server is not available. Check that the server is running and connected to the SharePoint farm.

If you get this error when deploying a SharePoint solution in Visual Studio on a SharePoint server, check that you have db_owner SQL Server permissions on the SharePoint content databases.

Update: I received a similar error to the one listed above:
Error occurred in deployment step ‘Recycle IIS Application Pool’:<nativehr>0×80070005</nativehr><nativestack></nativestack> Access denied.
For this error, make sure that you are a Site Collection Administrator

Leave a Comment

Displaying a SharePoint Modal Dialog window from SPGridView

I recently built a web part that required a list of announcements with summaries to be presented to a group of users.  Additionally, there was detailed content that was to be displayed in a Pop-up type window.  I used a gridview to display the list, which was pulled in from a web service and passing in a datatable.  That part was rather easy, but the data for the details was stored in a column that contained HTML formed text.  My first thought was to pass that to a javascript function that would call the method for displaying a SharePoint dialog: SP.UI.ModalDialog.showModalDialog();

When I added the HTML as a parameter to the javascript function, the result of doing that was rather odd.  The HTML text was displayed in the web part itself, which was not going to work.  I tried a few workarounds like encoding the HTML text and such, but I did not get good results with that either.  Instead, I knew that I had the ID for the items that I was displaying in the list.  I could pass in the ID to the dialog page and retrieve the HTML text at that point.  Unfortunately, it required two round trips to the web service (and subsequently the SQL Server).

Another issue when displaying the dialog was that the page that I was displaying contained all the elements of the master page that typical pages display (header, footer, etc).  This made the dialog too busy for the simple task it was asked to do.  To fix this, I added the MasterPageFile attribute to the Page directive which overrides DynamicMasterPageFile attribute.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AnnouncementPage.aspx.cs" Inherits="MyPages.WebParts.Layouts.AnnouncementPage" DynamicMasterPageFile="~masterurl/custom.master" MasterPageFile="~/_layouts/applicationv4.master" %>

In the end, a uncluttered summary list and detailed model dialog:

image

image

Code that made it happen:

<script type="text/javascript">
    function OpenDialog(aid) {
        var options = SP.UI.$create_DialogOptions();
        options.url = "/_layouts/MyPages/AnnouncementPage.aspx?announcementId=" + aid;
        options.width = 560;
        options.height = 480;
        options.dialogReturnValueCallback = Function.createDelegate(null, OnCloseDialog);
        SP.UI.ModalDialog.showModalDialog(options);
    }
</script>

<div class="spgridannounce">
    <SharePoint:SPGridView ID="spGridViewAnnouncements" runat="server" AutoGenerateColumns="false"
        ShowHeader="false">
        <HeaderStyle BackColor="Transparent" ForeColor="#08630C" />
        <AlternatingRowStyle BackColor="Transparent" />
        <RowStyle BackColor="Transparent" ForeColor="#BF5629" />
        <Columns>
            <asp:TemplateField>
                <HeaderTemplate>
                    Announcement</HeaderTemplate>
                <HeaderStyle />
                <ItemTemplate>
                    <a href='javascript:OpenDialog(<%# Eval("announcement_id")%>)'>
                        <%# Eval("subject") %>
                    </a>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </SharePoint:SPGridView>
</div>

Leave a Comment

Follow

Get every new post delivered to your Inbox.

Join 153 other followers