The relationship between SCHEMA.XML and the ASPX/HTM files in the list definition is akin to ASPX's code-behind concept. SCHEMA.XML should be thought of as the code-behind, whereas ASPX and HTM files represent the presentation code. In fact, the web part zone in the ASPX page and a web part zone-like component in the HTM file are the receptacles for SCHEMA.XML's CAML execution. As mentioned previously, ONET.XML overlaps SCHEMA.XML's functionality in some places. In these cases, ONET.XML's settings will override SCHEMA.XML, or vice versa. You therefore need to be aware of these nuances when modifying list definitions and should check both files if the list does not appear as you feel it should. The structure of SCHEMA.XML is shown in Listing 3.1. The major elements are List, Fields, Views, Forms, DefaultDescription, and Toolbar. Listing 3.1. SCHEMA.XML Structure
<List>: Top-Level List Definition SettingsList provides some top-level settings. Many of the List attributes were covered in Table 2.9 during our discussions of ONET.XML. In this section, we will expand on our discussion of the List element. Listing 3.2 shows the default List element for a document library in the STS site definition. As previously mentioned, if these same attributes are specified in ONET.XML, they can take precedence over those specified within SCHEMA.XML. Listing 3.2. SCHEMA.XML Document Library List Element Declaration
If our site definition includes the code from Listing 3.2 and Listing 3.3, the values of Title and Url specified in ONET.XML will be used over those specified in SCHEMA.XML. Listing 3.3. ONET.XML Configuration for Team Site
The BaseType attribute specified in the List element refers to a particular base type defined within ONET.XML. Recall that the base types specify a base schema (columns) for the list types. This base schema can be developed once and then applied to the various list types as appropriate. For example, the BaseType of 1 is applied document libraries, picture libraries, and form libraries. Configuring Event HandlersSome of the more powerful list customizations for document, picture, and form libraries are event sinks. With event sinks, your custom code can hook into SharePoint library eventscheck in, check out, and so on. Event sinks only apply to libraries and do not apply to other types of lists. It should be noted that these events are fired after the operation is performed. For example, the delete event is fired after a document is deleted from a document library. The next version of SharePoint will feature events that fire before the operation is performed. However, if you cannot wait until the next version of SharePoint, you might want to consider writing your own HTTP Module to act on requests immediately before SharePoint acts on them. Assuming you have enabled event handlers for your Virtual Server (see Figure 3.7), SharePoint can pass the document library events to a specified EventSinkAssembly and EventSinkClass. Additionally, you can specify EventSinkData that will be passed with the event information to the specified assembly and class. This capability is useful if you have one generic assembly responding to events from various sources. Your event handler can therefore react appropriately to the event depending on what the associated EventSinkData is passed to the handler. Because you can attach only one assembly to each document library in this version of SharePoint, creating a generic assembly to respond to events from different libraries is a good practice to follow. Figure 3.7. Virtual Server General Settings with Event Handlers enabled.Figure 3.8 shows the advanced settings of a document library. The Advanced Settings page is where you can manually specify a custom event handler through the web user interface. Alternatively, you could use the List element's EventSinkAssembly, EventSinkClass, and EventSinkData attributes within the site definition's ONET.XML to avoid this manual task. Configuring event handlers in a library can be incredibly useful. One scenario underscoring their usefulness would be processing newly uploaded documents in a document library. For instance, a newly uploaded Excel file could be processed to extract data to update an enterprise application. The page in Figure 3.8 is also where a Microsoft Exchange public folder can be specified. If specified, SharePoint will download its content into the SharePoint document library. Site definitions provide no way to bind a library with an Exchange public folder. However, this does not preclude writing code that interacts with the SharePoint API to configure this setting. This code could be embedded within NEW.ASPX and run immediately after a document library was created. Figure 3.8. Document Library Advanced Settings.<Fields>: Defining Additional Columns over the Base TypeThe Fields element can define list columns and can define how a list is rendered. In the former case, we use the Fields element to add additional fields to what was defined by the base list type. In the latter case, the Fields element is embedded within the Views and Forms elements along with quite a bit of other CAML. In Listing 3.4, we examine defining the Title and Expiration Date fields in our document library through the Fields element. Title is a holdover from the SCHEMA.XML taken from the STS site definition. Expiration Date is something we will be adding to our MyFirstSiteDefinition site definition. It represents a date at which the document content is considered stale and therefore out of date. Listing 3.4. SCHEMA.XML Adding Fields to a Document Library
Because we do not want the ExpirationDate element to be removed, we have set the Sealed attribute to TRUE. The effects are shown in Figure 3.9. As you can see from the figure, sealing the field restricts more than the option to delete the column. The data type, data type formatting, default value, and whether it is required are also inaccessible to the user. Figure 3.9. FLDEDIT.ASPX Expiration Date as a sealed column.We have also set the ShowInNewForm, ShowInFileDlg, and Required attributes to trUE. ShowInNewForm specifies whether the field should show up in UPLOAD.ASPX. As shown in Figure 3.10, ShowInNewForm for Expiration Date was set to true, whereas for Title, it was set to false. In contrast, ShowInFileDlg specifies whether the field should show up in EDITDLG.HTM (refer to Figure 3.5), which is accessible from Microsoft Office applications. The Required attribute forces a user to select a non-blank value for that column. The caveat is that this constraint is not enforced when a file is uploaded through the Explorer View. In that case, there is no facility to specify a value, and it will be set to null. Figure 3.10. UPLOAD.ASPX Expiration Date as a required column.A default value of three years from today was set for the ExpirationDate column. This was done through the DefaultFormula element. We used the functions defined within the Formulas and Functions section of SharePoint's online helpwhich is shown in Figure 3.11. It is interesting to note that these functions are not explicitly defined within the SharePoint CHM help file. Figure 3.11. SharePoint Help on Functions.
Although we have touched on a number of Field attributes, we have merely scratched the surface of its capabilities. The complete list of Field's attributes are summarized in Table 3.2.
<Fields>: Advanced ConceptsIn the previous section, we concentrated our efforts on a simple exampleadding a document expiration field to a document library. In this section, we explain the Fields element's link to the database. Ultimately the individual list fields are stored in the database. The primary table where list items are stored is UserData, which is found in every content database. Additional list items can be retrieved from other database tables through database joins. Listing 3.5 showcases some of these joins to other tables. Listing 3.5. ONET.XML Document Library Base Type Definition
The entire document library base type is defined within ONET.XML. Listing 3.5 defines only the top portion of this definition. This base type retrieves information from the UserData, UserInfo, and Docs database tables. The first bold field definition in Listing 3.5 defines the approval status. The ColName attribute specifies that the column will be stored in the tp_ModerationStatus database column. The lack of a List attribute implies that its value will reside in the UserData database table. Furthermore, the three choicesApproved, Rejected, and Pendingwill be serialized as 0, 1, and 2, respectively. tp_ModerationStatus has a data type of int, so saving these values as anything other than an integer is not acceptable. If a column name is not specified, SharePoint will choose one for you. The second bold field definition in Listing 3.5 defines the file size (File_x0020_Size). This definition is a bit more complicated. The field's value is defined in the Docs table and not UserData, Furthermore, the size data retrieved from the Docs table is further computed (see Listing 3.6) to return the size in kilobytes. The file size field references the Docs table through the List attribute. The field also defines an inner join where Docs.DoclibRowId equals UserData.tp_ID. Docs.Size is selected from the resulting join and returned as the field's value. It was the computation that we alluded to previously that helped map ID to tp_ID and SizeInKB to Size (see Listing 3.6). This translation needs to happen because the FieldRef and Show-Field attributes reference other field definitions. Let's first search for the ID field defined by FieldRef. This ID field is the first field element defined earlier in Listing 3.5. As specified in its definition, it maps to the tp_ID database field in UserData. The definition for SizeInKB can be found in BASE.XML located in the C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\1033\XML folder (assuming your LCID is 1033). The kilobyte size field definition is bolded in Listing 3.6. This translation specifies a database column of Size and a scaling division factor of 1024. Thus, DOCS.Size will be retrieved and divided by 1024. Furthermore, the user will see this value with a friendly column name of File Size. Listing 3.6. BASE.XML Docs Database Table Mapping
<Views>: Defining List ViewsThe Views element defines the initial views for the list. You are no doubt familiar with the All Documents and Explorer views of a document library. These, along with three other views, are defined within SCHEMA.XML for the standard document library. You might recall that in Table 2.12, we enumerated the attributes of the View element. The View element is the only child element allowed for Views. In Listing 3.7, we show the top-level nodes of all the views within a document library. Unfortunately, the View definitions are quite large and therefore difficult to dissect in detail. For example, the view definition for ALLITEMS.ASPX spans approximately 1,500 lines. Listing 3.7. SCHEMA.XML Document Library Views Structure
By looking at the Path and Url attributes, you have probably surmised that the View with a BaseViewID of 1 maps to the All Document view, the one with a BaseViewID of 2 maps to the dialog rendered from Microsoft Office, as shown previously in Figure 3.4, and finally the BaseViewID of 3 maps to the Explorer view. You've probably also noticed the references to web part zones in these three views. They are rendered within a web part zone on the Url or Path specified page. This means that anything outside of this web part zone is not modifiable through SCHEMA.XML. In these cases, the ASPX or HTM page must be modified. Creating an Additional ViewOur emphasis in this section will be adding an additional view based on the All Documents view. This view will be entitled Expired Documents. So now you are probably rolling your eyes and saying, "These views are 1,500+ lines long, and you want me to create one?" Well, it actually is much simpler than it sounds. We can recycle almost everything from the All Documents view and tweak the rest. Alternatively, we could design a custom list template and capture the appropriate CAML code from MANIFEST.XML. Of course you could painstakingly look up all the CAML elements instead of generating a custom list template. However, it is generally far easier to recycle code from MANIFEST.XML. Let's start by designing our custom list template. Because the Expired Documents view requires an ExpirationDate column, we will create one. We need not give it all the properties that our ExpirationDate column in Listing 3.4 defined. The column need only be based on a Date and Time type and could look as simple as Figure 3.12. Figure 3.12. Expiration Date created within a custom list template.Next, create a standard view for the Expired Documents and fill it out as shown in Figure 3.13. You will need to specify the view name, the sort order, the group by column, the filter, and enable showing documents without folders. Figure 3.13. Expired Documents view settings.As we outlined in Chapter 1, "Custom Templates," save the custom document template to your local drive and examine its MANIFEST.XML file. Search for the View element that defines our newly created Expired Documents view. It should look similar to Listing 3.8. Listing 3.8. MANIFEST.XML Expired Documents View Partial Listing
From MANIFEST.XML, select the entire View definition (1,500 or so lines) for Expired Documents and then copy it to our SCHEMA.XML. It should be inserted into SCHEMA.XML so that the Views element is its parent. From a best practice standpoint, it should be inserted as the last View definition within Views. However, its placement within the Views element has no effect on its function. The ViewFields element defines the fields that will be displayed in the view and was generated from the Columns section specified in Figure 3.13. The GroupBy, OrderBy, and Where CAML elements map to the Group By, Sort, and Filter sections of the same figure. Furthermore, the View's Scope attribute corresponds to the Folders section of that same figure. As mentioned previously, we could have copied the All Documents view definition in SCHEMA.XML and modified the CAML by hand, and we would have achieved the same result. One benefit of harvesting CAML for View definitions, Field definitions, or just about anything else with a list template is that you can usually skip a significant amount of debugging that you might have to perform if done by hand. The next step is modifying the recently copied View node. You will need to remove the Name attribute, add a WebPartZoneID reference, and modify the Url and BaseViewID. These changes are represented in Listing 3.9. Listing 3.9. Updated View after Inserting It into SCHEMA.XML
The final configuration piece is to make a copy of ALLITEMS.ASPX and name it ExpiredDocuments.ASPX. This additional file is shown in Figure 3.14. Figure 3.14. ExpiredDocuments.ASPX file added to list definition.The result of our work is shown in Figure 3.15. We could have added any number of additional views, modified the existing views, or removed some of the views. However, because there are several external references (links) to some of these views, you will need to remove default viewssuch as All Documents and Explorer viewswith care. Figure 3.15. Expired Documents view.When we added our view, we selected a BaseViewID of 100 so that it was different from the other BaseViewID values. Every view must have a unique BaseViewID. Furthermore, the BaseViewID defines the view's placement order on the left navigation bar shown in Figure 3.15. The view with the lowest BaseViewID will be placed at the top, whereas the view with the highest BaseViewID will be placed at the bottom of the left navigation bar. Common <View> Child ElementsTable 3.3 enumerates some of the more popular child elements of View. In the previous section, we designed a view from SharePoint's web user interface and then harvested its CAML code through a list template. The web user interface only controls Aggregations, Query, RowLimit, and ViewStyle. Greater control of views can be achieved with the additional child View elements in Table 3.3.
The two most commonly used View child elements are Aggregations and Query. Aggregations specifies how the items of a view should be calculated. Query provides a mechanism for filtering, sorting, and grouping a view. AggregationsThe Aggregations element specifies how items in the view should be calculated. The results of this calculation are typically shown in a header row. An example of Aggregations use is shown in Listing 3.10. In our example, we are counting the number of times the LinkFilename is used. Listing 3.10. Aggregations Example in SCHEMA.XML
As shown in Figure 3.16, we build on Listing 3.8 with Listing 3.10 to count the number of times LinkFilename is used per grouping along with the total number of times for the list. The practical effect is to count the number of items (rows) in the grouping and the number of items in the list. We could have just as easily specified another column instead of LinkFilename. Figure 3.16. Expired Documents view with Aggregations specified.Although only one column is aggregated in the example, you can aggregate any combination of the columns that are present in the view. Furthermore, each column could have a different aggregation type. Those include average, maximum, minimum, summation, standard deviation, and variation. Obviously, these functions lend themselves better to numeric data types than string data types. QueryThe Query element defines the filtering, sorting, and grouping for a view. The valid child elements for Query include GroupBy, OrderBy, and Where. Although GroupBy and OrderBy will never have descendants past children, there is virtually no limit to the number of descendants that Where can have. Recall that the query for creating our Expired Documents view is shown in Listing 3.8. In that query, we leveraged GroupBy for grouping, OrderBy for sorting, and Where for filtering. As expected, GroupBy and OrderBy only have child elements, but Where has great-grandchildren descendants. The descendants for Where could exist well beyond great-grandchildren when using a logical AND or a logical OR. All the valid child elements of Where are shown in Table 3.4.
Listing 3.11 details an example Where clause that showcases the level of granularity that can be defined with the And and Or elements. The clause is equivalent to (State='Florida' AND City='Miami') AND (Building-Color='Black' OR BuildingColor='Gray'). Listing 3.11. CAML Where Clause Example
<Forms>: Interacting with One Item at a TimeViews are designed to show multiple items from the list. In contrast, forms are designed for just one item. For instance, displaying the properties of an item (DISPFORM.ASPX), editing the properties of an item (EDITFORM.ASPX and EDITDLG.HTM), and the information collected to upload a file to a document library (UPLOAD.ASPX) are all defined within the Forms section of SCHEMA.XML. The basic structure of forms within a document library is shown in Listing 3.12. Listing 3.12. Basic Forms Structure in a Document Library
Table 3.5 details the allowable child elements of Form. To be clear, the content in ListFormOpening, ListFormButtons, ListFormBody and ListFormClosing is not shown in the listing. The form definitions approximate the length of the view definitions and both weigh-in at about 1,500 lines.
<DefaultDescription> ElementThe two remaining top-level elements in SCHEMA.XML are Default-Description and Toolbar. DefaultDescription defines a description for the document library, and Toolbar defines a navigation bar. Listing 3.13 details the default description within SCHEMA.XML for a document library. Listing 3.13. Document Library Description Defined in SCHEMA.XML
The effects of this description are shown in Figure 3.17 immediately above the toolbar. Figure 3.17. Document library using the default description.Keep in mind that this default description will only be used when the list is created as part of the site definition. When a new list is created in an existing site, the user is prompted for the description (see Figure 3.18). In this scenario, the default description will be blank and will not be pre-populated with the one specified in the site definition. Figure 3.18. Prompting for description when creating a new document library.<Toolbar> ElementThe Toolbar element defines a block of HTML. Typically this HTML renders a toolbar, but it is not a requirement. In fact, the Toolbar element shown in Listing 3.14 does not render a toolbar. It renders the view's Actions items (Alert me, Export to spreadsheet, Modify settings and columns) on the left bar shown in Figure 3.17. Listing 3.14. RelatedTasks Toolbar Defined in SCHEMA.XML
The RelatedTasks toolbar defined in Listing 3.14 is referenced in the ALLITEMS.ASPX page. As shown in Listing 3.15, the SharePoint:RelatedTasks server control renders the toolbar's CAML code. Also shown in the listing is the SharePoint:ViewSelector server control. This renders a list of links to all the appropriate views defined within SCHEMA.XML. Listing 3.15. Left Navigation from ALLITEMS.ASPX
|