mo.notono.us

Wednesday, July 25, 2007

MOSS: The importance of the Template Name attribute

Our client decided to change the name of their MOSS solution towards the end of our project, so I had the fun task of renaming visible instances of the old product name.

A relatively brief find and replace session later, I was trying to redeploy our site when I encountered the error

Failed to instantiate file "default.master" from module "DefaultMasterPage": Source path "default.master" not found. at Microsoft.SharePoint.Library.SPRequestInternalClass.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)

at Microsoft.SharePoint.Library.SPRequest.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)

As Bjarne L. Gram discovered, this was due to the fact that I had changed the name of my Template tag in the Webtemp***.xml file, so that it was no longer matching the folder name in {12-hive}\SiteTemplates.

Thanks to Bjarne for pointing this out; I added a comment to the MSDN documentation.

Labels: , , ,

Thursday, July 19, 2007

MOSS: Debugging

The debugging process in MOSS is challenging, to say the least, especially if your "development" mostly consists of modifying CAML in XML files.

Some tips:

  • Switch off Custom Errors and Enable Callstack; especially helpful if you are doing a lot of coding against the API
  • Minimize the number of changes between each deployment and test - SharePoint loves to throw "unknown error"s for the seemingly most minor issue, especially in ONET and Schema files, and tracking down just which change caused the issue is not easy
  • Recycle the app pool instead of doing an IISReset
  • Minimize the number of tedious manual actions for deployments of your changes by creating batch files to copy and paste files, etc.  Learn which files can be simply copied to the 12-hive to affect a change, and which require GACing, instantiation of new MOSS objects, etc.
  • Use the IE Developer Toolbar to make sense of the client-side code (html, IDs, styles, classes, JS, etc)
  • Check the log files at C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS.  These files may or may not be helpful.
  • Create your own logging/trace mechanism for your code to supplement the SharePoint logs.

Labels: , ,

Wednesday, July 18, 2007

MOSS: Site Column: LinkedTitleDocNoMenu

MOSS 2007 (and I believe SharePoint 2003 as well) has a number of built-in site columns for linking to the item or document in a list/document library, while displaying either the Name or the Title, with or without the Edit context menu.

Unfortunately, the exact combination that I needed is not provided: Display the Title field of a DocumentLibrary item, with a link to the document (not item property page), and do not display the context menu.

The CAML I came up with is listed below for future reference - it borrows heavily from LinkedFileNameNoMenu:

