Tuesday, October 30, 2007

Some good read (aka linklove! :)

  • Solutions - deployment options compared by Chris O'Brien, Chris discusses the options and best practice on when to use what to migrate content from development environments to staging to production. Very handy read for us developers!
  • DPM 2007 has RTM'd !!!!!!!!!!!!!!!!!!!!!!!!! by Jason-DPM, the announcement that DPM is finally in RTM (Release To Manufacture). Here is a snippet from the post that covers what DPM really is all about :

    With DPM 2007, customers can look to Microsoft not only for their SQL Server solution (as an example), but also for the backup and recovery of that SQL Server deployment – from the simple incremental purchase on their existing Volume License / Enterprise Agreements, to their TAM understanding their needs, to the Microsoft Consulting Services deployment specialist, to Microsoft product support services.   Now, for authenticity's sake, are there still reasons to use non-Microsoft backup solutions for backing up Microsoft workloads - probably.  Some are political, othes are proceedural, and a few are technical.  But at least now, it isnt a mandate.  If a customer is predominantly using Microsoft workloads, they no longer have to look elsewhere to protect those workloads.

    Similarly, DPM empowers Microsoft Partners who may or may not have a storage/backup specialty, but who are experts in their application areas (SQL Server or SharePoint) to deliver a rich data protection experience that is optimized for the workload that they are deploying for their customers -- again, consolidating that expertise back to the application owner/integrator without looking elsewhere

  • SharePoint Logging Spy - Awesome Tool by Neil (RRE), Neil who is a member from the very elite Rapid Response Engineers team at MS is talking about a tool that is available on CodePlex that logges almost everything ".. I'd like a tool that can show me everything that is happening across my MOSS farm all in one place. I'd like to see the ULS logs in realtime but integrated with the event logs. I'd want to be able to check out the status of running processes and see the farm roles and configuration, again all in one screen. I'd like ....."
  • Recommendations for SharePoint Application Pool Settings by Joel Oleson's SharePoint Land, very recommended read!

 

Technorati tags:

Something's still are better in 2003 than in 2007

And here is one of those reasons:

When you created a new sitecollection using SPS2003, you were prompted with a screen that required you to fill in an owner of that particular sitecollection. If users were added to the site, the 'From' field of the email was the one of the sitecollection owner. So if users were confronted with access problems they could immediately email the site collection owner to fix those problems. 

Now in 2007 you only have the 'To' field and the 'From' field is being used from the webapplication settings and therefore is a global email address. So users cannot 'simply' reply to the sent email.

 
Does someone know how to setup a different 'From' emailaddress for each sitecollection?

 

Technorati tags: , ,

Thursday, October 25, 2007

SPARQL, SharePoint and IMM?

 

From the IMM (Interactive Media Manager) blog comes a post on how they made the screenshot above here possible.. here are some snippets to attract you to their post and become as enthusiastic about it as I am :)

we aren’t using a list to store our data. Instead what we decided to do with IMM is to store all of our metadata in Resource Description Framework (RDF). RDF is a specification outlined by the W3C at http://www.w3.org/RDF/. Since RDF by itself can be a very unstructured way of describing things a Web Ontology Language (OWL) (http://www.w3.org/2004/OWL/) was created by the W3C to create a vocabulary so that things could be described consistently and related to each other. In this article I don't want to go into all of the details on why we chose RDF over using a SharePoint list or something else. This is saved for another day.

As I mentioned earlier the data is stored in an RDF store that we have running outside of SharePoint. In order to get to this data we use SPARQL queries. SPARQL is a W3C specification (http://www.w3.org/TR/rdf-sparql-query/) that specifies how to query RDF data. For the media library these queries are stored in the Data Source section of the template XML file.

The syntax for these queries appears to be similar to SQL but that is as far as it goes. The similarity is truly only skin deep. Does this make it a shallow language? Not really as SPARQL is only able to do perform SELECT queries but it provides a lot of power around it.

 

In case you wondering what IMM is, it's a solution developed by Microsoft for media and entertainment companies which use SharePoint for their collaboration environment.

 

Technorati tags: , ,

Tuesday, October 23, 2007

Some cool things

Within the last week a lot of cool things popped out of nowhere! (well actually they didn't but it makes a better story if I told that it was right?:)

  • Servé's Theme Generator, my mate has been very busy developing a theme generator. Here is a snippet of what it can do :
  • This tool takes an original style sheet from an existing theme.

    It then simplifies colors according to the number of colors you want. Remember that a default style sheet easily has 50 unique colors it in. Try to replace those with you company colors. It takes a while. You can tell this tool to simplify the color scheme to for instance 16 colors. Then you start editing the remaining 16 colors, until you are satisfied.

    The tool also replaces general and header font definitions. Again, there are a lot of font definitions you'll have to replace. And always you will just miss those which are defined in the Core.css. This tool replaces all of them. You can define the general font family, size, color and letter spacing. Also for the header.

    Finally, you can replace all images and define your own header. Very nice feature because by just entering your new theme name, every existing image will be replaces by the same filename with your theme name added. Which makes all of the images unique. If they don't exist they won't show up and you are rid of all the background images and gradient stuff. If you for instance, want a list header gradient, just upload the image, use the original file name added with your theme name, and ready.

  • SharePoint Skinner by Doug W (SharePoint Skinner Tutorial), a bit like Serve's although slightly different is this skinner tool by Doug. The difference is that Servé's generator simplifies the color schemes whereas Doug's gives you an overview of all the color that are being used and showed real-time what the effects are if you change them. I think the combination of both them tools are superb!
  • Listas, a new tool by Microsoft Labs in which you can share a list with friends or colleagues. Here is a snippet of the listas site about what Listas really is..  (what's up with the Vista > Listas connection?!)
  • Listas is a tool for the creation, management and sharing of lists, notes, favorites, and more. It allows you to quickly and easily edit lists, share them with others for reading or wiki-style editing, and discover the public lists of other users.  We encourage you to try using it for meeting notes, bookmarks, shopping lists, to plan a night out, or whatever other creative ways you can think of.

  • PopFly, a tool that I blogged about a couple of months ago but now finally available for the public beta, is PopFly. An online mashup tool by Microsoft.. very cool shit! Check out (another) movie by Mike Gannotti : Video- Creating a Popfly Video Mashup in 4 Minutes or Less on how powerful and easy it is. I see a lot of future in this product if it's made available for offline use as well (SharePoint lists being queried and mashed up in a very sleeky looking building block?)
  • Gatineau, a web-analytics tool by MS. Maybe this is the answer from MS to Google Analytics (which is a very cool analytics tool if I say so myself!). Hopefully this tool is not only made available for web analytics but also for analytics for BI. Maybe as an add-on for Performance Point Server? Check out movie samples at The skinny on Gatineau

 

Wednesday, October 17, 2007

Policy for Web Application

Learning from my own mistakes, I wanted to share the following bit about defining security policies for a web application using Central Admin. If you open up the Application Management you see the following section :

Now there is a 'no-touchy' link and 'yes, please touch me link'. The 'no-touchy' link is the 'User permissions for Web Application" link, when you touch and uncheck some options like 'Manage Web Site'. You will experience strange behavior and errors described in some previous posts Self-Service Site Creation and permissions and Permissions and workflow.

Best practice is to leave that thing alone and define your own 'user-permissions for Web Application' using the 'yes, please touch me link' ;)

Once there, click on the "Manage Permissions Policy Levels" (on the left)

Click on "Add Permission Policy level", then you see an overview all the permissions (like in "User Permisisions for web application" link) and you can deny of grant the permissions according to the requirements that you have.

So give it a proper name and description, check the permissions you want to give and click on OK. Next step is to add a group of users (in my case ALL the users) to use that permission level. Click on "Add Users", click Next (you can apply the custom policy to zones here (for example an internet zone on the same webapplication has different permissions that the intranet zone))

Type in the Groupname (or just particular users), check your custom permission level and click on Finish et voila. You've assigned all the users to make use of your custom permission level. Thereby letting all the service accounts use their own permissions levels.

 

Explorer View problems

If you are experiencing problems with the Explorer View (don't matter which version of the product you are using) check out the following post : Explorer view problem by S.S. Ahmed - MVP Microsoft SharePoint

In our case, the update of the webfolders (Webfldrs-KB892211-ENU.exe) did the trick! Also mentioned in the post is to overcome the hard coded longer than 255 characters in an url limitation using REGEDIT.

Monday, October 15, 2007

Be careful with uninstalling (core) features

At a customer a requirement came not to enable wiki page libraries (yet) for WSS teamsites. So like I did with customizing the SiteSettings feature, I looked in the FEATURES folder to find where the wiki library was located and 'just' uninstalled the feature. For your information, the feature that covers the wiki library is called "WebPage Library (little odd though).. So I went in and uninstalled feature and voila the link to create a wiki library was gone! Yeah baby! :)

But then.... when I tried to create a site (didn't matter if it was a sitecollection or subsite) I was prompted with:

The template you have chosen is invalid or cannot be found.

Luckily a test user was testing the creation of mysites and he got the same error as I did. Then I did checked the event log of the server, the following error was given during the creation :

Event Type:    Error
Event Source:    Office SharePoint Server
Event Category:    User Profiles 
Event ID:    5187
Date:        10/15/2007
Time:        8:28:39 AM
User:        N/A
Computer:    FRONTENDSERVER
Description:
My Site creation failure for user 'Username' for site url 'http://portal/personal/username'. 
The exception was: Microsoft.Office.Server.UserProfiles.PersonalSiteCreateException:
A failure was encountered while attempting to create the site. --->
System.ArgumentException: Dependency feature with id 00bfea71-c796-4402-9f2f-0eb9a6e71b18 for feature 'TeamCollab'
(id: 00bfea71-4ea5-48d4-a4ad-7ea5c011abe5) is not installed.

Looking at the error, two things were blinking in my eye and those were "TeamCollab" and "Dependency feature". So.. because of my uninstallation of the Wiki Page Library, none of the sites could be created because the TeamCollab feature wants to fire the WebPage Library feature and fails doing so. And what amazes me the most that this error was given by the UserProfile service!

Once I installed the WebPage Library feature again, all the sites (mysites & teamsites) could be created.

So let that be a lesson to everyone ! ;)

 

Technorati tags: ,

Thursday, October 11, 2007

Alerts not working *all the time*

We had (maybe still) have a problem that alerts don't work all the time. It seems that not for every edit or add action an alert is being sent to specific users. Unfortunately I could not reproduce this error although I did not receive some alerts myself. So I placed a call at Microsoft Support to help me out on this one.. I explained to them that this environment is an upgraded one (2003 > 2007) and that the alerts do work (so I don't have Ishai's problem). I got an answer from Holger Lutz (start blogging mate! ;) a SharePoint Support Engineer and he told me to take the following steps :

  • Using STSADM to make sure that the alerts for that particular site are set properly:
stsadm.exe -o setproperty -url <http://yourserver/problemsite> -pn alerts-enabled -pv true
stsadm.exe -o setproperty -url <http://yourserver/problemsite > -pn job-immediate-alerts -pv "every 5 minutes"

Now it's wait and see if the clients that reported the problem do not experience the same behavior as before..(it's a real bugger that the problem can't be reproduced since it's so random)

Update : got a tip from Servé to look at the following post : Sharepoint 2007 task notification alert emails not working 

Technorati tags: , , ,

Wednesday, October 10, 2007

MS IT Usage and Storage Reporting Tool Released to Codeplex

As Joel and Mike point out in there latest blogposts.. Cory Burns published a MS, up until now, internal tool on CodePlex to monitor usage and storage of SharePoint environments:

I am pleased to announce I have finished version 2.0 of the MSIT SharePoint Reporting Framework.  Versions 1.0 was used heavily internally for our service metrics and operational tracking.  With version 2.0 many great improvements have come out of it, additionally with the release to the public :)  I encourage everyone to head over and check it out.  Thanks!!

In this post I will guide you on how to implement this since this is not an application which you can install clicking using a wizard (yet ;))..

  1. Download the file from CodePlex
  2. Logon remotely to the SQL Server of your acceptance environment
  3. Start > All Programs > SQL Server 2005 > SQL Server Management Studio
  4. Login with the same account as the database access account that is used for your SharePoint environment
  5. Click on "New Query"
  6. Paste the first snippet and click on Execute (the database needs to be created first before the stored procedures get built)
  7. GO
    /** MetricsOPs Database Creation **/
    SET NOCOUNT ON
    GO
    IF Exists (select name from master..sysdatabases where name = 'metricsops')
    PRINT 'Metricsops Database allready exists - Skipping Creation.'
    ELSE
    BEGIN
    DECLARE @CMDSTR6 NVARCHAR(4000)
    SELECT @CMDSTR6 = '
    create database metricsops
    alter database metricsops
    Modify file
    (name = metricsops,
     filegrowth = 10%);
    alter database metricsops
    modify file
    (name = metricsops_log,
    filegrowth = 10%)
    '
    EXEC (@cmdstr6)
    PRINT 'Metricsops Database Created.'
    END
  8. Next paste the remaining snippets to create the stored procedures
  9. Then to populate the tables use the created stored procedures by using the following snippet
  10. use metricsops
    exec cb_q1_proc
    exec cb_q2_proc
    exec cb_q3_proc
    exec cb_q4_proc
    exec cb_q5_proc
  11. To view the data, open up the tables
    1. cb_q1 > Gives you an overview of all the sitecollections with data about sizing, last modified date, bandwidth usage, recycle-bin size, etc
    2. cb_q2 > Gives you a total overview per config database which content databases host which sitecollection
    3. cb_q3 > Gives you an overview of all the servers in the farm
    4. cb_q4 > Gives you an overview of all the sitecollections and sites about pages (?)
    5. cb_q5 > Gives you an overview of all the databases on the SQL Server with their sizes and unallocated space
  12. Connect using a front-end application (Excel, Report Server) to view those tables in nicely way in SharePoint ;)


 

Technorati tags: , , , ,

Installing SPS2003 on a machine with MOSS2007

In these times of upgrading/migrating/using MOSS 2007, it's hard to find development machines without MOSS installed on them. Now MOSS is, of course, not the problem when you want to install the 2003 version on it as well.. but .NET 2.0/3.0 are! Since 2003 was built for .NET 1.0/1.1 and since SP2 it had .NET 2.0 support.
I restored a portal using Central admin and then point to the restored databases as SITE/PROF/SERV databases on a clean virtual server in IIS. At first sight everything looked fine.. the portal was up and running and all the content was there. Problems started at the Search & Index page.. It tried to crawl the portal and I only got the following errors in the gatherer log:

Could not load type 'Microsoft.SharePoint.Portal.SiteData.BucketWebSecurityProvider'

Now if you type in this assembly in Google the only hit you are getting is the following : "SharePoint Portal Server 2003 APIs that Do Not Work in Office SharePoint Server 2007" Now this started to ring a bell.. So I checked which .NET version was selected in IIS for the virtual server and, as you may have guessed, .NET 2.0 was selected. So I changed this back to .NET 1.1.. hit an IISRESET and now I was getting errors that particular settings in the web.config weren't supported. So I modified these (in the IIS Folder as well in the 60 hive > templates\layouts folder) and my portal was up and running again and the indexer could crawl my portal woohoow! :)

Technorati tags: , ,

Friday, October 05, 2007

Account locked WebPart

And while I'm at it.. I created another webpart that tells an administrator whether or not an useraccount is locked out in Active Directory. Further I provide the admin with information about the last logon time and when the password will expire. There is a lot to be found on what you can extract from Active Directory using System.DirectoryServices and ActiveDs :)

Here is the code to get the informatio to check whether an account is locked:

 object o = entry.InvokeGet("IsAccountLocked");
 if (o != null)
 {
     bool locked = (bool)o;
     output.Text += "Account Locked : <b>" + locked.ToString() + "</b>";
 };
 

Here is the code to check whether an account is disabled :

bool isDisabled;
isDisabled = ((int)entry.Properties["userAccountControl"].Value &
(int)ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE) != 0;
output.Text += "<BR>Account Disabled: <b>" + isDisabled.ToString() + "</b>";

Here is the code to see when the successful logon was :

object lastlogon = entry.InvokeGet("LastLogin");
if (lastlogon != null)
{
      DateTime LastLogon = (DateTime)lastlogon;
      output.Text += "<BR> Last Logon was at : " + LastLogon.ToString("d", ci) + "  " + LastLogon.ToShortTimeString();
}

And to determine when the password is about to expire use this code :

LargeInteger liAcctPwdChange = entry.Properties["pwdLastSet"].Value as LargeInteger;

// Convert the highorder/loworder parts of the property pulled to a long. 
 long dateAcctPwdChange = (((long)(liAcctPwdChange.HighPart) << 32) + (long)liAcctPwdChange.LowPart);

// Convert FileTime to DateTime and get what today's date is. 
DateTime dtNow = DateTime.Now;
// I added 90 days because I know what my password expiration is set to, if not you need to pull that information and add the number of days it is set for. 
DateTime dtAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).AddDays(180);
string strAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).ToString("d", ci);
string strAcctPwdExpires = DateTime.FromFileTime(dateAcctPwdChange).AddDays(180).ToString("d", ci);

// Calculate the difference between the date the pasword was changed, and what day it is now and display the # of days. 
TimeSpan time;
time = dtAcctPwdChange - dtNow;

output.Text += "<BR>Password will expire in " + time.Days + " days";

You can reuse the code from the previous post to get things working

 

AD Change Password WebPart

Update 30/1/2009

See the latest post about this at zevenseas AD ChangePassword WebPart released where you can find the link download this ;)

 

It was always a nice to have for our extranet environment to have a webpart available within SharePoint to let users change their password instead of using an isolated .NET web application (no.. not a SharePoint WebApplication ;)). As it turned out in the last couple of days it became a must-have since the webapplication didn't seem to work properly anymore. Please note that everything did run smoothly for 2yrs. Although a couple of weeks ago we migrated the environment from 2003 to 2007, ever since users received errors like "The server is not operational" when they tried to change their password.

So I once again turned on my best friend Google and try to find any free/opensource ChangePassword webparts. Unfortunately I couldn't find one so I wrote one myself (more fun anyway eh? ;)) Luckily enough I could re-use some of the code that I used to build the webapplication. 

So how does my webpart look like in code?

using ActiveDs;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System;
using System.DirectoryServices;
using System.Web.UI.WebControls;


namespace ChangePassword
{
    public class ChangePasswordWebpart : System.Web.UI.WebControls.WebParts.WebPart
    {

        private TextBox oldpassword;
        private TextBox newpassword;
        private TextBox checknewpassword;

        private LinkButton btn;
        private Label output;


        protected override void CreateChildControls()
        {
            this.oldpassword = new TextBox();
            this.oldpassword.TextMode = TextBoxMode.Password;
            this.Controls.Add(oldpassword);

            this.newpassword = new TextBox();
            this.newpassword.TextMode = TextBoxMode.Password;
            this.Controls.Add(newpassword);

            this.checknewpassword = new TextBox();
            this.checknewpassword.TextMode = TextBoxMode.Password;
            this.Controls.Add(checknewpassword);

            this.btn = new LinkButton();
            this.btn.Click += new EventHandler(btn_Click);
            this.btn.Text = "Change Password";
            this.Controls.Add(btn);

            this.output = new Label();
            this.Controls.Add(output);

            base.CreateChildControls();
        }

        
        void btn_Click(object sender, EventArgs e)
        {

            if (newpassword.Text.ToString() == checknewpassword.Text.ToString())
            {

                SPWeb webContext = SPControl.GetContextWeb(Context);
                string strLoginName = webContext.CurrentUser.LoginName;

                int iPosition = strLoginName.IndexOf("\\") + 1;
                strLoginName = strLoginName.Substring(iPosition);

                

                DirectoryEntry entry = new DirectoryEntry("LDAP://domain.com", strLoginName, oldpassword.Text.ToString(), AuthenticationTypes.Secure);
                DirectorySearcher search = new DirectorySearcher(entry);
                search.Filter = "(SAMAccountName=" + strLoginName + ")";
                search.SearchScope = SearchScope.Subtree;
                search.CacheResults = false;

                SearchResultCollection results = search.FindAll();
                if (results.Count > 0)
                {
                    foreach (SearchResult result in results)
                    {
                        try
                        {
                            entry = result.GetDirectoryEntry();
                        }
                        catch (Exception error) { output.Text += "<BR>" + error.Message.ToString(); }

                    }

                    try
                    {
                        entry.Invoke("ChangePassword", new object[] { oldpassword.Text.ToString(), newpassword.Text.ToString() });
                        entry.CommitChanges();
                        output.Text += "<BR> Password is changed";
                    }
                    catch (Exception)
                    {
                        output.Text += "<b> Password couldn't be changed due to restrictions<b>";
                    }
                }
                else
                {
                    output.Text += "<BR> User not found or bad password";
                }
            }

            else
            {
                output.Text += "<BR>Passwords don't match";
            }

        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {

            string strLoginName = string.Empty;

            try
            {
                SPWeb webContext = SPControl.GetContextWeb(Context);
                strLoginName = webContext.CurrentUser.LoginName;
            }
            catch (Exception) 
            {
                output.Text += "<BR> Please sign in first using the 'Sign In' button above";
            }

            if (strLoginName != string.Empty)
            {
                writer.Write("<table border=0>");
                writer.Write("<tr>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("Current password:");
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                oldpassword.RenderControl(writer);
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("</td>");
                writer.Write("</tr>");
                writer.Write("<tr valign='top'>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("New password:");
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                newpassword.RenderControl(writer);
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("</td>");
                writer.Write("</tr>");
                writer.Write("<tr valign='top'>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("Confirm new password:");
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                checknewpassword.RenderControl(writer);
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("</tr>");
                writer.Write("<tr valign='top'>");
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                btn.RenderControl(writer);
                writer.Write("</td>");
                writer.Write("<td class='ms-vb'>");
                writer.Write("</td>");
                writer.Write("</tr>");
                writer.Write("</table>");
                output.RenderControl(writer);
            }
            else { output.RenderControl(writer); }

           
        }
    }


}

You have to reference the "System.DirectoryServices" and the COM "Active DS Type Library", also when you package everything together, make sure that the Interop.ActiveDs.dll is included otherwise it doesn't work.

And at runtime it looks like this:

 

Hope this helps someone who is looking for the same as I was ;)

Thursday, October 04, 2007

Replacing the search bar

In this particular case, a customer already has a enterprise search engine so it wouldn't make sense of having two search engines crawling the same content. Therefore my task was to redirect the user with his search query to the page of that search engine. The fist thing that sprung into my mind on how to do this, was to modify the masterpage and remove the current searchbar with my own.

So I created the following HTML to simulate the look&feel of the default searchbar :

<table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
</table>

Then I opened up our default.master and traced the following bit

 <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server">
    <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox"/>
  </asp:ContentPlaceHolder>

I replaced the DelegatedControl within the ContentPlaceHolder with my HTML (see below) and previewed it SharePoint Designer and there was my modified search bar! :)

<asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server">
 <table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
 </table>
</asp:ContentPlaceHolder>

It was a big suprise to find out that when I opened up the default.aspx page from a site where I applied the custom masterpage that my custom search bar was gone and the default search bar was there. I was lost for a couple of hours yesterday figuring this one out.. I tried a couple of things :

  • Adding my custom masterpage to a feature, as insisted by a mate of mine, and then deploy it to all the sitecollections. Found a very interesting link to do this Feature to Install a Custom Master Page by Paul Papanek Stork . But unfortunately that didn't do the trick either..
  • Modifying the default.master page on filesystem level (to make sure that my masterpage was being used (this was a desperate attempt to make it work:)) and reghosting the sitecollections to make sure the masterpage was being used.
  • Put some random text in other placeholders to see whether my customized masterpage were applied or not..

And it did! It did? Yes! So no more pulling my hair out because I couldn't apply a custom masterpage.. it was my modification! It seemed that a Content PlaceHolder not only holds the content you put into but it also generates some controls itself and overrides everything you put there yourself! When I placed my custom HTML out of the placeholder I was visible instantly. So I applied the Visible="False" attribute:

 <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server" Visible="false">
                <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" Visible="false"/>
          </asp:ContentPlaceHolder>
             <table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
</table>

And there you have it :)

I found some very interesting things while googling about this matter and those are :

Another approach how to incorporate another search engine within SharePoint (instead of leading your users to another search site (which is not very userfriendly, so I'm gonna see whether I can use this approach as well))

 

Technorati tags: , , ,