<Field ID="{4EB765CD-0750-46fc-9058-CFBAC553F82F}"
    Name="LinkTitleDocNoMenu"
    SourceID="http://schemas.microsoft.com/sharepoint/v3"
    StaticName="LinkTitleDocNoMenu"
    Group="AIS"
    ReadOnly="TRUE"
    Type="Computed"
    DisplayName="$Resources:core,Title;"
    DisplayNameSrcField="Title"
    Filterable="FALSE"
    AuthoringInfo="$Resources:core,linked_to_document;">
  <FieldRefs>
    <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"/>
    <FieldRef ID="{687c7f94-686a-42d3-9b67-2782eac4b4f8}" Name="FileLeafRef"/>
    <FieldRef ID="{30bb605f-5bae-48fe-b4e3-1f81d9772af9}" Name="FSObjType"/>
    <FieldRef ID="{94f89715-e097-4e8b-ba79-ea02aa8b7adb}" Name="FileRef"/>
    <FieldRef ID="{39360f11-34cf-4356-9945-25c44e68dade}" Name="File_x0020_Type"/>
    <FieldRef ID="{03e45e84-1992-4d42-9116-26f756012634}" Name="ContentTypeId"/>
  </FieldRefs>
  <DisplayPattern>
    <IfEqual>
      <Expr1>
        <LookupColumn Name="FSObjType"/>
      </Expr1>
      <Expr2>1</Expr2>
      <Then>
        <FieldSwitch>
          <Expr>
            <GetVar Name="RecursiveView"/>
          </Expr>
          <Case Value="1">
            <LookupColumn Name="FileLeafRef" HTMLEncode="TRUE"/>
          </Case>
          <Default>
            <SetVar Name="UnencodedFilterLink">
              <SetVar Name="RootFolder">
                <HTML>/</HTML>
                <LookupColumn Name="FileRef"/>
              </SetVar>
              <SetVar Name="FolderCTID">
                <FieldSwitch>
                  <Expr>
                    <ListProperty Select="EnableContentTypes"/>
                  </Expr>
                  <Case Value="1">
                    <Column Name="ContentTypeId"/>
                  </Case>
                </FieldSwitch>
              </SetVar>
              <FilterLink Default="" Paged="FALSE"/>
            </SetVar>
            <HTML><![CDATA[<A onfocus="OnLink(this)"  HREF="]]></HTML>
            <GetVar Name="UnencodedFilterLink" HTMLEncode="TRUE"/>
            <HTML><![CDATA[" onclick="javascript:EnterFolder(']]></HTML>
            <ScriptQuote NotAddingQuote="TRUE">
              <GetVar Name="UnencodedFilterLink"/>
            </ScriptQuote>
            <HTML><![CDATA[');javascript:return false;">]]></HTML>
            <Column Name="Title" HTMLEncode="TRUE"/>
            <HTML><![CDATA[</A>]]></HTML>
          </Default>
        </FieldSwitch>
      </Then>
      <Else>
        <HTML><![CDATA[<A onfocus="OnLink(this)" HREF="]]></HTML>
        <Field Name="EncodedAbsUrl"/>
        <HTML><![CDATA[" onclick="DispDocItemEx(this,']]></HTML>
        <ServerProperty Select="HtmlTransform"/>
        <HTML><![CDATA[',']]></HTML>
        <ServerProperty Select="HtmlTrAcceptType">
          <Column Name="File_x0020_Type"/>
        </ServerProperty>
        <HTML><![CDATA[',']]></HTML>
        <ServerProperty Select="HtmlTrHandleUrl">
          <Column Name="File_x0020_Type"/>
        </ServerProperty>
        <HTML><![CDATA[',']]></HTML>
        <ServerProperty Select="HtmlTrProgId">
          <Column Name="File_x0020_Type"/>
        </ServerProperty>
        <HTML><![CDATA[')">]]></HTML>
        <Column Name="Title" HTMLEncode="TRUE"/>
        <HTML><![CDATA[</A>]]></HTML>
        <IfNew>
          <HTML><![CDATA[<IMG SRC="/_layouts/[%=System.Threading.Thread.CurrentThread.CurrentUICulture.LCID%]/images/new.gif" alt="]]></HTML>
          <HTML>$Resources:core,new_gif_alttext</HTML>
          <HTML><![CDATA[">]]></HTML>
        </IfNew>
      </Else>
    </IfEqual>
  </DisplayPattern>
</Field>

YMMV, no support is offered...

Labels: , , ,

Wednesday, July 11, 2007

SQL: Efficiently Get Table Row Count

A quick and efficient way to get the row count of a table is to query the system table sysindexes

In order to get the rows of a single table called MyTable you can use the following SQL:

SELECT rows FROM sysindexes WHERE indid < 2 AND ID = OBJECT_ID('MyTable')

In order to get the rows of all tables, you can use this:

SELECT so.name, si.rows
FROM sysindexes si 
       INNER JOIN sysobjects so on si.id = so.id
WHERE si.indid < 2 
       AND so.xtype = 'U'
ORDER BY so.name

Labels: ,

SQL: Compare values or rows

In SQL, if you need to check if two values (or rows) are different, the BINARY_CHECKSUM function is very useful and fast:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ba-bz_1mi1.asp

Labels: ,

SQL: Does the object exist?

If you need to check if an object exists in the database, rather than querying an obscure system table, you can use the OBJECT_ID function.

If you want to verify that the table FooBar exists in the YadiYada database, simply write the following IF statement:

IF OBJECT_ID('YadiYada..FooBar') IS NOT NULL
BEGIN
--FooBar exists so you can use it here
--...
END

Labels: ,

Monday, July 02, 2007

DDF Command and Variable Syntax

DDF files as used in SharePoint to create Solution (WSP) files are an anachronistic throwback to an ancient Microsoft technology: CAB files.  Since CAB files predate the era of blogging, it is not particularly straightforward to find documentation on DDF files.

Unless you actually read the documentation provided by Microsoft, that is...  Relevant excerpts from the MakeCab.doc included in the Microsoft Cabinet Software Development Kit are included below:

"4.2.2. Command Summary

"The following table provides a summary of the MakeCAB Directive File syntax. Directives begin with a period (“.”), followed by a command name, and possibly by blank delimited arguments. Note that a File Copy command is distinguished from a File Reference command by the setting of the GenerateInf variable.  

Command Syntax

Description

;

Comment (anywhere on a DDF line)

src [dest] [/inf=yes|no] [/unique=yes|no] [/x=y ...]

File Copy command

dest  [/x=y ...]

File Reference command

.Define variable=[value]

Define variable to be equal to value (see .Option Explicit)

.Delete variable

Delete a variable definition

.Dump

Display all variable definitions

.InfBegin Disk | Cabinet | Folder

Copy lines to specified INF file section

.InfEnd

End an .InfBegin section

.InfWrite string

Write “string” to file section of INF file

.InfWriteCabinet string

Write “string” to cabinet section of INF file

.InfWriteDisk string

Write “string” to disk section of INF file

.New Disk | Cabinet | Folder

Start a new Disk, Cabinet, or Folder

.Option Explicit

Require .Define first time for user-defined variables

.Set variable=[value]

Set variable to be equal to value

%variable%

Substitute value of variable

<blank line>

Blank lines are ignored

"4.2.3. Variable Summary

Standard Variables

Description

Cabinet=ON | OFF

Turns Cabinet Mode on or off

CabinetFileCountThreshold=count

Threshold count of files per Cabinet

CabinetNamen=filename

Cabinet file name for cabinet number n

CabinetNameTemplate=template

Cabinet file name template; * is replaced by Cabinet number

ChecksumWidth=1 | 2 | ... | 8

Max low-order hex digits displayed by INF csum parameter

ClusterSize=bytesPerCluster

Cluster size on diskette (default is 512 bytes)

Compress=ON | OFF

Turns compression on or off

CompressedFileExtensionChar=char

Last character of the file extension for compressed files

CompressionType=MSZIP

Compression engine

DestinationDir=path

Default path for destination files (stored in cabinet file)

DiskDirectoryn=directory

Output directory name for disk n

DiskDirectoryTemplate=template

Output directory name template; * is replaced by disk number

DiskLabeln=label

Printed disk label name for disk n

DiskLabelTemplate=template

Printed disk label name template; * is replaced by disk number

DoNotCopyFiles= ON | OFF

Controls whether files are actually copied (ACME ADMIN.INF)

FolderFileCountThreshold=count

Threshold count of files per Folder

FolderSizeThreshold=size

Threshold folder size for current folder

GenerateInf=ON | OFF

Control Unified vs. Relation INF generation mode

InfXxx=string

Set default value for INF Parameter Xxx

InfCabinetHeader[n]=string

INF cabinet section header text

InfCabinetLineFormat[n]=format string

INF cabinet section detail line format

InfCommentString=string

INF comment string

InfDateFormat=yyyy-mm-dd | mm/dd/yy

INF date format

InfDiskHeader[n]=string

INF disk section header text

InfDiskLineFormat[n]=format string

INF disk section detail line format

InfFileHeader[n]=string

INF file section header text

InfFileLineFormat[n]=format string

INF file section detail line format

InfFileName=filename

Name of INF file

InfFooter[n]=string

INF footer text

InfHeader[n]=string

INF header text

InfSectionOrder=[D | C | F]*

INF section order (disk, cabinet, file)

MaxCabinetSize=size

Maximum cabinet file size for current cabinet

MaxDiskFileCount=count

Maximum count of files per Disk

MaxDiskSize[n]=size

Maximum disk size

MaxErrors=count

Maximum errors allowed before pass 1 terminates

ReservePerCabinetSize=size

Base amount of space to reserve for FCRESERVE data

ReservePerDataBlockSize=size

Amount of space to reserve in each data block

ReservePerFolderSize=size

Amount of additional space in FCRESERVE for each folder

RptFileName=filename

Name of RPT file

SourceDir=path

Default path for source files

UniqueFiles=ON | OFF

Control whether duplicate desintation file names are allowed

Details of selected commands and variables:

.Define variable=[value]

Define variable to be equal to value.

To use variable, surround it with percent signs (%) -- %variable%.

Using an undefined variable is an error, and will cause MakeCAB to stop before pass 2.

value may include references to other variables.

Leading and trailing blanks in value are discarded.

Blanks may be enclose in quote (“) or apostrophe (‘) marks.

Explicit percent signs (%), quotes (“), or apostrophes (‘) must be specified twice.

NOTE: If .Option Explicit is specified, then you must first use .Define to define any user-defined variables before you can use .Set to modify them. For standard MakeCAB variables, .Define is not permitted, and only .Set may be used on. If .Option Explicit is not specified, then .Define is equivalent to .Set.

.Set variable=value

Set variable to be equal to value.

To use variable, surround it with percent signs (%) -- %variable%.

Using an undefined variable is an error, and will cause MakeCAB to stop before pass 2.

value may include references to other variables.

value may be empty, in which case variable is set to the empty string.

Leading and trailing blanks in value are discarded.

Blanks may be enclose in quote (“) or apostrophe (‘) marks.

Explicit percent signs (%), quotes (“), or apostrophes (‘) must be specified twice.

NOTE: If .Option Explicit is specified, then you must first use .Define to define any user-defined variables before you can use .Set to modify them. For standard MakeCAB variables, .Define is not permitted, and only .Set may be used on.

DestinationDir=path

Path prefix to store in cabinet file for each file in the cabinet.

Default: .Set DestinationDir= ; Default is no path prefix

path is concatenated with a path separator (“\”) and the target file name on File Copy Commands to produce the file name that is stored in cabinet file. EXTRACT.EXE will use this file name as the default name when the file is extracted.

SourceDir=path

The default path used to locate source files specified in File Copy Commands.

Default: .Set SourceDir= ; Default is to look in the current directory

path is concatenated with a path separator (“\”) and the source file name on the File Copy Command to produce the file name used to find the source file.

If path is empty, then the source file name specified on the File Copy Command is not modified.

UniqueFiles=ON | OFF

Controls whether destination file names in a layout must be unique..

Default: .Set UniqueFiles="ON" ; File names must be unique

If UniqueFiles is ON, MakeCAB checks that all destination file names (names stored on disks or in cabinets) are unique, and generates an error (during pass 1) if they are not. ON is the default, since using the same filename twice usually means that the same file was accidentaly included twice, and this would be a waste of disk space.

If UniqueFiles is OFF, MakeCAB permits duplicate destination file names.

The /UNIQUE parameter may be specified on individual File Copy commands to override the value of UniqueFiles.

Labels: , , ,

Sunday, July 01, 2007

Links for 2007-06-30 [del.icio.us]

Link - Sun, 01 Jul 2007 01:00:00 GMT - Feed (1 subs)

Sent using Rmail R|mail.

Labels: