Sei sulla pagina 1di 555

Sitefinity 5

by the Falafel Sitefinity Team

Welcome to Sitefinity 5 We hope you enjoy the book as much as we, at Falafel Software, enjoyed creating it.

Sitefinity 5
2012 Falafel Software
All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic, electronic, or mechanical, including photocopying, recording, taping, or information storage and retrieval systems - without the written permission of the publisher. Products that are referred to in this document may be either trademarks and/or registered trademarks of the respective owners. The publisher and the author make no claim to these trademarks. While every precaution has been taken in the preparation of this document, the publisher and the author assume no responsibility for errors or omissions, or for damages resulting from the use of information contained in this document or from the use of programs and source code that may accompany it. In no event shall the publisher and the author be liable for any loss of profit or any other commercial damage caused or alleged to have been caused directly or indirectly by this document. Printed: April 2012

Publisher Falafel Software Inc. Falafel Sitefinity Team Noel Rice Basem Emara Alain "Lino" Tadros Bary Nusz Gary Campbell Scott Frolich Matt Kurvin Technical Editors Basem Emara George Saddeh Alain "Lino" Tadros Cover Designer Matt Kurvin Team Coordinator Alain "Lino" Tadros Administration Sean Samuel Production Falafel Software Inc.

Special thanks to: All the team members at Telerik worldwide for creating a magnificant piece of software in Sitefinity. The authors also would like to thank the Falafel team members in Colorado, Texas, Michigan, N. Carolina, Canada, Lebanon and California for their feedback and recommendations on the subjects of the manual. Also the team would like to thank the following members of the Telerik Sitefinity team for their hard work and continuous support: Gabe Sumner Ivan Dimitrov Georgi Chokov Steve Miller Ivan Osmak Boyan Rabchev Anton Hristov Josh Morales Hristo Borisov Radoslav Georgiev Lidiya Petkova Slavo Ingilizov Stanislav Velikov Vassil Terziev

Sitefinity 5

Table of Contents
1 Introduction 2

What .......................................................................................... You Need to Know Before Reading This Courseware 2 What Do You Need to Have Before Reading This Courseware .......................................................................................... 3 How .......................................................................................... This Courseware is Organized 4 What .......................................................................................... is a CMS and why do you need one? 7 Sitefinity .......................................................................................... 3.7 vs. 5.x 8

2 Setting Up Your Environment

10

Objectives .......................................................................................... 10 Installing .......................................................................................... Sitefinity 5 11 Installing .......................................................................................... the SDK 14 Summary .......................................................................................... 17

3 Getting Started

19

Objectives .......................................................................................... 19 Sitefinity .......................................................................................... Project Manager 20 Dashboard .......................................................................................... 22 About .......................................................................................... Pages and Content 23 Front .......................................................................................... End vs. Back End 24 Creating .......................................................................................... Projects 25 Summary .......................................................................................... 40

4 Pages

42

Objectives .......................................................................................... 43 Page .......................................................................................... Settings 44

2012 Falafel Software

Contents

Editing .......................................................................................... the Page 51 Tour .......................................................................................... of Page Administration 77 Summary .......................................................................................... 82

5 Content

84

Objectives .......................................................................................... 85 Tour .......................................................................................... of the Content Menu 86 Content .......................................................................................... Block 87 News .......................................................................................... 94 .......................................................................................... Events 101 .......................................................................................... Images and Albums 106 .......................................................................................... Video 118 .......................................................................................... Lists 127 .......................................................................................... Blogs 132 .......................................................................................... Documents 145 .......................................................................................... Forms 153 .......................................................................................... Social Sharing Options 162 .......................................................................................... Summary 164

6 Permissions

166

.......................................................................................... Objectives 167 .......................................................................................... Built-In Roles 168 .......................................................................................... Creating a Role 169 .......................................................................................... Creating a User 171 .......................................................................................... Test the New User 173 .......................................................................................... Summary 174

7 Workflow

176

.......................................................................................... Objectives 177 .......................................................................................... Defining a Workflow 178


2012 Falafel Software

Sitefinity 5

.......................................................................................... Testing the Workflow 183 .......................................................................................... Summary 184

8 Analytics

186

.......................................................................................... Objectives 187 .......................................................................................... Setup 188 .......................................................................................... Using Analytics in the Administrator 191 .......................................................................................... Summary 194

9 Widget Templates

196

.......................................................................................... Objectives 197 .......................................................................................... Accessing Widget Templates 198 .......................................................................................... Changing a Template 199 .......................................................................................... Creating a New Template 202 .......................................................................................... Managing Widget Templates 204 .......................................................................................... Summary 205

10 Page Templates

207

.......................................................................................... Objectives 208 .......................................................................................... Creating and Using a Page Template 209 .......................................................................................... Stying 221 .......................................................................................... Debugging CSS 225 .......................................................................................... Summary 229

11 Responsive Web Design

231

.......................................................................................... Objectives 232 .......................................................................................... Creating Rules 233 .......................................................................................... Previewing the Results 236 .......................................................................................... Device Characteristics 237 .......................................................................................... Adding New Behaviors 239
2012 Falafel Software

Contents

.......................................................................................... Summary 242

12 Working with Master Pages

244

.......................................................................................... Objectives 245 .......................................................................................... Masterpage Overview 246 .......................................................................................... Using a MasterPage from the Marketplace 247 .......................................................................................... Editing 3rd Party Templates 256 .......................................................................................... Master Page Surgery Tips 265 .......................................................................................... Summary 269

13 Developing in Sitefinity

271

.......................................................................................... Objectives 272 .......................................................................................... What Flavor API? 273 .......................................................................................... Getting Started with Sitefinity Development 274 .......................................................................................... Sitefinity Projects in Visual Studio 278 .......................................................................................... Developing with Thunder 280 .......................................................................................... Summary 281

14 Using the Sitefinity API

283

.......................................................................................... Objectives 284 .......................................................................................... Working with Pages 285 .......................................................................................... Working with Content Items 291 .......................................................................................... Publishing 297 .......................................................................................... Summary 298

15 Authentication and Security

300

.......................................................................................... Objectives 301 .......................................................................................... Claims vs Forms Authentication 302 .......................................................................................... Setting the Authentication Type 303 .......................................................................................... Login Programmatically 304
2012 Falafel Software

Sitefinity 5

.......................................................................................... Logout Programmatically 306 .......................................................................................... Create a User 307 .......................................................................................... Roles and Permissions 308 .......................................................................................... Summary 311

16 Using the Fluent API

313

.......................................................................................... Objectives 314 .......................................................................................... Fluent API Facades 315 .......................................................................................... Working with Pages 316 .......................................................................................... Working with Content Items 319 .......................................................................................... Summary 337

17 Working with Forms

339

.......................................................................................... Objectives 340 .......................................................................................... Getting a List of All Forms 341 .......................................................................................... Retrieve a Single Form 343 .......................................................................................... Retrieving Form Entry Values 344 .......................................................................................... Summary 349

18 Localization

351

.......................................................................................... Objectives 352 .......................................................................................... Localizing Front End Pages 353 .......................................................................................... User Language Selection 360 .......................................................................................... Localizing In Code 362 .......................................................................................... Localizable Strings 363 .......................................................................................... Localizing Back End Pages 364 .......................................................................................... Summary 367

19 Working with Widgets

369

.......................................................................................... Objectives 370


2012 Falafel Software

Contents

.......................................................................................... User Controls 371 .......................................................................................... Custom Controls 382 .......................................................................................... Custom Control Designers 394 .......................................................................................... Using RadControls for ASP.NET AJAX with Sitefinity 408 .......................................................................................... Silverlight Controls 410 .......................................................................................... Communication between Custom Control and Silverlight 418 .......................................................................................... Custom Form Controls 427 .......................................................................................... Summary 439

20 Working with Modules

441

.......................................................................................... Objectives 442 .......................................................................................... Create a Custom Module 443 .......................................................................................... Add Module Content 450 .......................................................................................... Customizing the Backend Grid 452 .......................................................................................... Add the Module to a Page 455 .......................................................................................... Working with the Module in Code 458 .......................................................................................... Summary 462

21 Sitefinity Web Services

464

.......................................................................................... Objectives 465 .......................................................................................... Getting Available Services and Methods 466 .......................................................................................... Anatomy of a Web Service Call 470 .......................................................................................... Using Claims Authentication 471 .......................................................................................... Using Forms Authentication 486 .......................................................................................... What Next? 495 .......................................................................................... Summary 496

22 Content Classification - Taxonomy

498

.......................................................................................... Objectives 499 .......................................................................................... Terminology 500


2012 Falafel Software

10

Sitefinity 5

.......................................................................................... Getting Started 501 .......................................................................................... Listing Taxonomies 502 .......................................................................................... Listing Taxa 503 .......................................................................................... Finding Frequently Used Categories and Tags 504 .......................................................................................... Get Items by Category or Tag 506 .......................................................................................... Adding Categories and Tags 509 .......................................................................................... Summary 510

23 Dynamic Data

512

.......................................................................................... Objectives 513 .......................................................................................... Adding Custom Fields 514 .......................................................................................... Using the DynamicData Facade 520 .......................................................................................... Programmatically Listing Types 521 .......................................................................................... Programmatically Listing Fields 523 .......................................................................................... Reading and Writing Custom Field Values 528 .......................................................................................... Summary 529

24 About Falafel

531

.......................................................................................... Support and Services 532

Index

537

2012 Falafel Software

1
Introduction

Sitefinity 5

Introduction
What You Need to Know Before Reading This Courseware
This Courseware first demonstrates how to be productive right away using Sitefinity in a business environment, progresses to administrative and designer tasks and finishes up with details on developing for Sitefinity. Depending on your use of Sitefinity, different parts of the book will be useful to you. Business Users: If you want to create web content but have no interest in web site

administration or fiddling with technical details.


Designers and Administrators: If you are responsible for the installation and setup of new

web site projects, configuration and management of users.


Developers: If you need to programmatic control over Sitefinity websites or widgets, need to adapt Sitefinity to include features that dont exist out-of-the-box or need to access data contained in your Sitefinity website or feed data to your website.

2012 Falafel Software

Introduction

What Do You Need to Have Before Reading This Courseware


Server Side
Microsoft Windows Server 2003, 2008, Windows XP [1] Windows Vista, Windows 7 Internet Information Services 6+[2] Microsoft .NET Framework 4.0

Database
Microsoft SQL Express 2005 2008 Microsoft SQL Server 2005, 2008

Supported Browsers
Internet Explorer 7+ Firefox 3.6 + JavaScript must be enabled on all browsers Silverlight 4 plug-in must be installed on all users' browsers

Tip!

In practice, Chrome, Opera and Safari also work well with Sitefinity. Business users may want to use Chrome, currently the fastest browser on the market. Firefox can be used for any testing and debugging by web designers and developers. You may need to use Internet Explorer based on business needs.

*http://www.sitefinity.com/a sp-net-cms-fea tures/systems-requirements.a spx NOTE 1: You ca n run Sitefinity with Windows XP, only when using the Sitefinity integra ted web server. NOTE 2: It is not required to use IIS. If you wa nt to use IIS, you must configure it for Silverlight Applica tion. For more informa tion, see Configuring IIS for Silverlight a pplica tion below. NOTE 3: If you a re using Windows XP or Windows Server 2003 ma ke sure you ha ve upda ted your Windows Insta ller to version 4.5.

2012 Falafel Software

Sitefinity 5

How This Courseware is Organized


Setting Up Your Environment
This Chapter covers the basic installation of Sitefinity.

Getting Started
In this Chapter you will create a minimal, simple Sitefinity website. The website will contain a single "Welcome" page populated with text.

Pages
This chapter explains the options for creating and configuring a page. Then you'll learn how to edit page content and layout, paying particular attention to working with the HTML Editor. A tour of the page administration explores the list of pages and the possible Actions you can take, filtering and managing pages.

Content
This chapter tours the Content Menu and demonstrates how to work with each type of content. You'll learn how to create content, how to use widgets to display content in a page and how to configure the widget to fine-tune the layout and behavior of the content.

Permissions
This chapter explains how the built-in roles are used, how to create a role, how to create a user and how to assign roles to users.

Workflow
In this chapter you'll learn how to define and test a workflow.

Analytics
In this chapter you will learn how to setup Analytics. A brief survey of the Analytics interface will show you the kinds of web traffic information you can generate and analyze.

Widget Templates
This chapter demonstrates where you can access widget templates, how to edit the template markup, how to create your own custom templates and how to work with the Administration menu Widget Templates option.

2012 Falafel Software

Introduction

Page Templates
In this chapter you'll learn use page templates to establish a basic layout and content across multiple pages. You will add styles to the page template using both the CSS widget and using ASP.NET Themes. Finally, you'll learn how to debug CSS issues.

Responsive Web Design


In this chapter you'll learn how Responsive Web Design helps your application react to device sizes ranging from full-sized desktop or notebook screens to the smallest of handheld devices. You'll learn how to define rules that react to different screen configurations, how to make basic layout changes based on those configurations and how to fine tune all aspects of the page using styles.

Working with Master Pages


In this chapter you'll learn how Master pages work together with the page template and theme. You'll see how to use a Master page from the marketplace and how to "slice-anddice" third party templates to integrate them in your web site.

Developing in Sitefinity
In this chapter you will learn the basics for getting started with Sitefinity development. You'll learn what basic flavors of the API are available to you and how to work with the API in Visual Studio.

Using the Sitefinity API


This chapter explains how to work with the Sitefinity API. First you'll learn how to create a Sitefinity page programmatically and then how to display the hierarchy of pages in a tree view. You'll also create content programmatically and perform CRUD (Create Read Update Delete) operations against content items. Finally, you will add a programmatically created content item to a page, on-the-fly.

Using the Fluent API


This chapter demonstrates how the Fluent API works with pages and content items. You will learn how to upload images and documents. In particular, you will use a web service to load images to an Album en-masse. Finally, you will use the Fluent API to return lists of content items, filter, sort and select content items into useful subsets and then bind your results to ASP.NET controls.

2012 Falafel Software

Sitefinity 5

Working with Forms


This chapter explains how to programmatically retrieve forms and form items. This chapter will also discuss how to get at the form entry column names and captions.

Localization
In this chapter you will learn how to localize front end pages using Sitefinity Administration, how to localize strings in code, how to localize back end pages and how to use the Interface Labels & Messages page.

Working with Widgets


This chapter steps you through how to create user and custom controls available from the toolbox and usable within the page. You will also learn how to create designers for custom controls to assist your users in configuring the control. You will use a RadControls "RadComboBox" and "RadGrid" inside your page as well as perform CRUD operations against live data. You will see how to integrate a Silverlight control and how to make the Silverlight control and page communicate. Finally, you will create a custom form control.

Working with Modules


In this chapter you will work with modules to handle custom data. You will learn how to create a custom module, add content to the module and add the module widget to a page to view the data. You will also learn how to customize the backend table of module data.

Sitefinity Web Services


This chapter demonstrates how to work with both Forms Authentication and, the new default, Claims Authentication. This chapter first shows how to get all the available web services and method calls. You will learn the basic steps in common with all web service method calls, how to log in and log out of Sitefinity from a web service and how to retrieve and parse information from a web service call.

Content Classification - Taxonomy


This chapter introduces the basic terminology for Taxonomies and shows how to traverse hierarchies of taxonomies and taxa. You'll learn about how to get statistics for a taxon, retrieve items by a category or tag and how to programmatically add categories and tags.

Dynamic Data
In this chapter you'll learn how to add a new custom field to a content item from the Sitefinity back end. Then you'll use the DynamicData facade to programmatically list types and fields. Finally, you'll learn how to read and write custom field values.

2012 Falafel Software

Introduction

What is a CMS and why do you need one?


A Content Management System (CMS) allows multiple people to contribute website content from any location. Before CMS, one person received email with web change requests, managed all the code and recompiled the entire site for each change. Even the graphic web designer, who made changes continually, had to send email to that one person. That one person was the bottleneck. What about business users? Each business group (marketing, accounting, sales, etc.) wants to own their particular area without the bother of sending a ticket to an IT department and waiting for the ticket to be received and processed. CMS lets you split up the work for the web site and store the results in a single database or file system. Web designers can completely change website look-and-feel without having to know anything about content. Business users can create news, events and blogs and completely ignore how their content is presented. CMS "workflow" allows documents to be approved or rejected before being published, e.g. accounting makes their own changes and submits for approval while a manager verifies that numbers being published to the outside world do not conflict with company policies. While Sitefinity makes it easy to set up the initial website, you must think about maintaining and extending the website later for new capabilities. You can maintain Sitefinity content in one place and reuse the content everywhere. Maintenance is largely a matter of point-and-click, drag-and-drop. Sitefinity is completely extensible so that developers can integrate with 3rd party packages (e.g. Salesforce), add new custom widgets and modules.

2012 Falafel Software

Sitefinity 5

Sitefinity 3.7 vs. 5.x


Sitefinity was created based on Telerik's internal need for content management of their own website. Now thousands of companies use the product. Along the way, Telerik learned about the real world needs for the product. Sitefinity 5 is very different from Sitefinity 3.7. In fact, you might consider Sitefinity 5 a brand new product with a new background database and excellent new architectural underpinnings. One key Sitefinity 5 architecture change is the extensive use of AJAX technology to speed up administration page refreshes. In Sitefinity 3.7 , you had to wait for the entire page to refresh. In Sitefinity 5.0, AJAX technology allows a small request to the server and only a small part of the page is refreshed.

2012 Falafel Software

2
Setting Up Your Environment

10

Sitefinity 5

Setting Up Your Environment


Objectives
This Chapter covers the basic installation of Sitefinity.

2012 Falafel Software

Setting Up Your Environment

11

Installing Sitefinity 5
Once you have downloaded the installation for Sitefinity from www.sitefinity.com, follow the steps below to install the product. 1. Run the installation. The Welcome page will display. Click the Read License Agreement button to reviewing the license terms. If you accept the license conditions Click the I Agree - Continue button to continue.

Figure 1 --The Welcom e Screen

2. The Summary page will list the features to be installed. If you want to install the product in a custom location or specify the features to install, click the Customize button. Click the Install button to continue.

Figure 2 --Sum m ary

2012 Falafel Software

12

Sitefinity 5

3. The Installing Sitefinity page displays status. No action is required on this page.

Figure 3 --Installation

4. In the Completed Successfully Installation page, leave the Launch Sitefinity Project Manager option checked and click the Finish button to close the installation wizard and display the Sitefinity Project Manager.

Figure 4 --Com pleted Page

2012 Falafel Software

Setting Up Your Environment

13

5. The Sitefinity Project Manager provides quick access to creating and configuring Sitefinity projects.

Figure 5 --Sitefinity Project Manager

2012 Falafel Software

14

Sitefinity 5

Installing the SDK


The Sitefinity SDK includes important resources for development not included directly with the core Sitefinity install. Once you have downloaded the installation for the Sitefinity SDK from w w w .sitefinity.com > Developer Netw ork > SDK, follow the steps below to install the product. 1. Run the installation. The Welcome page will display. Click the Read License Agreement button to reviewing the license terms. If you accept the license conditions Click the I Agree - Continue button to continue.

Figure 6 --The Welcom e Screen

2. The Summary page will list the features to be installed. If you want to install the product in a custom location or specify the features to install, click the Customize button. Click the Install button to continue.

Figure 7 --Sum m ary

2012 Falafel Software

Setting Up Your Environment

15

3. The Installing Sitefinity page displays status. No action is required on this page. The Installation will also install other Telerik products including RadControls for ASP.NET AJAX, RadControls for Silverlight and OpenAccess ORM.

Figure 8 --Installation

4. In the Completed Successfully Installation page, leave the Launch Sitefinity SDK Browser option checked and click the Finish button to close the installation wizard.

Figure 9 --Com pleted Page

2012 Falafel Software

16

Sitefinity 5

5. The SDK Browser includes a rich set of resources for getting started with Sitefinity, starter kits, code samples, widgets, blogs, documentation and links.

Figure 10 --SDK Brow ser

2012 Falafel Software

Setting Up Your Environment

17

Summary
In this Chapter you learned how to install Sitefinity.

2012 Falafel Software

3
Getting Started

Getting Started

19

Getting Started
Objectives
In this Chapter you will create a minimal, simple Sitefinity website. The website will contain a single "Welcome" page populated with text.

2012 Falafel Software

20

Sitefinity 5

Sitefinity Project Manager


The Sitefinity Project Manager is the starting point for creating, managing and browsing your Sitefinity website. The Sitefinity Project Manager is available from the Start menu under All Programs | Telerik | Sitefinity <version> | Sitefinity Sitefinity Project Manager. Use this application to: Create a New Project brings up the New Project Wizard where you can create a Sitefinity project on your local file system, in an IIS (Internet Information Services) website on your machine, a remote web site or using FTP to a remote web site. Import a Project prompts so you can add an existing project. The Actions menu and the right-click, context menu contain similar options to perform against any of the selected projects.

Figure 11 --Sitefinity Sitefinity Project Manager

2012 Falafel Software

Getting Started

21

From the Actions menu you can: Go to the Administration backend of the site. Browse to display the live site. Explore the Sitefinity project in the file system. Upgrade a project to the latest version. Edit the project in Visual Studio opens the Sitefinity project in Visual Studio. Show the License Information to see the license constraints such as the product version, number of concurrent users allowed, number of published pages allowed, etc. Show Cassini Info displays the Sitefinity Integrated ASP.NET server dialog along with the Url of the project, physical path, port, and virtual path. You can also start and stop the server from this dialog. Remove eliminates the project from the Project Manager and optionally, will delete the actual files that make up the project. Set SF3.7 for migration prompts for the location of an existing 3.7 website and migrates the project to the current version.

Figure 12 --Actions Menu

2012 Falafel Software

22

Sitefinity 5

Dashboard
The Dashboard is the first visible Page when you navigate to Administration. The Dashboard has the main menu across the top, links to videos and documentation to help you get started and a "Full Documentation" link at the bottom of the page.

Figure 13 --Sitefinity Adm inistration

2012 Falafel Software

Getting Started

23

About Pages and Content


Sitefinity websites are built from two major pieces: Pages and Content. Pages are containers of data. Content is the data that will be placed in the containers. Once you create a page, it goes straight into the database. Likewise, any content you create is saved immediately into the database. You can backup and restore the database and automatically recreate your entire website.

2012 Falafel Software

24

Sitefinity 5

Front End vs. Back End


Pages and content can be placed in either front-end or back-end locations. Front-end refers to the live published site that the end user will see, while back-end refers to the administration (Dashboard) portion that is used to create sites in Sitefinity but is hidden from the user.

2012 Falafel Software

Getting Started

25

Creating Projects
Sitefinity projects can be created using major technology platforms for websites including: Right in your own local file system Using IIS (Internet Information Services) Remotely, through a FTP (File Transfer Protocol) or HTTP (Hypertext Transfer Protocol). The Sitefinity Sitefinity Project Manager makes it easy to get started building your own websites. You don't have to use IIS (Internet Information Services) or spend days making sure the web site will work. The Sitefinity installation includes everything you need to get started building your website.

Lab: Creating a Minimal Sitefinity Website


This Lab demonstrates creating a minimal Sitefinity website stored in your local file system. In this example we're not going to go into the details, but simply walk through creating the web site on your local file system. This project will be launched using the built-in web server.

2012 Falafel Software

26

Sitefinity 5

Creating the Project 1. From the Sitefinity Project Manager click the Create a New Project button from the toolbar at the top of the window.

Figure 14 --New Project

2. The Create New Project Wizard displays. Enter the Project Name "CarConduit". Click the Next button to continue.

Figure 15 --Creating a New Project

2012 Falafel Software

Getting Started

27

3. The Activate a License page of the wizard displays. Enter your Email address and Password from your Sitefinity.com account. If you have a license file downloaded, select the Use a License File You Have Downloaded option and choose the file using the Browse button.

Figure 16 --Activating a License

Notes

If you have already created a project, then you will be able to select from existing licenses.

2012 Falafel Software

28

Sitefinity 5

4. Select the Sitefinity edition that fits the requirements of your project.

Figure 17 --Selecting Sitefinity Edition

Notes

Click the Compare All Editions link that navigates to http://www.sitefinity.com/ purchase/license-comparison.aspx where a matrix displays product capabilities, licensing and pricing.

2012 Falafel Software

Getting Started

29

5. Select the Free Trial or Licensed options button. Subsequent steps will verify your Sitefinity.com login against your licenses. Click the Next button to continue.

Figure 18 --Selecting the Type of Installation

6. The Confirm License page will display the status of your license. Check the Open the Administration of this Project... option. Click the Finish button to close the wizard.

Figure 19 --Confirm ing the License

2012 Falafel Software

30

Sitefinity 5

7. The new project will be added to the list in the Sitefinity Project Manager. At this point Sitefinity has created everything needed for the website except for the database. 8. The Status column for the project will update briefly, then a browser window will open to display the Project Startup . The first step of the project startup is to Set the Database. This example assumes you have Microsoft SQL Server Express installed on your machine with the default instance name of "SQLExpress". Click the Continue button.

Figure 20 --Setting the Database

2012 Falafel Software

Getting Started

31

Notes

If you have a full version of SQL Server installed, click the Microsoft SQL Server option. You will need to provide authentication information, the Server and Database names before clicking the continue button. If you don't have SQL Server Express, you can download it from www.microsoft.com/ express/database/. Each database type will have its own set of authentication entry requirements for the particular database. The screenshot below shows the entries required for each.

2012 Falafel Software

32

Sitefinity 5

9. The second project setup step is to Register the Administrator for the site. Enter the First Name, Last Name, Username and Password that will be used to login to your new website and finally, an Email address. Click the I'm Done button. The Administrator will be granted all possible rights for the project, including the ability to add content, pages and new users.

Figure 21 --Registering the Adm inistrator

2012 Falafel Software

Getting Started

33

10.Next, you will be prompted to login to the new site. Enter the Username and Password from the previous step and click the Login button.

Figure 22 --Logging In

11.After logging in, the site administration Dashboard page will display. From here you can use the menu to navigate between administration tasks.

Figure 23 --The Adm inistration Site

2012 Falafel Software

34

Sitefinity 5

Creating a Page Now you will create a "Welcome" page for your website. 1. From the administration site, click the Pages menu option.

Figure 24 --The Pages Menu Option

2. Click the Create a Page link.

Figure 25 --The Create a Page Link

2012 Falafel Software

Getting Started

35

3. The Create a Page entry form will display. Enter "Welcome" in the Name field.

Figure 26 --Entering the Page Nam e

4. Scroll further down the form and enter "Welcome to CarConduit" in the Title for Search Engines field.

Figure 27 --Entering the Page Title

2012 Falafel Software

36

Sitefinity 5

5. Scroll to the bottom of the form, leave the remaining entry fields at their defaults and click the Create and Go to Add Content button.

Figure 28 --Creating the Page

6. The editor for your new "Welcome" page has a set of content boxes surrounded by dotted lines. The right site of the page is titled Drag Widgets and contains a number of widgets that can be dragged into the content areas. Drag a Content Block widget over to the top box and drop it there.

Figure 29 --Adding the Content Block Widget

2012 Falafel Software

Getting Started

37

7. Click the Enter Content link.

Figure 30 --Clicking the Enter Content Link

8. In the Edit dialog that displays, enter the text "Welcome to CarConduit!". Click the Save button to close the Edit dialog.

Figure 31 --Editing the Content Block

2012 Falafel Software

38

Sitefinity 5

9. At this point we have a minimal page that is working and retrieving data from the database, but is still in draft mode. The page can't be accessed from the outside world yet. At this point you have the option to click the Save as Draft button and continue to work on the page without publishing it. Instead, click the Publish button to make the new page visible in your new website. This step will return you to Pages administration.

Figure 32 --Publishing the Page

10.In Pages administration locate the Welcome page in the list and click the View link.

Figure 33 --View ing the New Page

11.The new page will display in the browser. Notice that the address bar shows a "localhost" address, followed by the project name, then the page name, i.e. "/ CarConduit/welcome". Also notice that the title "Welcome to CarConduit" appears at the top of the page. Finally, the content "Welcome to CarConduit!" displays in the page body. The steps for creating rich, complex pages are essentially the same and involve additional widgets and content.

Figure 34 --The Finished Page

2012 Falafel Software

Getting Started

39

Setting the Default "Home" Page How do you set the default, "home" page? 1. In the Administration list of pages, click the Actions drop down list and select the Set as Homepage link.

Figure 35 --Setting the Hom epage

2. Notice that the "Home" icon appears in the icon next to the page name.

Figure 36 --Hom e Icon

3. Navigate to the site and the default page is displayed automatically without having to write out the complete URL in the browser address bar.

2012 Falafel Software

40

Sitefinity 5

Summary
In this Chapter you created a simple Sitefinity website. The website contains a single "Welcome" page populated with text.

2012 Falafel Software

4
Pages

42

Sitefinity 5

Pages
Clicking the Pages menu item brings you to Pages administration where you can create new pages, rework the layout of the page and set the content of the page. Pages administration has tools to perform all possible actions in Sitefinity.

Figure 37 --Pages

2012 Falafel Software

Pages

43

Objectives
This chapter explains the options for creating and configuring a page. Then you'll learn how to edit page content and layout, paying particular attention to working with the HTML Editor. A tour of the page administration explores the list of pages and the possible Actions you can take, filtering and managing pages.

2012 Falafel Software

44

Sitefinity 5

Page Settings
In the Chapter "Getting Started", we did a quick walk-through of building a page without paying much attention to the detail. As a business user, do you care about any of these other settings for creating pages? Absolutely! The page settings help get your page noticed by search engines like Google, Bing and Yahoo (the major three). Other settings determine how your entire page is arranged. Let's create another page and look at the settings: 1) From the administration site, click the Pages menu option. 2) Click the Create a Page link. 3) The first section of Create a Page is used to name the page and set its location. See the screenshot below for an example of how to fill this section. The Name will display in the navigation. The Name "Contact Us" will appear in menus and other widgets to show the list of pages in the site. Put this page... places the page at the top, "root" level of the site, or Under parent page... to select a parent. In the screenshot below, the "Contact Us" page is placed under the "Welcome" page.
Url is a powerful component of Sitefinity that can specify the how the page will be

accessed in the browser and by internet search engines. Notice that Url does not end in a suffix like".aspx" as in past versions of Sitefinity. Sitefinity "Navigation rerouting" allows the Url to be completely different from the Name of the page and does not have to match up with any technical naming convention. By default, the Url will be the Name of the page, using dashes in place of spaces. In the screenshot below, clicking the Change button, renames the Url "contact-us" to "contact-carconduit". The Show in Navigation checkbox by default makes the "Contact Us" page visible in all navigation widgets. Uncheck this option if you want the page available but not immediately visible from navigation menus.

2012 Falafel Software

Pages

45

Select the Use this page only to group other pages checkbox to have the page become a holder for other pages. If you select this option, the remaining sections that come below (e.g. Title and Description) are eliminated.

Figure 38 --Setting the Page Nam e and Location

2012 Falafel Software

46

Sitefinity 5

4) Title for Search Engines appears in the page title and is also important for Search Engine Optimization (SEO). Be sure to enter something here so that Google or Bing will not ignore your page. Remember, no Title means your page will have a lower search engine ranking.

Figure 39 --Assigning the Title

Tip!

Google robots look for the dash symbol. Google responds best when the web site name is followed by a dash "-", then a short description. For example, "Falafel Software - Home Page".

2012 Falafel Software

Pages

47

5) The Template section lets you control the layout of the page, e.g. the header, footer, toolbars and content areas, how many columns, and how many rows are on the page. Templates create areas that are ready for you to add content to. Click the Select another Template button to choose from a list of predefined template layouts. If you're feeling adventurous you could select the Don't use Template option to start the page completely from scratch.

Figure 40 --Assigning a Tem plate

Notes

Other templates with custom layouts can be created, but this is not a business user task. Developers or designers can create templates using drag and drop in Visual Studio.

2012 Falafel Software

48

Sitefinity 5

6) The Description and Keywords section is another section that's important to define for the best ranking by search engines. Make the Description short and sweet (two sentences max). In the Keywords entry, add the most important words first.

Figure 41 --Entering Description and Keyw ords

Tip!

The key information for the search engines are Title, Description and Keywords. Each search engine has a slightly different priority for these. Some search engines will go up to using eleven keywords while some don't use more than eight. If there are too many keywords, the engine may drop your keywords altogether or just use the first few. So keep the most important keywords first and don't use too many.

2012 Falafel Software

Pages

49

7) The options on the Advanced Options page only need to be changed if a designer or developer has a specific need. In particular, leave the Allow search engines to index this page option enabled so the page will be automatically indexed for searching. The other options fill specific needs: Check the Require SSL to make the page use the HTTPS protocol. HTTPS is used to provide secure communication for sensitive information, e.g. credit card numbers. Enable ViewState is unchecked by default. ViewState is what appears to be garbage characters inside of HTML and is used by the browser to know how to reload the page when the browser Back button is clicked. You should only check this option if you need ViewState and know why you need it. As a business user, you will not need to use this setting, unless your designer requires it. Include RadScriptManager is enabled when required by certain AJAX controls. Set this checkbox if your designer or developer requires AJAX support. Allow Parameter Validation needs to be checked if you're passing parameters to your page. Allow Multiple Urls for this Page Caching Options should be "As set for the whole site". Later you can set caching for the entire site at one time from Administration > Settings > Advanced Settings > System > Output Cache Settings.

2012 Falafel Software

50

Sitefinity 5

Use the HTML included in the <head> tag entry to add script links, style sheet links and "meta" tags. This text box is used to add certain HTML tags that aren't built into Sitefinity already. The screenshot below shows an example of a Meta tag used to refresh the content every 15 seconds from the server. "Expires" is another important Meta tag used to let search engines know that a particular page or document is no longer valid after a certain date. You can look up more Meta tag examples online that you can cut-and-paste into the text box.

Figure 42 --Advanced Options

8) Click the Create and go to add content button to create and edit the page.

2012 Falafel Software

Pages

51

Editing the Page


After clicking the Create and Add Content button, the new page will display. If you want to navigate back to change any of the page information, click the Title & Properties link.

The title of the page shows at the top along with the current page status (should show as "Draft"). The page is not published and will not be visible to users from the browser. The page designer shows on the left and widgets on the right. Notice the buttons Content and Layout at the top right that toggle between the two main views of the designer. Layout shows where the content will go while Content shows the widgets that will display in the page.

Figure 43 --Designing the Page

2012 Falafel Software

52

Sitefinity 5

Editing Content
In this walk-through, we will add some generic HTML content with our contact information, and an image that represents the company and dresses up the page. 1) Click the Content button found at the top of the "Contact Us" page, 2) The right side, labeled Drag widgets, has a list of all the controls that can be dragged to the box areas on the left side. Sitefinity comes with a set of basic widgets for Content, Navigation, RadControls, Data , Scripts and Styles, Login, Search , Classification and Newsletters. We'll start out working with the widgets under the Content title. 3) From the Drag Widgets area on the right side of the page, drag the Content block to the upper right box area.

Figure 44 --Adding a Content Block

4) Click the Enter Content link. to edit the content block. Note that you can also click the Edit link at the top right of the widget. Both actions display a RadEditor control.

Figure 45 --Clicking the Enter Content Link

2012 Falafel Software

Pages

53

5) The RadEditor is an advanced editor for the web that will allow you work with text or directly with HTML, insert links, add images, media or Flash. Click the HTML button located just below the editor window. Paste the following into the editor window:
<p>CarConduit is headquartered in Capitola, California. For more information, please contact us at: </p> <p>Toll Free:<br /> 888 CAR-CONDUIT <br /> Phone:<br /> 555-462-0457 <br /> Fax:<br /> 555-480-4902 <br /> email:<br /> <a href="mailto:info@carconduit.com">info@carconduit.com</a> </p>

6) Click the Design button, also located at the bottom of the editor window. 7) Click the More formatting options button, located in the upper right hand side of the editor. Additional insertion and formatting options will show up on the editor toolbar, and the button will now read Basic options only .

Figure 46 --Enter Text to the RadEditor

2012 Falafel Software

54

Sitefinity 5

8) The screenshot below shows some of the options you may not recognize. In particular, notice the Image Manager used to insert *.gif, *.jpg and *.png directly from your computer or out of the Sitefinity database. The Paste Word button is used to get material from Word documents without the usual large amount of formatting. The Format Stripper is a related button that has a drop down selection of options where you can strip out all the css formatting, Word, Span or Font elements from the content.

2012 Falafel Software

Pages

55

9) Select the word "CarConduit" with the mouse and click the Hyperlink Manager button. Enter a web address, complete with the "http://" prefix, click the More options link and enter a Tooltip. Click the Insert this Link button.

Figure 47 --Inserting a Link

Notes

You can use the LinkTo options to link to an external website,

2012 Falafel Software

56

Sitefinity 5

10)Rest the mouse over the CarConduit link to see the tool tip for the link.

11)The editor can automatically detect web and email addresses. Click the "info@carconduit.com", then click the Hyperlink Manager. Notice that the LinkTo: Email option is already selected and the email address is already filled in. 12)Select the text "Toll Free:" and select a blue foreground color. Repeat this for the text "Phone:", "Fax:" and "email:".

Figure 48 --Selecting Foreground Color

2012 Falafel Software

Pages

57

13)Click the HTML tab. Notice the "<a>" tag for the CarConduit hyperlink, the "mailto" link for the contact email and the span with color styles.

Figure 49 --The HTML View

14)Click the Save button to close the editor. The content block should now look something like the screenshot below.

Figure 50 --The Com plete Content Block

2012 Falafel Software

58

Sitefinity 5

15)Drag the Image widget to the top left box area. Click the Select an image link. In the Insert an image dialog that displays, notice that you can upload images From your computer and From already uploaded (images already stored in the Sitefinity database). From your computer, click the Select... button and locate an image. "BlackTruck.jpg" is being used in the example here. Enter "Black Truck" for the Alternative text. Leave the other values at their defaults. Click the Save button to close the dialog.

Figure 51 --Inserting an Im age

2012 Falafel Software

Pages

59

16)The truck image is too large and has bled into the space for the content block. Click the Image widget Edit button to begin fixing this.

Figure 52 --Im age Widget With Oversize Im age

2012 Falafel Software

60

Sitefinity 5

17)Click the From already uploaded link. Select the black truck image. Then click the Resizing options to open that area. Select the Resize the image width to... option and select "Small: 240 px width" from the drop down list. Click the Save button to close the dialog.

Figure 53 --Fixing the Im age Size

18)Now the image shows at a reasonable size and is proportionate to the content block.

Figure 54 --Im age Widget With Appropriate Size Im age

2012 Falafel Software

Pages

61

19)Click the Publish button. 20)From the page list, click the View link next to the "Contact Us" page. The page should look something like the screenshot below.

Q & A...

Q: Is content within the content block indexed? A: Yes, once indexing is turned on, the content block is included in the search indexing automatically. News, blogs, etc. are all included in the search.

2012 Falafel Software

62

Sitefinity 5

Editing Layout
Arrange where content will go on the page by editing the layout. You can drag layout items around quickly in the page without writing any code. 1) Click the Layout button 2) The left side of the page shows the layout designer and predefined areas that will hold content. Each box in the designer has a hint to "Drag layout elements" to divide the area into columns.

The Layout Designer

3) From the right side, titled Drag layout elements, drag the 25% + 75% layout element into the top box.

Figure 55 -- Dragging a Layout Elem ent

2012 Falafel Software

Pages

63

4) Now the top box is sub-divided into two areas, one with 25% width and the other with 75%. Click the Edit button.

Figure 56 -- New Layout

5) Move the mouse between the two columns and drag the resize handles to reportion the column widths. Set the left column to around 20% and the right column to around 80%.

Figure 57 --Changing Colum n Proportions

2012 Falafel Software

64

Sitefinity 5

6) On the right side of the designer, the Edit Layout Element area allows you to fine tune the box sizes in either percentages (the default) or pixels. Enter the value "30" in the space for Column 1 . Column 2 is marked as auto-sized and will automatically change to "70%".

Figure 58 --Changing Sizes

2012 Falafel Software

Pages

65

7) Click the Spaces link. The amounts below increase the space between the outside edge of the content and the area surrounding the content. Change the first column spacing to have "5" pixels on each side. Change the second column to have "5" pixels on the top, right and bottom, and "20" pixels to the left. As you edit the amounts, notice the changes to the columns displayed to the left.

Figure 59 --Editing a Layout Elem ent Spaces

2012 Falafel Software

66

Sitefinity 5

8) Click the Classes link. Each column in the screenshot below is using a predefined CSS (Cascading Style Sheet) class that's built into the system. You can also use Wrapper to add styles to the entire box area. If your designer supplies styles for the project, you can apply those styles here.

Figure 60 --Editing a Layout Elem ent Classes

9) Click the Done button. 10)Click the Save as Draft button.

2012 Falafel Software

Pages

67

Tour of the HTML Editor


Initially, the buttons for the HTML Editor show only a minimal set of options. You can toggle this using the More Formatting Options button located on the right hand side of the button bar. The screenshot below shows key editor features:

2012 Falafel Software

68

Sitefinity 5

Hyperlink/Remove Link: The Insert a link dialog that displays in response to this button allows you to create links for web addresses, pages from your Sitefinity site or email. Use the dialog to set the Web address and Text to display. Options in the dialog allow you to set the Tooltip, the CSS class and if the link should be opened in a new window.

Figure 61 --Inserting a Hyperlink

2012 Falafel Software

Pages

69

Image Manager: The Insert an image dialog that displays in response to this button allows you to load images from your local computer to your website or use images that have already been loaded to the Sitefinity database. You can load the image to an Album, assign Alternative text (to satisfy accessibility requirements) and resize the image automatically to predefined dimensions (e.g. "thumbnail", "large", etc.) or set custom dimensions.

Figure 62 --Inserting an Im age

2012 Falafel Software

70

Sitefinity 5

Spell Check is performed directly in the HTML editor. A message at the top of the editor notifies that the editor is in Spell checking mode. Buttons to the right allow you to Finish spellchecking and Cancel . The list that drops down under each misspelled word contains alternative correct spellings and options to Ignore, Change Manually or Add the highlighted word to the dictionary.

Figure 63 --Spell Checking

2012 Falafel Software

Pages

71

Paste From Word inserts content without losing the Word formatting. For example, if you have a heading, subheading and some paragraph text, a standard paste will pick up on the fact that there's a heading and display it as such, but will lose the detailed font style formatting. The Paste From Word option retains the detailed font formatting. The next few screenshots show content in Word, then the same content pasted to the editor window, then finally the same content Pasted as Word to the editor window.

Figure 64 --The Content in Word

Figure 65 --Using Control-V to Paste Word Content

2012 Falafel Software

72

Sitefinity 5

Figure 66 --Using Paste from Word

The Tables button drops down a list where you can define a table by dragging the mouse graphically, or use the buttons below to invoke the Table Wizard , add/merge/delete rows and columns and to set table properties.

Figure 67 --Creating Tables

2012 Falafel Software

Pages

73

The Symbols button drops down a list of characters that would otherwise be unavailable from the keyboard. For example, when you need to paste the Copyright symbol in a document, you can select it from this list. Select a symbol with the mouse to insert it into the HTML Editor.

Figure 68 --Inserting Sym bols

The Format Stripper button allows you to remove all excess formatting, or just certain aspects, such as Css formatting. Word formatting is famous for being verbose, so Strip Word Formatting will remove all that extra HTML.

Figure 69 --Rem oving Form atting

2012 Falafel Software

74

Sitefinity 5

The Find & Replace button displays a dialog that can search for a given word or replace a found word with another. The search is performed from the current cursor position with the search Direction traveling either Up or Down. The dialog includes industry standard Search Options, Match case and Match whole words.

Figure 70 --Find & Replace Dialog

2012 Falafel Software

Pages

75

The Media Manager button displays a dialog that works exactly like Insert an Image except that the Insert a Video dialog accepts *.wmv files.

Figure 71 --Inserting a Video

2012 Falafel Software

76

Sitefinity 5

The Document Manager dialog allows you to insert any document file. Clicking the Insert the document or other file button inserts a link to the file in the HTML Editor using the text in What title to display .

Figure 72 --Inserting a File

2012 Falafel Software

Pages

77

Tour of Page Administration


As your own website builds in size and complexity, you will need to work on all your pages in one place. For example, you may want to search for a certain set of pages, then publish them all. Page Administration allows you to work on all your pages. The top left of Page Administration contains the Function Bar, below that the list of pages and to the right, the Manage Pages area.

Figure 73 -- Page Adm inistration

Page List
Pages are listed in a tree structure. The screenshot below shows our home "Welcome" page, with the "Contact Us" underneath it. Notice the "House" icon that lets us know that Welcome page is the default home page. Also notice the green check marks that indicate these pages are published. Click the name of the page to edit the page or click the View link to preview the page at any time in a separate browser. The Actions menu provides the full set of options possible for the page, such as deleting, editing, etc. The Date/Owner column shows the creation date of the page and the person that created it.

Figure 74 --Page List

2012 Falafel Software

78

Sitefinity 5

Actions
The Actions drop down menu is available for every page. With the Actions menu you can Delete the entire page, or Unpublish to make the page invisible to the outside world. If you want to create a page that's almost the same as an existing page, you can use the Duplicate option to make a copy. The duplicated page will have all the same SEO settings, along with Title, Keyword, Description and content. Before you duplicate a page, consider using a template for aspects of the page that don't change. Also be aware that duplicated pages must have a unique Url. Click the Set as Homepage option if the page should be the default when navigating to the site. Only one page can be the Homepage.

Create a child page adds a new page underneath the current page in the tree hierarchy. The Edit... section of the Actions menu allows you to go back and edit the Content or Title and Properties. Permissions determines who can see and perform other actions on the page. See the upcoming section on Permissions for a thorough discussion on controlling access to your pages. Revision History allows you to see each of the changes made to the page, who made these changes and when. If a later version has serious mistakes, you can also revert to any earlier version. The Change section of the Actions menu allows you to change the Template for the page. For example, if I want the page that has a single column and header and footer to use the Apple style "Promo" layout with three columns, then I can change the template for the entire page. Be aware that, as of this writing, the content will be removed. You can also change the Owner for the page so that you can pass off certain pages to other members of your team so that they can search for pages that they have responsibility for. Use the Move... section Up and Down options to move the page in the tree hierarchy. More options may show up on this menu depending on the state of the page. For example, if the page is locked, the Unlock option will display here.

2012 Falafel Software

Pages

79

Notes

All items in the menu will only show up if you have the appropriate permissions. For example, you might not see the Change Owner option if you don't have the correct permissions.

Saving Drafts and Publishing


When you click the Save button, the content is recorded in the revision history (shown on the right of the screenshot below). The revision history allows you to compare versions, roll back to earlier versions and add notes to particular versions.

2012 Falafel Software

80

Sitefinity 5

Manage Pages
The example site only has a couple of pages right now, but as you build your own production website, it will become harder to locate certain pages when you want to maintain them. The Manage Pages area to the right of the page list allows you to Filter pages quickly. The filters shown here are not random, but reflect Telerik's experience working with Sitefinity customers in real-world situations. For example, lack of Descriptions or Keywords are not best practice for Search Engine Optimization.

Clicking a filter performs an AJAX based search, that is, the page does not refresh and the search returns more quickly. You can use the "With No Keywords" filter for example to get the pages where keywords were left out. You can, of course, just filter to show only your own pages. Using the by Date modified... filter you can look at the most recent changes, or use a custom date and time range. The Manage also > Templates option is a shortcut for Design > Page Templates. The Permissions for all pages option allows you to change the access to all pages at one time, controlling what roles can view, edit, modify, change permissions and so forth.

2012 Falafel Software

Pages

81

Function Bar
The Function Bar works against all selected pages at one time. The checkboxes to the left of each page indicate which pages are affected. You can Create a child of the selected page to extend the hierarchy of pages. The More actions drop down menu includes the ability to change the page Template (i.e. the predefined overall layout of the page). You can also restructure your page by dragging and dropping pages.

Figure 75 --Using the Function Bar

To narrow down a long list of items, click the Search... button, enter the text to search for and click the Search button. The search is not case sensitive and looks for Titles that contain the search text. Click the Close Search button to return to the unfiltered list of items.

Figure 76 --Searching for Item s

2012 Falafel Software

82

Sitefinity 5

Summary
This chapter explained the options for creating and configuring a page. You learned how to edit page content and layout, paying particular attention to working with the HTML Editor. A tour of the page administration explored the list of pages, the possible actions, filtering and managing pages.

2012 Falafel Software

5
Content

84

Sitefinity 5

Content
While you can add page content on-the-fly in Sitefinity, the content is kept separately and can be managed from the Content menu items. Why is content managed separately in Sitefinity? Imagine you have a company logo, or a document (say, a legal disclaimer) and you need to change the content. Then, your organization changes logo images or the legal department has new wording that must be implemented. If the logo or document is used in hundreds of places on your site, you would need to update each. Not only would that be time consuming, forgetting to change the wording on a legal document on a single page could cause problems for your organization. If the image or document is kept in a single place, you can make changes once and know that the change will show up everywhere it is used. Not only that, as you build up libraries of content, you can mix-and-match existing material to build new pages more easily.

2012 Falafel Software

Content

85

Objectives
This chapter tours the Content Menu and demonstrates how to work with each type of content. You'll learn how to create content, how to use widgets to display content in a page and how to configure the widget to fine-tune the layout and behavior of the content.

2012 Falafel Software

86

Sitefinity 5

Tour of the Content Menu


The Content menu item lets you add standard subject matter like Blogs, Images and Events. The initial page for each type of Content will display a message that "no items have been created yet" and a link to create the first item. The screenshot below shows a representative example from the News page.

Figure 77 --Link to Create a New Item

When at least one item has been created, the page displays the items in a list. The screenshot below shows an example of News items. Above the list is a Function Bar containing Create and Delete buttons, a drop down list of More actions and a Search... button. To the right of the list is a Manage column with additional actions. The presentation of buttons and list will vary according to the type of content shown.

Figure 78 --Content List

2012 Falafel Software

Content

87

Content Block
News, Events and Content Block are similar to one another with only minor variations. The simplest item, Content Block, has a title and some HTML. To create a Content Block: 1. Drop down the Content menu and select Content Blocks. 2. This is the first time to visit the Create a Content Block page, so you will see the "No Content Blocks have been created yet" message. Click the Create a Content Block link. This will display the Create a Content Block page.

Figure 79 --Creating a Content Item

2012 Falafel Software

88

Sitefinity 5

3. Enter a Title. Below the title area, enter any text or HTML content in the HTML Editor.

Figure 80 --Content Block Title and Content

2012 Falafel Software

Content

89

4. Categories and Tags help you organize content and allow search engines to locate and rank your content. Categories are used when searching the website while Tags are used by external search engines. In the Categories and Tags area of the page, select the Categories Change button to add categories. You may also enter a comma-separated list of Tags.

Figure 81 --Entering Categories and Tags

Q & A...

Question : Do categories have to do with Search Engine Optimization (SEO)? Answ er : Categories are used for searching the site within Sitefinity. SEO is driven by title, description and keywords.

5. Click the Create this content block button. 6. In place of the "No Content Blocks have been created yet", the items will display in a list that shows the item Title, a drop down list of Actions, the Owner and the Date.

Figure 82 --The Content Block Page

2012 Falafel Software

90

Sitefinity 5

7. Click the Pages menu item, then click the "Welcome" page link to edit the content. Alternatively, you can also click the Actions > Edit... > Content. 8. Drag the Content Block widget to the second row, right side column of the "Welcome" page.

Figure 83 --Adding the Generic Content List Widget

9. Click the Edit link of the Content Block widget.

Figure 84 --Editing Content

2012 Falafel Software

Content

91

10.In the Edit dialog that displays, click the Select from existing shared content button.

Figure 85 --Selecting from Existing Shared Content

11.You will see a list of shared content items. Select the "Classic Car Appraisal" item you created earlier, then click the Done selecting button to return to the Edit dialog.

Figure 86 --Selecting Existing Content

2012 Falafel Software

92

Sitefinity 5

12.Back in the Edit dialog, click the Save Changes button.

Figure 87 --Saving the Shared Content

Notes

The Edit dialog notifies you that the content is shared among any pages that reuse this particular Content Block. You can edit the content and the changes will ripple out to all pages where its used.

2012 Falafel Software

Content

93

13.Click the Publish button to make the content available to a page on the website.

Notes

If you decide to Save a Draft, the content item is saved in the database, but is not available to use in a page. Only after the content item is published can you use it and have it visible in a page.

14.View the "Welcome" page and view the new Content Block.

Figure 88 --View ing the Content Block

2012 Falafel Software

94

Sitefinity 5

News
News is almost identical to Content Block except that News includes a Summary section below the HTML Editor and a Additional info section that records the Author of the news article, the Source name that supplied the news and a Source URL.

Figure 89 --Additional Info

2012 Falafel Software

Content

95

1) From the administration menu, click Content > News. 2) Click the Create a news item button. 3) Enter a Title and add content text for your news article.

Tip!

If you're at a loss for words and simply want sample text so you can see how Sitefinity handles it, you can use "Lorem Ipsum". "Lorem Ipsum" is dummy text used by designers to simulate content when they're more interested in how the content will be arranged on the page. For example: "Duis rutrum nunc mauris, a molestie sem. Morbi semper dictum nulla, ut volutpat diam luctus in. Aliquam commodo varius lacus non interdum." Try the Lorem Ipsum generator at http://www.lipsum.com/ to create paragraphs, words or lists of text. Cut and paste the text into your news article content area or use one of the browser plug-ins.

4) Click the Click to add summary link. The Summary is important because we can display this in a list of news without reproducing the entire news item. 5) Click the Publish button. 6) Create and publish a second News item 7) Navigate to the "Welcome" page. 8) Drag the News widget to the left side of the second row. 9) Notice that all news items you have created show up in the list along with the one line Summary and a link to the full news story.

2012 Falafel Software

96

Sitefinity 5

10)Click the Edit link at the top of the News widget. Notice the three different sections you can use to tailor the presentation of the news: Content, List Settings and Single Item Settings. Content lets you show all of the published news, a single news item or filter new by a combination of Categories, Tags and Dates. Use the One particular news item only... option if you want the entire news article displayed directly on the page. Leave the default settings with the All published news option selected.

Figure 90 --Editing New s

2012 Falafel Software

Content

97

11)Click the List Settings option to configure how multiple news items will be displayed by the News widget on a page. Use paging limits the news items that show at one time and provide links for overflow news items. This option lets you control the amount of real estate that gets used on the page, particularly if you have other material to fit in. Use limit shows only X number of items. You can use this option along with the Sort news drop down to show a few of the newest items. No limit and paging just dumps all your news items out on the page in a list. The Sort news drop down list allows you to order news items by Last published on top , Last Modified on top , By Title (A-Z), by Title (Z-A) or As set in Advanced Mode. List template determines how the news content will be arranged on the page. Typically you will choose one of the predefined templates on the left, e.g. Titles and Dates. Telerik has presented you with the usual industry standard layouts, but if you need a specific layout, you will not hit the wall. Clicking the Edit selected template button allows you to change the layout and content of the template. Note: Tweaking the template does involve working in HTML, but you're supplied with all the fields that Sitefinity has access to, and Sitefinity creates the HTML you need so you can cut and paste to your template.

Figure 91 --List Settings

2012 Falafel Software

98

Sitefinity 5

12)Click the Single Item Settings of the News dialog. 13)The Single Item Settings let you choose to use the Auto-generated page or select an existing page. Typically, you will use the Auto-generated page option. If you have a custom page built to display the news, use the Select existing page... option to include this custom page instead. Leave the default settings here and click the Save button to close the dialog.

Figure 92 --SIngle Item Settings

2012 Falafel Software

Content

99

Q & A...

Question : What does the Advanced button do? Answ er : Advanced shows a list of all possible properties for the widget. For example, if your organization's designer adds a CSS (Cascading Style Sheet) file to the Sitefinity project, you could enter the name of a style in the CssClass property. Clicking the Simple button returns you to the original settings view.

2012 Falafel Software

100

Sitefinity 5

14)Click the Publish button for the "Welcome" page. 15)Click the View button for the "Welcome" page.

Figure 93 --New s List

16)Click the Full story link under one of the news items. This automatically generated page displays the full news article along with a comment section.

Figure 94 --New s Detail

2012 Falafel Software

Content

101

Events
Events are similar to Content Blocks but with additional sections to record the event summary, event start/end dates, location and contact information. 1) From the administration menu, click Content > Events. 2) Click the Create an event button. 3) Enter a Title and add content text into the HTML Editor. 4) Below the HTML Editor, enter a Summary , Event start and Event end . Click the Event start and event end text boxes to pop up date and time picker widgets automatically.

Figure 95 --The Event Sum m ary

2012 Falafel Software

102

Sitefinity 5

5) In the Location section, enter the event Street, City , Country and State.

Figure 96 --Event Location

6) In the Contact information section, enter details for the person acting as the main contact for the event.

Figure 97 --Event Contact Inform ation.

7) Click the Publish button.

2012 Falafel Software

Content

103

Tip!

In this example we want to see the event right away. But in a production website you may want the event to expire after the event has started or expire when the event is over. You can use the Schedule action from the menu to set start and stop dates and times for the event. Once the event becomes automatically unpublished, the event will not be visible on the page.

8) Navigate to the "Welcome" page. 9) Drag the Events widget to the left side of the second row.

Figure 98 --The Events List

2012 Falafel Software

104

Sitefinity 5

10)Click the Edit link at the top right of the Events widget. Notice that the arrangement of the Events dialog is very similar to the News dialog. The Content tab allows you to filter which events to display. The List Settings and Single Item Settings are almost identical to News except that Events displays Titles, Cities, Dates and Summaries.

Figure 99 --Editing Events

11)Click the Publish button for the "Welcome" page. 12)Click the View button for the "Welcome" page.

2012 Falafel Software

Content

105

13)Click the event title link to see the detail. Like news articles, the event detail has a predefined format that includes all the date, location and contact information. The format also includes a comments area.

Figure 100 --Event Detail

2012 Falafel Software

106

Sitefinity 5

Images and Albums


Images are stored in Albums. You can use the default album or create your own. Here are the steps to create an album and upload images to the new album. 1. From the Administration page, click the Content > Images menu item. 2. In the Images page, click the Create an image library link. 3. Enter an Album name, click the Click to add a description link and describe the album contents.

Figure 101 --Defining the Album Nam e and Description

4. In the Default image size section, click the Resize images... option and select "Small: 240 px width" from the drop down list.

Figure 102 --Defining Default Im age Size

2012 Falafel Software

Content

107

Notes

If you choose to "Resize images...", you can select from the predefined dimensions Thumbnail , Small , Medium, Large, or Extra Large.

Figure 103 --Selecting a Maxim um Size

2012 Falafel Software

108

Sitefinity 5

5. In the Advanced section, enter Max album size in megabytes, Max image size in kilobytes and customize the URL. You don't want to allow people to upload files that are huge and take over the hard disk on the server. The default is "anything goes", but you should make a decision on the maximum image size allowed. You can also change the URL of the image library, the Storage provider can be Database or File System, and you can also set caching options for both the Server caching and Browser caching .

Figure 104 --Setting Advanced Properties

2012 Falafel Software

Content

109

Notes

Caching is set to As set for the whole site as the default. Click the Details link to see what the current settings consist of. The Details popup shows the caching options, the HTTP Header equivalent, and the path to reconfigure these settings.

6. Click the Create and go to upload images button. 7. In the Images Page, click the Upload Images link. 8. In the Upload images page, click the Select images link.

Figure 105 --Selecting Im ages

2012 Falafel Software

110

Sitefinity 5

9. In the Windows Open file dialog that displays, navigate to image file location. Select and open one or more image files.

Figure 106 --Selecting Im ages

10.In the Upload images Page, open the select an album drop down, select the new "Cars" album.

Figure 107 --Selecting an Album

11.Click the Upload and publish button to store the images. Wait a moment as all the images are uploaded. When the "images have been successfully uploaded " message displays, click the View all images button to return to the Images Page.

Figure 108 --Successfully Uploaded Message

2012 Falafel Software

Content

111

12. Review the uploaded images.

Figure 109 --Im ages Page

2012 Falafel Software

112

Sitefinity 5

Displaying Image Content


You can display a single image using the Image widget, as demonstrated in the "Editing Content" section. The Image Gallery widget can display a series of images in a number of formats. To demonstrate, let's create a new page called "Marketplace". 1) From the Pages administration, locate the "Welcome" page, click the Actions menu and select the Create as child page option. 2) Name the new page "Marketplace", In the Template section, select the "1 Column, Header, Footer" template. Click the Create and go to add content button. 3) Drag the Image gallery widget to the top box area. All of your uploaded images should display. Remember that the "Black truck" image was loaded into the default gallery. The other images have been loaded to the new "Cars" gallery. Both sets of images should be displayed. 4) Click the Image gallery widget Edit link. 5) The Image Gallery dialog has two links, Images and Settings. The Images link lets you fine tune which images will be shown and sort the order the images will be displayed in.

Figure 110 --Im age Gallery Im ages Tab

2012 Falafel Software

Content

113

6) In the Images tab, under the section title Which images to display?, click the From Selected Image Library... option. Click the Choose button to display the Choose Image Library dialog. You can type into the text box at the top to filter the list. The list will update automatically when you finish typing. Select the "Cars" album and click the Done selecting button.

Figure 111 --Choosing an Album

7) The Images Gallery dialog should now look like the screenshot below.

Figure 112 --Im age Gallery Using Selected Album

2012 Falafel Software

114

Sitefinity 5

8) Click the Settings link. Settings is a powerful feature that arranges the images and describes the behavior of the gallery. The two sections in Settings are, 1) Select image gallery type and 2) Fine tune the selected type.

Figure 113 --Selecting the Gallery Type

Thumbnails + Detail page lists the image left to right, top to bottom. When you click on an image, the image is displayed in an entirely new detail page. Depending on the "Fine Tuning" settings, the detail page may also have links to previous and next images or previous and next thumbnails. Thumbnails + Overlay improves the user experience by displaying a selected image over the top of the gallery images. The user can click the X button in the upper right corner of the detail image to close it. From there, the user can navigate through the other images.

2012 Falafel Software

Content

115

Thumbnail strip also improves the user experience by display the images in a strip at the bottom of the widget and the selected image above the strip, on the same page. This also allows easy navigation between images.

Simple List displays all the images vertically but the images are not clickable and there is no detail view.

2012 Falafel Software

116

Sitefinity 5

9) The Fine tune the selected type section varies, depending on which gallery types is selected. For all types but the Thumbnail strip, there are three common options. The first two limit the number of images displayed. These two options are the recommended way to go. The first option, Use paging , limits the number of thumbnails displayed at any one time. The second option, Use limit, puts an absolute limit on the number of images shown. The No limit and paging option could be slow if there are a lot of images and could be difficult for the user to navigate. If you select Thumbnails + Detail , the Fine tune... section includes a checkbox to Show links to the previous and next image.

Figure 114 --Fine Tuning the Im age Gallery

Tip!

The lightbox option resizes the detail image automatically. You may need to get larger, higher quality images to display in the lightbox. It's also a good idea to make sure the images that display together in the lightbox are a similar size.

2012 Falafel Software

Content

117

10)Try each of the gallery types, save your settings for the Image Gallery, Publish the page and view the results.

2012 Falafel Software

118

Sitefinity 5

Video
Video Size and Behavior
Before you start uploading lots of videos to Sitefinity, you need to know how videos are stored, retrieved and played back. Be aware that when a video is uploaded to Sitefinity, the video is uploaded to the database, not as a separate file. So if you upload a 7mg video, the Sitefinity database grows by 7mg. When the user starts a video that is stored in a file, the video is "buffered" on the client machine, where after the first 20% or so of the video is read, the video starts to display. If the video is coming from a database, then the entire video must be read before it can start to play. The implication is that large files, 5mg plus as a general rule, should be left as files. The tradeoff is that loading everything into the database is good for deployment and the uploaded data is accessible throughout the site using the built-in widgets.

2012 Falafel Software

Content

119

Uploading and Configuring Video


Videos are handled very much like Images and are uploaded to Libraries. 1) From the administration menu select Content > Videos. 2) Click the Upload videos link. 3) Click the Select videos link. 4) Select the a sample video that ships with Windows, or any *.wmv file you have available. 5) Click the Upload button. Depending on the size of your video and the speed of the machine, the upload can take some time. 6) Click the View all videos button.

Figure 115 --The Uploaded Video

7) Click the Embed this video link.

Figure 116 --Em bedding a Video

2012 Falafel Software

120

Sitefinity 5

8) The Link or embed dialog provides a Link that can be placed in email or Instant Messenger. The Embed tag can be pasted into an HTML page for Mozilla and IE based browsers. Close this dialog.

Figure 117 --Getting a Video Link or Em bed Tag

9) Drop down the video's Actions menu (just below the video thumbnail) and notice that you can Play the video directly without having to view the page.

Figure 118 --Playing the Video

2012 Falafel Software

Content

121

10)Select the video's Actions > Edit Properties. This displays the Edit Video page where you can change the video Title, Thumbnail , Author and Description. Click the Thumbnail Change button.

Figure 119 --Changing the Thum bnail

2012 Falafel Software

122

Sitefinity 5

11)The Generate Thumbnails dialog pops up and lets you take snapshots of the video as it plays. Just click the Get the currently displayed frame button to save off a thumbnail image. You can save off multiple thumbnails to the thumbnail strip below the playing video. Select the thumbnail that you want displayed in the page and click the Done button.

Figure 120 --Generating Thum bnails

12)Click the Publish button for the video. The published video now displays the new thumbnail.

2012 Falafel Software

Content

123

Using Video Widgets


1) Click the Pages menu option. 2) Create a new child page under the home "Welcome" page named "Featured Videos". 3) Click the Create and go to add content button. 4) Drag a Video widget to the top row of the page. Notice that, in place of an image from the video, a message tells us that the page must be published before the video can be displayed. 5) Click the Video widget's Edit link. 6) In the Insert a video dialog, click the From already uploaded link. Select the video that you previously uploaded and click the Save button.

Figure 121 --Inserting a Video

7) Click the Publish button for the page.

2012 Falafel Software

124

Sitefinity 5

8) Click the View link for the "Featured Videos" page. The Video widget displays with a "Play" button arrow. Click the arrow to view the video. The video player displays with all the industry standard controls like play, pause, a time line, volume controls and a full screen button.

Figure 122 --View ing the Video

9) Navigate back to editing the "Featured Videos" page. 10)Remove the Video widget and drag the Video gallery widget to replace it.

2012 Falafel Software

Content

125

11)Click the Video gallery Edit link. The Video Gallery edit dialog is very similar to the Image Gallery. There is a link for Videos, where you can limit the display to All published videos, From selected library and Upload new videos.

Figure 123 --Video Gallery Settings

12)Click the Settings link. Like the Image Settings dialog, this dialog is split up between two sections, 1)Select video gallery type and 2) Fine tune the selected type. In the Select video gallery type section, you can choose Thumbnails + Detail page or Thumbnails + Overlay . These work the same as their Image counterparts.

2012 Falafel Software

126

Sitefinity 5

In the Fine tune the selected type section, you can limit both the number of items the gallery shows and the size of the thumbnails. To get the best control over your page real estate, select either the Use paging or Use limit options.

Figure 124 --Fine Tuning the Gallery

13)Select the Thumbnails + Overlay (lightbox) option. 14)Click the Save button. 15)Publish and view the page.
Q & A...

Question: What player is being used to play the video, Flash? Answ er: Sitefinity uses the Silverlight player . The Silverlight player is able to use the video hardware acceleration on your computer and can produce a smooth playback.

2012 Falafel Software

Content

127

Lists
Use the Lists content to display a series of values and descriptions. Lists can be useful to show relatively small collections of codes, categories or other designations, for example priorities, color coding or quality flags. These can be displayed in the page as simple lists, expandable lists, anchors, etc. Each List has a title for the list as a whole, e.g. "Priority". Each list has a number of ListItems, each with their own Title and Content, e.g. "High", "Medium" and "Low".

2012 Falafel Software

128

Sitefinity 5

Creating Lists
The walk-through demonstrates creating a simple "Priority" list. 1) From the administration menu, click Content > Lists. 2) Click the Create a List button. 3) Enter a Title for the list. In this example we will create a "Priority" list. 4) Click the Create this list button.

Figure 125 --Creating the List

5) Click the Create a list item button.

Figure 126 --Creating the List Item

2012 Falafel Software

Content

129

6) Enter the Title as "High", and content in the HTML editor as "High Priority". Click the Publish button.

Figure 127 --Populating the List Item

Tip!

Using the HTML editor, you can insert images from Albums that will display in the list. Click the Image Manager button to select images already in your albums or upload new images on your local disk.

7) Click the Create a list item button. Enter the Title "Medium" and HTML content "Medium Priority". Click the Publish button.

2012 Falafel Software

130

Sitefinity 5

8) Click the Create a list item button. Enter the Title "Low" and HTML content "Low Priority". Click the Publish button. 9) The list should now look something like the screenshot below.

Figure 128 --The Finished Priority List

2012 Falafel Software

Content

131

Using Lists in Pages


The walk-through demonstrates adding a simple "Priority" list to a page. 1) Navigate to a page that will contain the list. 2) From the Widgets on the right side, drag the List widget to the page.

Figure 129 --Adding the List Widget

3) Click the Set which list to display link to display the Edit dialog. 4) In the Content tab of the Edit dialog, click the Select lists button. Check the "Priority" list and click the Done selecting button. 5) Click the Settings link. 6) Select the Expandable list radio button. 7) Click the Save button to complete the Edit dialog and view the changes.

Figure 130 --List Displayed in Page

2012 Falafel Software

132

Sitefinity 5

Blogs
Blogs are used to publish recent news and allow commentary by readers to form an online conversation. A successful blog can also be "syndicated" to other websites over various standards such as RSS (Really Simple Syndication). Sitefinity makes it easy to create blogs for as many groups or subjects as needed. For example, you could have a blog for each subject your site covers (e.g. "Deserts", "Main Course" for a cooking site), or a blog for each department in your organization, or even a blog for each person in smaller organizations. The blog will contain blog posts, i.e. articles that relate to the blog content.

2012 Falafel Software

Content

133

Blog Engine
When someone says "I wrote a blog", they are usually talking about a "blog post". The blog itself is the blog engine that contains blog posts. Your first step will be to create the blog engine. 1) Drop down the Content menu and select Blogs. 2) Click the Create a Blog link. This will display the Create a Blog page. 3) Set the Title to "Classic Cars Blog". Allow Comments: Some medical, government or other public organizations may not want comments. If possible, you should allow comments to create a lively discussion and a sense of community. You can limit comments so that only registered users can contribute. You can also moderate comments so that comments have to be approved before appearing on the site. By default, comments are allowed by anyone and are not moderated. Alternative Publishing : By default, blogs are published as RSS (Really Simple Syndication) to be read by GoogleReader or other news readers that accept RSS or ATOM feeds. This allows your news to be syndicated, that is, your blogs are made available to multiple other websites.

Figure 131 --Creating a Blog

2012 Falafel Software

134

Sitefinity 5

4) Open the Alternative publishing (Rss) section. 5) Click the Change button. This will display the RSS feed page so that you can fine-tune the settings. Enter the Url name "classics" and click the Done button. RSS or Atom to generate? : This set of options adjusts the standard used to publish the feed. Both standards are widely used and can be handled by most popular feed readers. Url name: This must be entered to create the full url used to access the blog. Most browsers will recognize and format the blog automatically. This support is built into recent versions of Internet Explorer, FireFox and Safari. Google Chrome currently requires an extension to format blogs. Limit the items in the feed : To keep the material fresh, limit the number of posts shown in the blog to the newest items. An item in the feed contains: By default, each post shows both the title and content. You can cut this down to the title and a certain number of characters of the post or even show the title only.

Figure 132 --RSS feed Settings

2012 Falafel Software

Content

135

6) Based on the Url name that you entered, the Alternative publishing section now includes a link to the blog. Make a note of this link for later use.

Figure 133 --RSS Feed Link

7) Click the Create this blog button. This will bring you to the Blog Posts page.

2012 Falafel Software

136

Sitefinity 5

Blog Posts
You have created a Blog, i.e. the container for posts. Now you can create the actual blog posts. 1) From the Blog posts page, click the Create a Post link.

Figure 134 --Creating a Blog Post

2) In the Create a post page, enter a Title, then text to the HTML editor.

Figure 135 --Entering Title and Content

2012 Falafel Software

Content

137

Tip!

Insert images to the HTML editor using the Image Manager button located on the HTML editor toolbar. You can load images from your local hard drive or use images that are already uploaded to Sitefinity.

3) Click the Summary > Click to add summary link and add a line or two of text that sums up the post.

Figure 136 --Adding a Sum m ary

2012 Falafel Software

138

Sitefinity 5

4) From the More actions button at the bottom of the page select Schedule Publish/ Unpublish . Using the date and time pickers for the Publish on field, set a date in the future that lands on a Monday at 6am.

Figure 137 --Scheduling Publication

2012 Falafel Software

Content

139

Tip!

When it comes to blogging, all days of the week are not created equal. You should publish your blog early on Monday, around 5-6am. Later in the week, blog posts get lost in the shuffle and won't be read. The worst days to blog are Friday, Saturday and Sunday. Early Monday, the new blog posts come in and bury the weekend posts. The scheduling feature makes it easy to write your blogs at any time of the week and schedule them to show up at the optimum time.

5) The Blog posts page shows the new post with the "Clock" icon and the scheduled publish date and time.

Figure 138 --Scheduled Post

6) We will want to see this blog immediately, so click Publish from the Actions menu. 7) Click the All blogs link.

Figure 139 --Navigating to All Blogs

2012 Falafel Software

140

Sitefinity 5

8) From the Blogs page you can see the new blog has a single post. From here you can Create a post, use the Edit posts link to list all the posts for this blog or use the Actions drop down to Delete, edit the Title & Properties or edit the Permissions.

Figure 140 --Blogs Page

2012 Falafel Software

Content

141

Using RSS Feeds


Using the link to the RSS feed, plug this link into the address bar of your browser. If you don't have the link, the general format is:
http://<base website url>/Feeds/<feed name>

In the example, the link was:


http://localhost:47632/CarConduit/Feeds/classics

Viewing the example in Internet Explorer produces the result in the screenshot below. The blog will be formatted something like this example using Internet Explorer, FireFox and Safari. Google Chrome requires that an RSS Reader extension be configured for the browser.

Figure 141 --RSS Reading

2012 Falafel Software

142

Sitefinity 5

Using Blog Widgets


In this example, we only have a single blog post, but you can have as many blogs and blog posts as you like. You can also use as many Blog Widgets on the page as you need to display listings of multiple blog posts or smaller groups of blog posts. 1) Click the Pages menu item. 2) Create a new child page under the "Welcome" page titled "Blogs", then click the Create and go to add content button. 3) Drag a Blog Posts widget to one of the boxes on the page. Notice that the blog post shows up immediately. This is ok when you only have a single post, but you will need a way to select the blog posts that show. 4) Click the Blog posts widget Edit link. Click the From selected blogs only... option. The Blogs dialog will look similar to the News and Events versions where you have a Content link, a List Settings and Single Item Settings. The Content link lets you show all blogs or only selected blogs. You can narrow down the blogs to a single post or select posts by a combination of categories, tags and dates.

Figure 142 --Blogs Settings

2012 Falafel Software

Content

143

5) Click the Select a blog button. Select the blog you created earlier and then click the Done selecting button.

Figure 143 --Selecting a Blog

6) Click the List Settings link. Click Titles, dates and full content from the List template section. Like News and Events, you can limit the number of items in the list to an exact amount, "page" the items to a certain number of items per page or simply dump out everything on the page at once (not recommended). Use the Sort blog posts drop down to sort by Last published , Last modified , alphabetically or As Set in Advanced mode. List template controls the format of the list so that you can see the entire post at one time or just a "teaser".

7) Click the Save button to close the dialog.

2012 Falafel Software

144

Sitefinity 5

8) Publish and view the page.

Figure 144 --The Finished Blog Post

2012 Falafel Software

Content

145

Documents
Use Documents when you want to include a link to a PDF, Word or other file. These are contained in Libraries. You can also display links to a single document or all documents in a library.

2012 Falafel Software

146

Sitefinity 5

Create Libraries and Documents


1) From the administration menu Content, select the Documents & Files option. 2) Click the Create a library link. 3) Enter the Library name. Click the Click to add a description link and enter some text there.

Figure 145 --Defining the Library

4) Open the Advanced area. You don't want huge file uploaded to the server hard drive. Pick a maximum size, for example 2 MG, per file and enter it as the Max document/file size.

Figure 146 --Lim iting the File Size

2012 Falafel Software

Content

147

5) Click the Create this library button. 6) Click the Upload documents or other files link. 7) Click the Select documents or other files link. 8) Navigate to a Word file and select the file. 9) Click the Add more button and select another type of file. 10)Drop down the Where to store the uploaded documents or other files? list and select the library created in previous steps. 11)Click the Upload and Publish button.

Figure 147 --Starting the Upload

2012 Falafel Software

148

Sitefinity 5

12)Click the View all items button. Sitefinity detects the type of files that are uploaded and places the matching icon.

Figure 148 --Docum ent Item s

13)Click Embed link to this file of the first file in the list. This link can be used to paste into an email or Instant Messenger.

Figure 149 --Retrieving the File Link.

14)Close the window.

2012 Falafel Software

Content

149

Add Document Links to Pages


How do you add a link to a document or show a list of documents on the page? 1) Click the Pages menu item. 2) Open the "Welcome" page for editing. 3) Drag a Document Link widget to the bottom of the page, below any of the other widgets or boxes on the page. This will automatically create a new area on the page. 4) Click the Document Link widget Edit button. This brings up the Insert a document or other file dialog. Click the From already uploaded link. Select one of the files and click the Save button.

Figure 150 --Inserting a Docum ent

5) Click the Preview button. The link displays along with an appropriate icon. Click the document link. Depending on the default behavior and configuration of your browser, the document may display in the browser or prompt to download.

6) Close the preview. 7) Delete the Document Link from the page using the widget's More > Delete link .

2012 Falafel Software

150

Sitefinity 5

8) Drag a Download list widget to the bottom of the page. By default, the list will show all the documents from all libraries. 9) Click the Download List widget Edit button. The layout of this dialog closely matches the dialogs for New, Events or Blogs. You can include all documents, from a selected library or upload new documents. The documents can be sorted Last published, Last Modified, As they are ordered in library and As set in Advanced mode.

Figure 151 --Dow nload List Dialog

10)Click the Settings link to manage the layout details of the widget. There are two areas, 1) Select type and 2) Fine tune the selected type.

2012 Falafel Software

Content

151

The type of layout display as a List with the link at the top of each file.

The Table type arranges the document information in a grid with the link to the right side of each entry.

The last two options display the list or table with a link to a detail page where you can download the file. The screenshot here shows the detail page.

The Fine tune... part of the dialog changes slightly based on the selected type. The section at the top controls the number of files shown at one time. The lower part of the dialog controls whether icons are shown on the page and their size. The two Detail page options have check boxes that place the Download link above or below the description.

2012 Falafel Software

152

Sitefinity 5

11)Click the Save button to close the Download list dialog. 12)Publish and view the "Welcome" page.

2012 Falafel Software

Content

153

Forms
If you want to get information from users, you certainly don't want to wait for a developer to create a form. Using Sitefinity you can create your own form easily, without any programming. The user fills out the form online, clicks the submit button, and the information is stored in the Sitefinity database. How do you access the information sent by hundreds of people? The responses are all visible in the administration Responses list where you can view or export to Excel.

2012 Falafel Software

154

Sitefinity 5

Creating a Form
1) Click the administration menu Content > Forms item. 2) Click the Create a form link. 3) Assign a Title for the form. You can also assign a Name if developers will be using the form. The Name will be filled in automatically based on the Title or you can click the change button and use your own organizations naming convention. Click the Create and go to add content button.

Figure 152 --Form Title

4) The form designer looks very much like the designer for pages, except with a different set of widgets. 5) Drag a Textbox widget to the box area on the form. Sitefinity knows that you will need a submit button to collect the information, so the submit button is added automatically along with the Textbox widget.

Figure 153 --Adding a Textbox Widget

2012 Falafel Software

Content

155

6) Click the Textbox widget Edit link. The Textbox dialog that displays has links for Label and texts for the content and instructional text, Limitations to validate the Textbox input and Appearance to manage the Textbox size and CSS class. In Label and text, enter the following: Label : "Email" Instructional text: "Please enter your email address" Make required : check this box. This will prevent the form from being submitted until this field is filled in.

Figure 154 --Textbox Label and Text

2012 Falafel Software

156

Sitefinity 5

Notes

The Advanced > Name for developers is the ID that a developer can use to access a particular widget in code. For example, if you wanted to send an email when the user clicks the submit button, the email address could be extracted from the Textbox widget and an email sent automatically.

7) In Limitations > Range, enter a Min of "5". In the Error message displayed... enter "Email must be at least 5 characters long". 8) In Appearance > Text box size, drop down the list and select Large. 9) Click the Save button to close the dialog. The form now looks something like the screenshot below.

Figure 155 --The Form In-Progress

10)Drag a Multiple choice widget below the Textbox. Click the Edit link. In Label , enter "Your question is about..." The Choices section will have three choices predefined. Change the text for the First Choice to "Classic Cars" and the Second Choice to "Performance Cars". Click the minus "-" button next to the Third Choice to remove it. Select the Add 'Other' as a last choice check box. Select the Appearance link. In the Text box size options, select Inline (side by side).

2012 Falafel Software

Content

157

Click the Save button. The Multiple choice widget on the page should now look something like the example below.

Figure 156 --Multiple Choice Widget

11)Drag a Paragraph text box widget below the Multiple choice widget. Click the Edit link. In Label and text, enter the following: Label : "Question ". Instructional text: "Please enter your question and include specific details". Make required : This checkbox should be selected. Click the Save button. The form should now look like the screenshot below.

Figure 157 --The Com pleted Form

2012 Falafel Software

158

Sitefinity 5

12)On the upper right side of the form, above the widgets, locate the Settings button and click it. This will display the Settings area to the right of the form. Restrictions can be tailored to the particulars of a form. For example, for an informal poll you could restrict to only One entry per IP, that is, each computer would only be able to submit the form one time. Attempting to submit the form a second time displays an error message to the user. The One entry per username option would be useful if the form collected user registration information. The No Restrictions option makes sense for things like general questions or trouble tickets to a support group. Confirmation options control what the page does when the page is submitted. By default a "success" messaged is displayed on the page. The Redirect to a page... option requires the full Url of the page in the form of:
http://mydomain.com/mypage

The Label placement drop down places widget labels to Top aligned, Right aligned or Left aligned. The screenshot below shows labels left aligned.

13)Click the Publish button.

2012 Falafel Software

Content

159

Adding a Form to a Page


1) Click the Pages menu item. 2) Create a new child page under the "Welcome" page and name it "Q & A". 3) Drag a Form widget to one of the box areas on the page. 4) Click the Select a form link on the Form widget. 5) Select the "Ask CarConduit a Question" form. 6) Click the Done Selecting button. 7) View the "Q & A" form. 8) Click the Submit button without filling out the form. Error messages appears below the Email field to indicate that the field is required and that it must be at least 5 characters long. These errors are in response to the Make Required checkbox and the Limitations Range > Min length setting.

Figure 158 --Validation for the Textbox

9) Fill out the form and submit it.

Figure 159 --Filling out the Form

2012 Falafel Software

160

Sitefinity 5

Viewing Reponses
1) Click the administration menu Content > Forms. Notice the link to 1 responses.

Figure 160 --The Form s List

2) Click the 1 responses link. This takes us to the Responses for... page where we can see the key information about each response. One column shows for every field you added to the form.

Figure 161 --Responses List

3) If you click one of the response items, the detail shows up to the right. This detail includes the date and time the response was submitted and the IP address origin where the response was sent from.

Figure 162 --Responses Detail

2012 Falafel Software

Content

161

4) Click the Export as Excel button. This will prompt for a location on your hard drive where you can save the CSV file for use within Excel. Displaying responses in Excel shows very detailed information that also includes all the form fields.

Figure 163 --CSV Output in Excel

2012 Falafel Software

162

Sitefinity 5

Social Sharing Options


Buttons for sharing most content types can be added automatically simply by selecting a checkbox Enable social share buttons in the content editing dialog.

Figure 164 --Enabling Social Sharing

The screenshot below shows a Content Block with the social share buttons included.

Figure 165 --Content w ith Social Share Buttons

2012 Falafel Software

Content

163

You can configure the buttons that will show up from Administration > Settings > Social Sharing . Select the sharing sites you want included, select the icons style for small icons or Icons with text and finally, click the Save Changes button.

Figure 166 --Configure Social Sharing

2012 Falafel Software

164

Sitefinity 5

Summary
This chapter toured the Content Menu and demonstrated how to work with each type of content. You learned how to create content, how to use widgets to display content in a page and how to configure the widget to fine-tune the layout and behavior of the content.

2012 Falafel Software

6
Permissions

166

Sitefinity 5

Permissions
Use permissions to get fine-grain control over all your Sitefinity assets. A Permission allows a user to perform some action, e.g. edit a page, delete a blog post or make a comment. A Role is a collection of permissions. A User can be assigned one or more roles to obtain the permissions for those roles.

2012 Falafel Software

Permissions

167

Objectives
This chapter explains how the built-in roles are used, how to create a role, how to create a user and how to assign roles to users.

2012 Falafel Software

168

Sitefinity 5

Built-In Roles
Lets first look at the built-in roles that come with Sitefinity. Click the Administration > Roles menu item. These roles cover the major tasks performed in Sitefinity. Administrators can perform any action, anywhere in the system. BackendUsers can login to the Administration "backend" section of the web site. Editors have less privileges than Administrators or BackendUsers but still have wide authority over content. Designers can't do anything with content directly, but have control over pages and templates. With the least amount of privileges, Authors can create content but can't set permissions or perform deletes.

Figure 167 --Built-In Roles

2012 Falafel Software

Permissions

169

Creating a Role
1. Click the Create a role button. In the Role text box that appears, enter "Bloggers" and click the Create button.

Figure 168 --Creating a Role

2. Click the Permissions link for the "Blogger" role.

Figure 169 --Setting Perm issions

3. The extensive list of permissions covers all possible capabilities of a user in Sitefinity. Scroll through the list and notice that, by default, the role has no permissions. Without enabling some permissions, users with this role will not be able view, create, modify or delete anything in the system.

Figure 170 --List of Perm issions for a Role

2012 Falafel Software

170

Sitefinity 5

4. Locate Blogs > BlogPost section of the list. 5. Click the Change button. 6. Enable the View blog post and Modify blog and manage posts check boxes.

Figure 171 --Enabling View and Modify

7. Click the Done button to close the dialog. 8. Click the Back to all items link.

2012 Falafel Software

Permissions

171

Creating a User
1. Select the Administration > Users menu item. 2. Click the Create a user button. This will display the Create a user page. 3. All fields in the first section of the Create a user page are required except for Photo and Nickname.

Figure 172 --Entering Required Inform ation

2012 Falafel Software

172

Sitefinity 5

4. By default, the This user can access site backend option is checked. This actually includes the Backenduser role for this user automatically. Leave this option checked. Also select the new "Bloggers" role.

Figure 173 --Configuring Roles and Access

5. Click the Create this user button. 6. The new user shows up in the Users list.

Figure 174 --New User In List

2012 Falafel Software

Permissions

173

Test the New User


1. Click the Logout link found in the upper right corner of the page. 2. Login as the new user.

Figure 175 --Logging in as the new user

3. Logout and log back in as the new "Blogger" user. Now the administration menu should include both the Dashboard and Content menu items. You should be able to select the Content > Blogs menu item, open the existing blog you created earlier, add blog posts and edit blog posts.

Figure 176 --New User w ith Perm issions

2012 Falafel Software

174

Sitefinity 5

Summary
This chapter explained how the built-in roles are used, how to create a role, how to create a user and how to assign roles to users.

2012 Falafel Software

7
Workflow

176

Sitefinity 5

Workflow
A Workflow is an approval process for publishing documents. By default there are no workflows, so you can publish a document directly without any additional steps. A simple workflow might have just two steps, one to approve the document (perhaps a manager must review before the document is published) and the publishing step itself. For some medical, government or other organization that has a strict hierarchy or protocol for publishing may have many steps in their workflows. Workflows also include notification so that a manager will receive an email that there is something waiting for approval and that the content will not be available without approval.

2012 Falafel Software

Workflow

177

Objectives
In this chapter you'll learn how to define and test a workflow.

2012 Falafel Software

178

Sitefinity 5

Defining a Workflow
To define a workflow: 1) In the Administration menu, click the Settings & configurations > Workflow item. 2) No workflow has been created, so click the Define a workflow link. The Select a type page shows. Leave the default Approval before publishing . Approval before publishing is a single level of approval before the content is published and available on the website. 2 levels of approval before publishing is for organizations that need multiple levels of approval. If you select this option, you need to define the two roles that need to approve the content.

Figure 177 --Selecting a Workflow Type

2012 Falafel Software

Workflow

179

3) Now the Properties page of the workflow definition displays. Enter a Name for the workflow.

Figure 178 --Entering the Workflow Title

2012 Falafel Software

180

Sitefinity 5

In the Set approvers area, select the role that will approve items. Click the Add roles or users button. In the Select roles or users dialog, select the check box next to one or more roles. In this example we check the "Editors" role. Click the Done selecting button to close the dialog.

Figure 179 --Selecting the Roles to Approve the Workflow

2012 Falafel Software

Workflow

181

Back in the Set approvers area, the "Editors" role is included. Also select the Notify users by email when an item is waiting for their approval checkbox. Now, whenever an item has to be approved, everyone who has the "Editors" role will automatically be sent an email. Note that the email format is built-in, but can be changed by a designer.

Figure 180 --The Approvers and Em ail Notification

The Scope section defines where the workflow will apply. Leave the default All content and pages selected. This means that the workflow will be triggered anytime the Save button is clicked for any pages or content.

Figure 181 --Setting the Scope

The last two options for the workflow can be left with their default values. The Allow administrators to skip the workflow is recommended so that you don't have to slog through the approval process when you're making a lot of changes to the backend. Click the Save workflow button.

2012 Falafel Software

182

Sitefinity 5

Notes

For the Notify users by email when an item is waiting for their approval option to work properly, you must set up an SMTP email server at Administration > Advanced > System > SMTP (Email Settings).

2012 Falafel Software

Workflow

183

Testing the Workflow


1. Log out and log back in as the user you created for the previous Permissions example. 2. Edit one of the existing blog posts. 3. Notice there is no Publish button. Instead, click the Save Draft button. 4. Click the new Send for Approval button. Now the list of blog posts shows a new status indicating the content is waiting on approval. A user with an Editor role (or an administrator) can publish the content.

Figure 182 --Blog Waiting for Approval

2012 Falafel Software

184

Sitefinity 5

Summary
In this chapter you learned how to define and test a workflow.

2012 Falafel Software

8
Analytics

186

Sitefinity 5

Analytics
Google Analytics can be run directly in a dashboard without having to leave Sitefinity to study website activity. This dashboard displays using Silverlight, so its highly interactive. You can run the mouse over individual data points for detailed data or use mapping features to locate website activity and drill down for more detail in the Bing map.
Q & A...

Q. Where do I add the tracking code for Google Analytics? A. Register for Analytics and get the Javascript at www.google.com/analytics. You can drag and drop a Scripts and Styles Google Analytics widget onto your page or template. Edit the widget and paste the Javascript snippet.

2012 Falafel Software

Analytics

187

Objectives
In this chapter you will learn how to setup Analytics. A brief survey of the Analytics interface will show you the kinds of web traffic information you can generate and analyze.

2012 Falafel Software

188

Sitefinity 5

Setup
When you first click the Sitefinity Administration Analytics menu item, the First Time Setup and Configuration wizard will display. 1) Select the user that will administer Analytics. Click the Next step button to continue.

Figure 183 --Selecting Adm inistrators

2) Enter your Google Analytics user name and password and click the Get Analytics Accounts button.

Figure 184 --Entering Google Analytics Inform ation

2012 Falafel Software

Analytics

189

3) Select an available Google Analytics account from the drop down list and then click the Save Settings button.

Figure 185 --Selecting an Account

4) Click the Copy in clipboard button to get the JavaScript to be used in the Google Analytics widget.

Figure 186 --Copying the Google Analytics Tracking Code

2012 Falafel Software

190

Sitefinity 5

5) The "How to use" page of the wizard provides a reminder of the next steps you can take, i.e. navigate to Analytics using the Go to Analytics button or clicking the Configuring the Google Analytics widget link for more information.

Figure 187 --How to use Google Analytics

2012 Falafel Software

Analytics

191

Using Analytics in the Administrator


The dashboard provides a high-level overview of all your traffic, including: Number of daily visits Page views Average pages per visit Bounce Rate Average time on site New visits rate Traffic origin, i.e. direct traffic, from search engines, from referring sites.

Figure 188 --Analytics Dashboard

Move the mouse cursor over the data points to get fly-over tooltips with more detail information.

2012 Falafel Software

192

Sitefinity 5

The toolbar on the left holds high-level navigation to the Dashboard, Visitors, Traffic sources and Content. You can drill down into the tree for each of these high-level areas to display more detail. For example, the Visitors > Devices node includes detailed views that focus on Browsers, operating system, Screen colors and resolutions, Flash versions, Java support or mobile devices and carriers.

The Dashboard button bar groups and displays data in multiple views. Use the Map button to see web traffic data presented as geographic data.

2012 Falafel Software

Analytics

193

The map shows web traffic by location, color coded to indicate concentration. Use the Total Map Points buttons to quickly filter based on concentration of map points. A grid below the map (not shown here) lists locations, visits and percentage totals.

Figure 189 --View ing the Map

2012 Falafel Software

194

Sitefinity 5

Summary
In this chapter you learned how to setup Analytics. A brief survey of the Analytics interface demonstrated the kinds of web traffic information that could be generated and analyzed.

2012 Falafel Software

9
Widget Templates

196

Sitefinity 5

Widget Templates
What if you don't like the way a widget is arranged or the content it contains? Widgets Template allow you to tailor a widget to a particular arrangement with custom content.

2012 Falafel Software

Widget Templates

197

Objectives
This chapter demonstrates where you can access widget templates, how to edit the template markup, how to create your own custom templates and how to work with the Administration menu Widget Templates option.

2012 Falafel Software

198

Sitefinity 5

Accessing Widget Templates


There are two places you can access widget templates: From the Administration menu Design > Widget Templates option. The shows the name of the template and where the template is used. For example, the Titles and dates template is used or Applied To the blog post lists. This route allows you to delete widget templates and to change the widgets a template is applied to. Click the Name link to edit the template.

Figure 190 --Adm inistrative Widget Tem plates List

From the Edit link of a widget. Many of the widgets display content in a list will allow you to change either the list or detail layout.

Figure 191 --List Tem plate

2012 Falafel Software

Widget Templates

199

Changing a Template
This next walk-through assumes you already have one or more blog posts created. The blogs should have Tags defined. See Blogs topic for directions on creating Blog content. 1) Drag a Blog Posts widget to a page. 2) Click the Blog Posts widget Edit button. 3) Click the List Settings link. 4) Click the Titles and dates List Template, then click the Edit button.

Figure 192 --Editing a Tem plate

5) The Edit template dialog displays. The dialog has three areas, the HTML markup, the Blogs Insert... menu to the right of the HTML and the Template name below. The HTML markup uses ASP.NET syntax and has special tags that reference Sitefinity data fields. In the screenshot below, data is being brought into the widget for "Title", "Description" and "PublicationDate". The Blogs Insert... menu lists the data that can be dropped right into your widget. To make it easier to use, the list is divided into Common data fields you're likely to use and Other data that lists all possible fields.

2012 Falafel Software

200

Sitefinity 5

The Template name not displayed on the page, but used by Sitefinity to identify the template.

Figure 193 --Editing the Tem plate

6) Place your cursor in the HTML just below the "PublicationDate" field, on line 23 shown in the screenshot below.

Figure 194 --Placing the Cursor

2012 Falafel Software

Widget Templates

201

7) From the Blogs Insert... menu, click the Tags item. Sitefinity creates the markup needed to retrieve the "Tags" field. Click the Insert button to place the markup at the cursor position.

Figure 195 --Inserting the Tags Field

8) Click the Save changes button. 9) Click the Save button. 10)Now the "Tags" are listed below the "Title" and "Publication date'.

Figure 196 --The Updated Widget

2012 Falafel Software

202

Sitefinity 5

Creating a New Template


What happens to your changed template when a new version of Sitefinity is installed? The template may be overwritten by the new installation. The recommended approach is to create a new template that will not conflict with built-in templates. You can copy all the HTML from another template and then add any fields that you want. 1) Click the Blog Posts widget Edit button. 2) Click the List Settings link. 3) Click the Titles and dates List Template, then click the Edit selected template button. 4) Click the Restore template to default button. This rolls back any changes you have made to the original definition stored in the database.

Figure 197 --Restoring the Tem plate

5) Click the confirmation Yes, restore the default version... button. 6) Select all the HTML in the editing window, right-click and select Copy from the context menu. 7) Click the Save changes button. 8) Click the Create New Template button.

Figure 198 --Creating a New Tem plate

2012 Falafel Software

Widget Templates

203

9) Enter a unique, descriptive Template name.

Figure 199 --Assigning Tem plate Nam e

10)Place your cursor in the editing window and paste the HTML from the clipboard. 11)Again, place your cursor in the HTML just below the "PublicationDate" field. 12)From the Blogs Insert menu on the right side, open the Other data section and select the LastModified field. 13)Click the Insert button to paste the generated code into the HTML window. 14)Click the Create this template button. The new template should appear in the list of templates where it can be assigned or edited. 15)Select the new template.

Figure 200 --Selecting a Tem plate

16)Click the Save button. 17)The widget with the new template shows the modified date.

Figure 201 --Using The Widget Tem plate

2012 Falafel Software

204

Sitefinity 5

Managing Widget Templates


Widget templates are managed from the Administration menu Design > Widget Templates option. You should be able to see your new widget in this list, with your login name listed as the Owner. The widgets are grouped into Area and can be sorted by this column. Also notice the Applied To column that indicates where this template should be used.

Figure 202 --Widget Tem plates List

Use the link in the Name column to edit the template. The view of the widget is the same as that for editing a widget on a page, except for one important difference. The template Applied To can be changed from this dialog.

Figure 203 --Changing Where the Tem plate is Applied

2012 Falafel Software

Widget Templates

205

Summary
This chapter demonstrated where to access widget templates, how to edit the template markup, how to create your own custom templates and how to work with the Administration menu Widget Templates option.

2012 Falafel Software

10
Page Templates

Page Templates

207

10

Page Templates
Page templates allow you to have the same basic layout and content across multiple page. For example, you may want every page to have the organization logo in the upper left hand corner and a copyright notice centered at the bottom of the page. You can build all of your page templates entirely in Sitefinity, using drag and drop, without having to use any other tool.

Notes

You can still use Master Pages, but you're not forced to. See the upcoming Master Pages section for more information.

2012 Falafel Software

208

Sitefinity 5

Objectives
In this chapter you'll learn use page templates to establish a basic layout and content across multiple pages. You will add styles to the page template using both the CSS widget and using ASP.NET Themes. Finally, you'll learn how to debug CSS issues.

2012 Falafel Software

Page Templates

209

Creating and Using a Page Template


In this walk-through, we will create a new page template and use the new template to build a page. The template will include content for an organization logo, a drop down list to select languages, a navigation menu widget and a footer with a copyright.

2012 Falafel Software

210

Sitefinity 5

Creating a New Template


1) Access page templates from the Administration menu Design > Page Templates option. The list will show all the built-in templates that you can start with or use as-is. The Title column is a link to edit the template directly without having to use the Actions menu. The Actions menu has options to Delete the template, change the Title, change the Content (edit the template), change Permissions and Base Template (choose a template as a starting point). The Based On column shows if a base template was used as a starting point. To the right of Based On, a column shows the number of pages that use this particular template. You can click this link to see a list of pages that use the template and to preview those pages.

Figure 204 --Tem plates Page

2) Click the Create a template button and enter information about the template Enter the Name of the template. The name should be descriptive of how the template can be used.

2012 Falafel Software

Page Templates

211

Select the Use template option. Click the Select another Template button to choose the "1 Column, Header, Footer" template.

Figure 205 --Create a Tem plate Page

3) Click the Create and return to Templates button. The new template shows up in the list and the Based On column shows that we're using the "1 Column Header, Footer" template as a starting point.

Figure 206 --New Tem plate in Tem plates List

2012 Falafel Software

212

Sitefinity 5

Editing the Template Layout


1) Click the Actions > Content option (or click the title) to edit the template. 2) Click the Layout button. You should see the layout elements from the "Based on" template, i.e. the "1 Column, Header, Footer" template.

Figure 207 --Tem plate Layout

3) From the Drag layout elements area on the right, drag the 25% + 75% element onto the top row of the layout. This should land right on top of the existing layout element.

Figure 208 --Dragging a Layout Elem ent

2012 Falafel Software

Page Templates

213

4) Now the layout should look something like the screenshot below, where the top row is divided into proportions of 25% and 75%.

Figure 209 --Modified Layout

5) Drag the 100% layout element to a point just between the top and second rows. This will create a new row in the layout.

Figure 210 --Adding a Layout Elem ent

2012 Falafel Software

214

Sitefinity 5

6) Now the layout has a top row of 25% x 75% followed by three full rows.

Figure 211 --New Layout

2012 Falafel Software

Page Templates

215

Editing the Template Content


1) Click the Content button. 2) Drag an Image widget to the top row, leftmost element.

Figure 212 --Adding an Im age Widget

3) Click the Edit link. 4) In the Insert an Image entry: Click the Select... button and select a logo image for the upper left corner. Upload the image. In the screenshots that follow, the original image happens to be 300 x 53 pixels. Select Image Size drop down and select "Small: 240px width" from the list. Click the Save button.

Figure 213 --Insert an Im age Dialog

2012 Falafel Software

216

Sitefinity 5

5) Open the Drag widgets Login section and drag the Login name widget to the top row, right side.

Figure 214 --Adding a Login Nam e Widget

6) Click the Edit link of the Login name widget. Scroll down to the FormatString property and change it to "You're logged in as {FirstName} {LastName}". Click the Save button. The page now displays something like the screenshot below.

Figure 215 --Im age and Login Nam e Widgets

Notes

The Login name should float to the right in this layout. See the upcoming Styling section for directions on how to use CSS styling.

7) From Drag widgets > Navigation, drag a Navigation widget to the second row layout element.

2012 Falafel Software

Page Templates

217

8) Click the Edit button of the Navigation widget. In the What type of navigation to use? section, select the Horizontal with drop down menus option. In the Fine tune the selected type section, locate Open drop down menu on and select Mouse over. Click the Save button to close the dialog.

Notes

What if you don't want to display the "Home" page in the navigation, but only the pages that come under home? The "Fine tune" section has an option to display All pages under particular page, where you can use the Select button to choose the "Home" page. If your website is many levels deep, use the Levels to include option to limit the display to only a few levels deep.

9) Drag a Content block widget to the last row of the template. 10)Click the Edit link. Add a Copyright notice for your organization, e.g. "Copyright 2012 Falafel Software". Click the More formatting options button. Place your text cursor just after the word "Copyright", drop down the Insert Symbol list and select the copyright symbol.

2012 Falafel Software

218

Sitefinity 5

Select the text in the editor window, then click the Align Center button.

Click the Save button. 11)Click the Preview button to see the current state of the template.

Figure 216 --Tem plate Preview

Using the New Page Template


1) Select the Pages menu option from the Administration page. 2) From the "Home" page Actions menu, select Change > Template.

Gotcha!

Be aware that changing the template will "pull the rug from underneath" any current page design you already have in place. Changing the template will typically break the layout and you will be starting over for that page. If you want to retain changes, you should create a new page and use the new template there.

2012 Falafel Software

Page Templates

219

3) Select the new custom template. Notice the warning that the template change may break the existing layout for the page.

Figure 217 --Selecting the Custom Tem plate

Tip!

If this template will be used for most of your pages going forward, select the Use the selected template as a default template... option.

4) Click the Done button to close the dialog.

Notes

You can return to an earlier version of the page, before the template was changed, using the Actions menu Revision History item.

2012 Falafel Software

220

Sitefinity 5

5) From the Actions menu, select Content. The home page appears with the template layout and items already showing. Notice that the logo, login name, navigation menu and copyright notice all come from the template and cannot be changed here. You can drag new layout items around the template items, but you can't delete the template items, drag widgets on top of these areas or sub-divide the layout elements.

Figure 218 --The Tem plated Page

2012 Falafel Software

Page Templates

221

Stying
Custom changes to fonts, alignment, background and other appearance changes needs to be applied using styles. Styles can be added: Using the CSS (Cascading Style Sheet) widget. Styles can be added to the widget directly as text or you can link to a CSS file. Using Themes. Themes are collections of CSS that are referenced from Sitefinity administration.

2012 Falafel Software

222

Sitefinity 5

Adding Styles Using the CSS Widget


You can use the CSS widget for quick, ad-hoc styling. You can have as many CSS widgets on the page as you like. The styles defined in the CSS widget are added automatically to the <head> tag of the page. The last example shows the Login name widget text aligned left, much too close to the logo graphic. The following walk-through demonstrates adding a "text-align" style to the page and using the style in a Content block widget. 1) From the Administration menu, select Design > Page Templates. 2) Open the "CarConduit One Column" template created in the previous "Page Templates" section of this courseware. 3) Drag a CSS widget to the page.

Figure 219 --Adding a CSS Widget

2012 Falafel Software

Page Templates

223

Notes

Where you place the CSS widget is not critical to the functioning of the page. The styles in the CSS widget are always added to the page <head> tag. Multiple CSS widgets appear in the <head> tag in the order they're placed on the page.

4) Click the CSS widget Edit link. 5) Take a moment to explore the CSS dialog. If you choose the Link to a CSS file option, use the Select... button to browse to a *.css file within your project. In the Media section, you can select one or more media types that the styles will apply to. CSS files should be located in the \App_Themes folder. The Write CSS option allows you to add styles directly to the page. Styles can be added to the editor window, but be sure to leave out the "<style>" tag. 6) Select the Write CSS option and enter the style below to the window:
.ccLogin { text-align:right; }

7) Click the Save button. 8) Click the Layout button to move into layout mode. 9) Click the Edit link of the layout element that contains the login name. 10)In the Edit layout element section on the right side of the page, click the Classes link.

2012 Falafel Software

224

Sitefinity 5

11)You will see two classes for the already defined for the first and second column of the row. In the Column 2 edit, add a space and then add a new class "ccLogin".

Figure 220 --Adding a Class

Notes

You can also add a class to the entry labeled "Wrapper". "Wrapper" applies to the entire row.

12)Click the Done button. 13)Click the Preview button. The top row, right column text will be aligned to the right side.

Figure 221 --The Style Applied to the Content

2012 Falafel Software

Page Templates

225

Debugging CSS
One of your principal issues will be to find out what CSS classes apply to a particular element on the page. Firebug is a plug-in to the Firefox browser that debugs CSS, HTML, JavaScript and a whole lot more. You can download Firebug from http://getfirebug.com. After installing it, the firebug icon in the lower right hand corner of the browser can be pressed at any time. 1) Paste the URL of a Sitefinity page into the Firefox browser. 2) Click the Firebug icon found in the lower right hand of the browser.

Figure 222 --Starting Firebug

3) The Firebug environment opens up below the web page you're debugging. The HTML tab contains the key tools you'll want to use with Sitefinity. The HTML tab makes it easy to find elements on the page, see the cascading Styles for a given element, the Computed style that's left when the styles have been evaluated, visually work with the Layout for margins/padding and the underlying DOM (Document Object Model) properties for all the elements.

Figure 223 --Firebug and a Sitefinity Page

2012 Falafel Software

226

Sitefinity 5

4) The HTML tab highlights parts of the web page as your mouse hovers above the HTML elements.

Figure 224 --Autom atic Elem ent Highlighting

5) Likewise, you can turn on the element inspector so that as your mouse passes over the HTML markup, the corresponding elements on the page are highlighted. If you're having trouble styling a particular element, this tool will allow you to find the element visually and view the styles that apply to it.

Figure 225 --Turning on the Elem ent Inspector

2012 Falafel Software

Page Templates

227

6) When you find the element you're looking for the Style window shows the styles that apply along with the style sheet file and the line numbers where each style is defined. Styles that are overridden elsewhere in the file are crossed out.

Figure 226 --View ing Elem ent Styles

Tip!

When you pass the mouse over a color or image path, Firebug automatically displays the color or image.

2012 Falafel Software

228

Sitefinity 5

7) You can click any of the values and change them temporarily to "audition" the effect on the page. For example, you could click the color "#EEEEEE" and change it to Red "#FF0000". These changes aren't retained, but you can try them out and copy the changes to the style sheet later.

Figure 227 --Changing the Color Attribute

That should get you started with Firebug as it applies to Sitefinity. For more information, see the getfirebug.com website for documentation and tutorials.

2012 Falafel Software

Page Templates

229

Summary
In this chapter you learned how to use page templates to establish a basic layout and content across multiple pages. You added styles to the page template using both the CSS widget and using ASP.NET Themes. Finally, you learned how to debug CSS issues.

2012 Falafel Software

11
Responsive Web Design

Responsive Web Design

231

11

Responsive Web Design


Your web design is expected to look good on standard desktop displays, iPhones, Androids, tablets or any device used during the life of your website. Sitefinity automatically arranges the layout of the screen based on the current screen characteristics (i.e. screen size, device to pixel ratio, orientation, etc). If your large, browser-based layout takes up three columns from side to side, the iPhone can view the same content running in a single column. You can even customize font properties or swap images based on the current screen characteristics. Sitefinity implements Responsive Web Design automatically, using rules to define the characteristics to look for (e.g. 240-320 pixels in width like the HTC Wildfire) and how your site should react (e.g. transform the layout, redirect to another site, load a special css).

Notes

Under the hood, Sitefinity uses CSS media queries to get information about the screen minimum width and orientation. For more background information, check out Ethan Marcotte's seminal blog Responsive Web Design.

2012 Falafel Software

232

Sitefinity 5

Objectives
In this chapter you'll learn how Responsive Web Design helps your application react to device sizes ranging from full-sized desktop or notebook screens to the smallest of handheld devices. You'll learn how to define rules that react to different screen configurations, how to make basic layout changes based on those configurations and how to fine tune all aspects of the page using styles.

2012 Falafel Software

Responsive Web Design

233

Creating Rules
The first step is to create rules for the scenarios you expect to encounter. In our example, we'll create "Small" and "Large" versions of a simple website, but you can make rules for as many detailed cases as you want. Typically you'll want to cover small "Smart phone" screens, tablets and large notebook/desktop screens (1024px or higher). This next example starts with a simple set of three columns filled with images and text.

Figure 228 --The Initial Web Design

2012 Falafel Software

234

Sitefinity 5

To begin making this a responsive web site: 1. From the Sitefinity menu, select Design > Responsive and Mobile design. 2. Click the Create a group of rules button. 3. Enter a Name for the group of rules.

Figure 229 --Entering the Rule Nam e

4. Select device characteristics using the presets from the drop down list. For this example step, choose the "Smartphones" option.

Figure 230 --Setting the Device Characteristics

5. Leave the defaults for Apply behavior to... and Specific CSS file options.

2012 Falafel Software

Responsive Web Design

235

6. In the System settings: Fine tune default layout elements section, select the vertical arrangement of rows for each option. For example, where the default is "2 columns", select "2 rows".

Figure 231 --Tuning Layout

7. Leave the This group of rules is active checkbox selected and click the Done button.

2012 Falafel Software

236

Sitefinity 5

Previewing the Results


You can preview the results by simply resizing the browser to see the results. To get a better feel for how your site will look in a phone or tablet, click the More actions > Preview for Smartphones and Tablets option.

Figure 232 --Preview ing the Layout

From here you can look at the site as it will appear in iPhone 4, HTC HD2, HTC Incredible, iPad 2 and Samsung Galaxy Tab in Portrait or Landscape orientations. The iPhone Portrait view shows the content for the three columns stacked vertically.

Figure 233 --iPhone Portrait View

2012 Falafel Software

Responsive Web Design

237

Device Characteristics
Sitefinity predefines a set of device characteristics that will trigger layout changes. The likely suspects are listed there, but you can add your own rules to help "future proof" your site.

Figure 234 --Device Characteristics

2012 Falafel Software

238

Sitefinity 5

Click the Details button next to the "iPhone 4s" entry to configure the specifics that make up a rule. You can trigger rules based on the Size or Size range, the Orientation, Aspect ratio and Resolution. You can even trigger rules if the device is an old-school monochrome or grid-based device, e.g. teletypes, terminals or portable devices with limited display capabilities. As you change the settings, a media query is built dynamically in the Result area at the base of the dialog.

Figure 235 --Defining a Custom Rule

2012 Falafel Software

Responsive Web Design

239

Adding New Behaviors


Changing layout gets you part way there, but you may need to perform detailed styling of fonts, hide or show images, change margins or obscure elements that don't work with a particular device. There are two ways to handle these detailed changes: Apply behavior to Open a specially prepared site (e.g. a mobile version of your site). This is less flexible than using style sheets and may result in multiple sites being created as new device types come online. The advantage is that you can customize the site very specifically for each device type. To go this route, select the Open a specially prepared site option, then select the Root page of the specially prepared site.

Figure 236 --Routing to a Specially Prepared Site

If you select Apply Behavior to Transform the layout, you can choose a CSS file that will come into play when certain devices are detected.

Figure 237 --Transform ing the Layout

2012 Falafel Software

240

Sitefinity 5

Using a CSS file option, the page is still single source, but styles are applied to customize the page for each situation. The example below uses a stylesheet to control the look of the full sized web page. The screenshot shows a full size banner graphic that stretches across all three columns.

Figure 238 --Full Sized Page

When the browser size is reduced to trigger the "Small" set of rules, the "small.css" file kicks in and a reduced sized graphic displays at the top of the page. Notice that the small "smart phone" version of the page also uses a different font and font color than the larger version.

Figure 239 --Sm art Phone Layout

2012 Falafel Software

Responsive Web Design

241

Here's an example of the small.css file.


.banner_small { display:block !important; } .banner_large { display:none !important; } .threeImage { margin-top:30px; !important; margin-bottom:0px !important; margin-left:0px !important; } h3 { margin-top:0px; !important; margin-bottom:0px !important; } .blurb { color:#3060A0 !important; font-weight:bold !important; margin-top:0px !important; margin-bottom:0px !important; }

...and the large.css file:


.banner_small { display:none !important; } .banner_large { display:block !important; margin-bottom:20px !important; } .threeImage { margin-top:0px; !important; margin-bottom:0px !important; margin-left:0px !important; } h3 { margin-top:0px; !important; margin-bottom:0px !important; } .blurb { font-family: Arial !important; margin-top:0px !important; margin-bottom:0px !important; }

2012 Falafel Software

242

Sitefinity 5

Summary
In this chapter you learned how Responsive Web Design helps your application react to device sizes ranging from full-sized desktop or notebook screens to the smallest of handheld devices. You learned how to define rules that react to different screen configurations, how to make basic layout changes based on those configurations and how to fine tune all aspects of the page using styles.

2012 Falafel Software

12
Working with Master Pages

244

Sitefinity 5

12

Working with Master Pages


Master pages are the file-based standard that ASP.NET uses for templating. Master pages also have C# or VB.NET code behind unlike the Sitefinity template counterpart. If you want to use custom .NET coding, Master pages are the way to go. Whenever possible, use the built-in Sitefinity tools to sculpt the page layout look-and-feel. The only time you really need to use an external ASP.NET Master Page is to allow codebehind. For example, if you need to access an external web service.

2012 Falafel Software

Working with Master Pages

245

Objectives
In this chapter you'll learn how Master pages work together with the page template and theme. You'll see how to use a Master page from the marketplace and how to "slice-anddice" third party templates to integrate them in your web site.

2012 Falafel Software

246

Sitefinity 5

Masterpage Overview
Using Master pages inside a Sitefinity website involves three main pieces: The Master Page itself. The Master page file and its associated code-behind live in the Visual Studio project. The Theme contains styles and is stored in the Sitefinity database. The Sitefinity Template is also stored in the Sitefinity database. The template ties together the Master page and the Theme. The template is "based on" the Master page and the theme is applied to the template.

2012 Falafel Software

Working with Master Pages

247

Using a MasterPage from the Marketplace


The predefined themes on the Sitefinity Marketplace web site give you a jump on development by providing both the theme and the master page layout, all in one place. The walk-through that follows demonstrates how to integrate the "SolarFlare" master page and theme into your web site.

Figure 240 --The Sitefinity Marketplace

The Game Plan


The steps to using an existing themed master page from the Sitefinity Marketplace are: 1) Download the Theme 2) Add the Theme to the Solution 3) Define the Theme Setting 4) Create the Sitefinity Template 5) Use the Theme

2012 Falafel Software

248

Sitefinity 5

Downloading the Theme


1) In a browser, navigate to http://www.sitefinity.com/marketplace/themes.aspx. 2) Locate the SolarFlare link and click it. 3) Click the Download from Publisher button.

Figure 241 --Dow nloading SolarFlare

4) Save the "SolarFlare.zip" file to a location on your local drive. 5) Unzip the "SolarFlare.zip" file.

2012 Falafel Software

Working with Master Pages

249

Adding the Theme to the Solution


The recommended directory structure for master pages, themes and widget templates is shown in this outline: \App_Data\Sitefinity\WebsiteTemplates \App_Master \App_Themes \<my theme> \Global \Images \Styles

1) In the Solution Explorer, open the \App_Data folder. 2) Right-click the \Sitefinity folder, and select Add > New Folder from the context menu. Name the new folder "WebsiteTemplates".

2012 Falafel Software

250

Sitefinity 5

3) In the Windows File Explorer, locate your unzipped "SolarFlare" folder and drag it onto \WebsiteTemplates. The resulting folder structure should look exactly like the screenshot below.

Figure 242 --Directory Structure

Gotcha!

Make sure you're in the \App_Data\Sitefinity folder, not the \Sitefinity folder in the root of the project.

4) Save the solution.

2012 Falafel Software

Working with Master Pages

251

Defining the Theme Setting


1) In the Sitefinity Administration menu, navigate to Administration > Settings > Advanced > Appearance > Frontend Themes. 2) Click the Create New button. 3) Enter a Name for the theme and the exact Path , as shown in the screenshot below. This path must exactly match the directory structure in the Solution Explorer, starting with the "~" to indicate the project root. The actual theme folder is named "Green" in this example.

Figure 243 --The Frontend Them e Setting

4) Click the Save Changes button.

2012 Falafel Software

252

Sitefinity 5

Creating the Sitefinity Template


1) In the Sitefinity Administration menu, select Design > Page Templates. 2) Click the Create a Template button. 3) Set the Name to be "SolarFlare". 4) Click the Use Template radio button. 5) Click the Select another Template button. 6) In the Select a Template dialog, click the Use your own .master file button. 7) In the Select a masterpage dialog, click the Browse other folders button. 8) Select the SolarFlare.master file in the directory tree, then click the Use Selected button.

Figure 244 --Selecting the Master File

9) Back in the Create a template screen, click the Create and go to add content button.

2012 Falafel Software

Working with Master Pages

253

10)Click the Theme button. 11)Select the SolarFlare theme from the drop down list. 12)The SolarFlare theme graphics should display in the template. Click the Publish button.

Figure 245 --The SolarFlare in the Tem plate

2012 Falafel Software

254

Sitefinity 5

Using the Theme


1) Select Pages from the Sitefinity Administration menu. 2) Create a new page and go to editing content. 3) Click the Layout button. 4) Click the Select another template... button. 5) In the Select a template dialog, select the SolarFlare template and click the Done button.

Figure 246 --Selecting the Tem plate

6) Click the Create and go to add content button. 7) The SolarFlare graphics should now display in the page.

Figure 247 --The Page Using SolarFlare Tem plate

2012 Falafel Software

Working with Master Pages

255

8) Publish the page.

2012 Falafel Software

256

Sitefinity 5

Editing 3rd Party Templates


While the Marketplace themes are constructed specifically for Sitefinity consumption, you can also download hundreds of CSS templates from various sites on the web such as http://www.freecsstemplates.org. You will need to perform some "surgery" to make the theme useful in Sitefinity. For this example we will use the "index.html" file from the CarConduit Template as raw material for a master page. "CarConduit Template" is included along with the projects for this Courseware. Using Master pages inside a Sitefinity website involves three main pieces: The Master Page itself. The Master page file and its associated code-behind live in the App_Master folder of the Visual Studio project. The Theme contains style related files, i.e. css, JavaScript and images. The Sitefinity Template is stored in the Sitefinity database. The template ties together the Master page and the Theme. The template is "based on" the Master page and the theme is applied to the template.

Prepare the Project


1) In Visual Studio, create the following folder structure: \App_Data\Sitefinity\WebsiteTemplates \App_Master \App_Themes 2) In the Visual Studio, right-click the App_Master folder and select Add > New Item > Master Page. 3) Name the file CarConduit.Master and click the Add button. 4) Copy the contents of "index.html" from the CarConduitTheme folder and paste the HTML into "CarConduit.Master", completely overwriting the existing html. 5) In the Visual Studio, right-click the App_Themes folder and select Add > New Folder. Name the folder "CarConduit". 6) Copy the "css", "images", "js" directories and the "home.png" file to the \App_themes\CarConduit folder. Rename the "css" folder to "global".

2012 Falafel Software

Working with Master Pages

257

Notes

Sitefinity is looking for the "global" name specifically, to find the css files.

7) Now the directory structure should look like the screenshot below.

Figure 248 --Final Folder Structure

2012 Falafel Software

258

Sitefinity 5

Perform Masterpage "Surgery"


In Visual Studio, edit CarConduit.Master to work with Sitefinity. 1) Remove everything from the inside of the <head> tag. Sitefinity will take care of meta tags and style sheet references for us, so the <head> tag elements are not needed. You will need the <head> tag itself, so do not remove it. 2) Add the attribute runat="server" to the <head> tag. Sitefinity needs to access the head tag at the server and failing to do this will cause a "yellow screen of death" error. 3) In Visual Studio, press Ctrl-F and search for "<form". This will bring you to a <form> used to contain the search for the page. Remove the <form...>, </form> tags and the contents within the form tags. 4) Add a <form> tag inside the <body>. Be sure to add the runat="Server" attribute. It's also good practice to include an ID attribute for the <form> tag. The markup in CarConduit.Master should now look something like the screenshot below.

Figure 249 --Masterpage Markup

5) Replace the hard-coded copyright notice at the base of the page with a placeholder. In Visual Studio, press Ctrl-F and search for "footercredits". This will bring you to a <div> tag. Remove the copyright text from inside the tag. From the Toolbox, Standard section, drag a ContentPlaceHolder control to a point inside the "footercredits" <div> tag. Change the ID of the tag to "MyCopyright". The html markup should look something like the example below:
<div id="footercredits"> <asp:ContentPlaceHolder ID="MyCopyright" runat="server"> </asp:ContentPlaceHolder> </div>

2012 Falafel Software

Working with Master Pages

259

Gotcha!

Be sure to use ContentPlaceHolder, not Placeholder.

6) Build the project.

Defining the Theme Setting


1) In the Sitefinity Administration menu, navigate to Administration > Settings > Advanced > Appearance > Frontend Themes. 2) Click the Create New button. 3) Enter the Name "CarConduit". 4) Enter the Path "~/App_Data/Sitefinity/WebsiteTemplates/CarConduit/App_Themes/ CarConduit".

Figure 250 --CarConduit Them e Settings

5) Click the Save Changes button.

2012 Falafel Software

260

Sitefinity 5

Create Template and Apply Theme


The next step is to create a template that is based off the masterpage. 1) From the Sitefinity administration, select Design > Page Templates from the Sitefinity menu. 2) Click the Create a Template button. 3) In the Name section enter CarConduit Using Master . 4) In the Template section select Use template. Click the Select another Template button. 5) The Select a template dialog displays. Click the Use your own .master file button. 6) Click the Browse other folders link. 7) Navigate to \App_data\Sitefinity\WebsiteTemplates\App_Master and select CarConduit.Master. Click the Use Selected button.

Figure 251 --Selecting the Master

8) Click the Use Selected button to close the dialog and return to the Create a template page.

2012 Falafel Software

Working with Master Pages

261

9) Click the Create and return to templates button. The new template will show up in the list with the Based On column showing the masterpage in use.

Figure 252 --New Tem plate Using Master

10)Open the new template by selecting Actions > Content. The HTML from the masterpage displays but the effect is ugly because styles have not been applied.

Figure 253 --Tem plate With Masterpage But No Them e

11)Click the Theme button.

2012 Falafel Software

262

Sitefinity 5

12)Select CarConduit from the drop-down list found under the Set theme section on the right hand side. The styles now merge with the masterpage used in the template. Several images are broken because the paths were hard-coded. We could repair these, but we will be replacing most of the images with ContentPlaceHolder controls.

Figure 254 --Using the Them e

13)Scroll to the bottom of the template to where the copyright notice should be. Where the ContentPlaceHolder was added, a new layout element area is ready to accept widgets.

Figure 255 --Tem plate, Masterpage and ContentPlaceholder

14)Click the Publish button to make the template available for use in pages.

2012 Falafel Software

Working with Master Pages

263

Use the Template


The area created by adding a ContentPlaceHolder looks and acts the same as any layout area in a template. In this next walk-through, we will create a page that uses the new template and adds content to the copyright notice layout area at the bottom of the page. 1) Select Pages from the Sitefinity menu. 2) Click the Create a Page button. 3) In the Name section enter Welcome. 4) In the Template section, click the Use template radio button. Click the Select another Template button. 5) Select the CarConduit Using Master custom template, then click the Done button.

Figure 256 --Selecting the Tem plate

6) Click the Create and go to add content button. 7) Scroll to the bottom of the page. 8) Drag a Content block widget to the layout area at the bottom of the page. 9) Click the Edit link. 10)Enter a copyright notice. In the editor window enter Copyright <your organization><current year> .

2012 Falafel Software

264

Sitefinity 5

Click the More formatting options button. Place the text cursor just to the right of "Copyright". Drop down the list of symbols and select the copyright symbol. Click the align-center button. 11)Click the Save button.

Figure 257 --Testing the Tem plate

2012 Falafel Software

Working with Master Pages

265

Master Page Surgery Tips


To make the template general-purpose, add ContentPlaceHolder controls to any area of the masterpage you'll want to customize later. Try to remove any formatting markup that might limit you in the future. When you get done replacing various areas of the page, the master page becomes much smaller, only consisting of structural markup. You can also remove Javascript from the masterpage because the widgets will supply script for things like menu hover behavior. Once the general areas are setup in the masterpage, use the template in Sitefinity to further subdivide layout elements and to add common content. Develop the layout to fit your requirements, then create areas for customization using the ContentPlaceHolder control. The example below is a simplified version of the CarConduit masterpage. Several rows have been removed for the sake of example.

2012 Falafel Software

266

Sitefinity 5

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"></head> <body> <form runat="server" id="MyForm"> <div id="wrapper"> <div id="header"> <a class="logo" href="#">Site Home</a> <div id="navContainer"> <asp:ContentPlaceHolder ID="MyNavigation" runat="server" /> </div> </div> <div id="content"> <asp:ContentPlaceHolder ID="MyContent" runat="server" /> </div> <div id="footer"> <div class="one-fourth"> <div class="footer-widget"> <h3>Testimonials</h3> <div class="testimonial-widget"> <asp:ContentPlaceHolder ID="MyTestimonials" runat="server" /> </div> </div> </div> <div class="one-fourth"> <div class="footer-widget"> <h3>Recent Comments</h3> <asp:ContentPlaceHolder ID="MyComments" runat="server" /> </div> </div> <div class="one-fourth"> <div class="footer-widget"> <h3>Recent Posts</h3> <asp:ContentPlaceHolder ID="MyPosts" runat="server" /> </div> </div> <div class="one-fourth last"> <div class="footer-widget"> <h3>Categories</h3> <asp:ContentPlaceHolder ID="MyCategories" runat="server" /> </div> </div> <br class="break" /> <div id="footercredits"> <asp:ContentPlaceHolder ID="MyCopyright" runat="server" /> </div> </div> </div> </form> </body> </html>

2012 Falafel Software

Working with Master Pages

267

The compiled template looks like the screenshot below. The masterpage ContentPlaceHolder controls supply areas for the upper right hand side navigation menu, a content area below that and sections for "Testimonials", "Recent Comments", "Recent Posts" and "Categories". The area at the bottom of the page is intended as a space for the copyright notice but could hold other page footer content.

Figure 258 --The Tem plate

2012 Falafel Software

268

Sitefinity 5

Tip!

The titles in the footer for "Testimonials", "Recent Comments", etc., have been hardcoded to make it easier for this exercise. Just the same, you could swap out all those titles with more ContentPlaceHolder controls. Later, if "Categories" had to be changed to "Tags", someone without Visual Studio experience could still change the content using Sitefinity alone.

Now that your template holds your masterpage and theme, you can simply drop widgets into any page that uses the template. Here is an example of the "Welcome" page created earlier with additional content. To show something of interest in the navigation menu, the "About Us", "Blogs" and "News" pages have been copied underneath the new "Welcome" page. The logo image is directly from the masterpage markup, while the menu is a Navigation widget dropped into the page. Below those two items, the Image Gallery widget displays a list of images along with detail for one image. Below the Image Gallery, "Testimonials" and "Recent Comments" are placed using a simple Content widget. "Recent Posts" uses a News widget and the "Popular Tags" area holds a Classification > Tags widget.

Figure 259 --Page Using Tem plate With Masterpage

2012 Falafel Software

Working with Master Pages

269

Summary
In this chapter you learned how Master pages work together with the page template and theme. You saw how to use a Master page from the marketplace and how to "slice-anddice" third party templates to integrate them in your web site.

2012 Falafel Software

13
Developing in Sitefinity

Developing in Sitefinity

271

13

Developing in Sitefinity
Using only the Sitefinity Administrator you can do many things, but what if you need to work with your Sitefinity data programmatically? For example, convert records in an Oracle database to a set of blog posts, or create pages in a user interface you build in a Windows form or WPF? The Sitefinity API can help with one-time migration tasks, building interfaces to consume Sitefinity, custom content entry interfaces or just about anything you can visualize.

2012 Falafel Software

272

Sitefinity 5

Objectives
In this chapter you will learn the basics for getting started with Sitefinity development. You'll learn what basic flavors of the API are available to you and how to work with the API in Visual Studio.

2012 Falafel Software

Developing in Sitefinity

273

What Flavor API?


There are three ways of working with Sitefinity programmatically: Using the Sitefinity API. This is the full-featured API that provides the deepest set of features for controlling Sitefinity functionality. Use the Sitefinity API to access everything that Sitefinity has to offer. Here is an example of the Sitefinity API that returns all blog posts:
BlogsManager manager = BlogsManager.GetManager(); IQueryable<BlogPost> blogs = manager.GetBlogPosts();

The Fluent API: this is a wrapper around Sitefinity API that surfaces the most commonly used features in an elegant, LINQ friendly syntax. Use this language feature to be productive quickly.
var blogs = App.WorkWith().BlogPosts().Get().ToList();

Using Sitefinity REST services opens the door to any client platform that can hit a URL including Linux, Windows, Mac, IWhatever (iPad, iPhone), Silverlight, WPF, Flash, Android, etc. REST services allow you to list any information on the site and perform CRUD (Create, Read, Update, Delete) operations on the data you find there. Sitefinity REST services can communicate in XML or JSON (for easy access in JavaScript client code). The example below brings back a list of all blog posts in XML format from "<my site>".
http://localhost:12345/<my site>/sitefinity/services/Content/BlogPostService.svc/xml

2012 Falafel Software

274

Sitefinity 5

Getting Started with Sitefinity Development


Now that you've seen a few basic examples of the Sitefinity API and the Fluent API, you may wonder "Where do I put this code?". You can code directly against your Sitefinity web site simply by adding a standard ASP.NET page and adding API code to the page.

Prepare the Sitefinity Project


In this example we will use the Sitefinity API to provide a list of pages in the site. This walk-through assumes you already have a Sitefinity web site created. 1) Open a Sitefinity web site in Visual Studio, from the Sitefinity Project Manager by clicking the Edit in Visual Studio button.

Figure 260 --Editing the Sitefinity Project in Visual Studio

2012 Falafel Software

Developing in Sitefinity

275

2) In the Visual Studio Solution Explorer, right-click the SitefinityWebApp project and select Add > New Folder from the context menu. Rename the folder to "My Pages".

Figure 261 --Adding the New "My Pages" Folder

3) Right-click the "My Pages" folder and select Add > New Item... from the context menu. In the Add New Item dialog, select the Web > Web Form item and set the Name to "MyPagesList.aspx". Click the Add button to create the page and close the dialog.

Figure 262 --Adding an ASP.NET Page

2012 Falafel Software

276

Sitefinity 5

Use the API to List Pages


1) In the aspx markup for the page, add a standard ASP.NET ListBox.
<asp:ListBox ID="ListBox1" runat="server" Height="300px" Width="200px"></asp:ListBox>

2) In the code behind for the page, add the code below to the Page_Load event handler.
protected void Page_Load(object sender, EventArgs e) { PageManager manager = PageManager.GetManager(); var list = manager.GetPageDataList().ToList(); ListBox1.DataSource = list; ListBox1.DataTextField = "Title"; ListBox1.DataBind(); }

The first step is always to get the "manager" object for the part of the API we're working with. The static GetManager() returns a single instance of the PageManager . From there, you can call any of the many methods of the manager object to accomplish your task. In this example, the GetPageDataList() method returns a list of PageData objects containing header and page level information. You can iterate this information or use it to bind directly to a control. 3) In the Solution Explorer, right "MyPageList.aspx" and select Set as Start Page from the context menu. The running application will display the list box with whatever pages you have published in your site. Notice that the list contains pages with blank titles, front end pages and back end pages.

Figure 263 --Unfiltered List of Pages

2012 Falafel Software

Developing in Sitefinity

277

4) To show only for the backend pages you can use LINQ statements to filter the list before binding to the list box. Add the Where() statement to the end of your GetPageDataList() method call. This will check that the PageData IsBackendPage is false for every PageData in the list.
var list = manager.GetPageDataList().ToList() .Where(p => p.IsBackendPage == false); // <-- add this statement

5) Re-run the project. Notice that only your front end pages are listed.

Figure 264 --Filtered List of Pages

2012 Falafel Software

278

Sitefinity 5

Sitefinity Projects in Visual Studio


A Sitefinity web site is really an ASP.NET web site at its heart and can be worked with just like any other ASP.NET web site. The major difference is that page creation is performed automatically using information from the database. You can open a Sitefinity web site in Visual Studio, from the Sitefinity Project Manager.

Figure 265 --Editing the Sitefinity Project in Visual Studio

The first thing to notice is that we have opened a web application project, not a web site. A web site is a loose collection of files, but a project is managed as a whole and compiled into a single DLL assembly. There is one default.aspx page in the project to keep IIS happy, but all the pages actually used in the project are stored in the database. As a result of page storage in the database, the project structure will not change much as the content grows.

Figure 266 --The Sitefinity Web Project

2012 Falafel Software

Developing in Sitefinity

279

Configuration
In past versions of Sitefinity, the "web.config" file was huge, but the Sitefinity architecture has moved all of the Sitefinity-specific configuration to separate XML files for easier handling. Only ASP.NET related configuration is left in the web.config. This architecture is easier to maintain and also handles updates better, even if the web.config is overwritten. All these files are written to from the Sitefinity back end administration, but you can find the XML files in \App_Data\Sitefinity\Configuration. To make the Configuration folder visible in the Visual Studio Solution Explorer, you will need to select the project folder, then click the Show All Files button.

Figure 267 --Sitefinity Configuration Files

2012 Falafel Software

280

Sitefinity 5

Developing with Thunder


Sitefinity Thunder is a Visual Studio plug-in that helps organize and build Sitefinity applications. The Thunder plug-in includes an explorer that navigates Sitefinity items in the project, new Sitefinity project items (widgets, designers and themes) and the ability to register existing widgets automatically. At the time of this writing, you can install the Thunder beta from the Visual Studio Gallery or use the Visual Studio Tools > Extension Manager menu option to download and install the Thunder plug-in.

2012 Falafel Software

Developing in Sitefinity

281

Summary
In this chapter you learned the basics for getting started with Sitefinity development. You learned about the basic flavors of the API that are available to you and how to work with the API in Visual Studio.

2012 Falafel Software

14
Using the Sitefinity API

Using the Sitefinity API

283

14

Using the Sitefinity API


The Sitefinity API provides a full set of services over Sitefinity web sites. Later, you'll learn about Using the Fluent API, where the Fluent API is a subset of the Sitefinity API.

2012 Falafel Software

284

Sitefinity 5

Objectives
This chapter explains how to work with the Sitefinity API. First you'll learn how to create a Sitefinity page programmatically and then how to display the hierarchy of pages in a tree view. You'll also create content programmatically and perform CRUD (Create Read Update Delete) operations against content items. Finally, you will add a programmatically created content item to a page, on-the-fly.

2012 Falafel Software

Using the Sitefinity API

285

Working with Pages


Why use code to work with pages? You may want to read from an outside table or site map and create pages programmatically. You may be porting material from some legacy system. You could also modify all the pages on the site in a batch, e.g. read and modify the keywords for all pages in the system.

Tip!

Create your own set of tools to take with you when you work at other sites. For example, utility classes or functions that iterate and modify pages, create new pages, look for specific keywords, locked pages, empty keywords and so on.

Creating a Page Programatically


Creating a page at runtime involves the following: PageData represents the Titles and Properties information for the page. PageNode contains the actual instance of the page. You create both of these in code and then assign the PageData to a property of the PageNode. 1) In Page_Load of an ASP.NET page in the Sitefinity project, add code to get the currently running singleton instance of the PageManager and turn off security checks.
PageManager pageManager = PageManager.GetManager(); pageManager.Provider.SuppressSecurityChecks = true;

2) Then add the PageData to represent header information about the page.
// create the PageData corresponding to "Titles and Properties" PageData pageData = pageManager.CreatePageData(); pageData.HtmlTitle = "CarConduit Blogs Title for Search Engines"; pageData.Title = "CarConduit Blogs"; pageData.Description = "CarConduit Blogs Description"; pageData.Keywords.Value = "Cars,Autos,Collectors"; pageData.Status = ContentLifecycleStatus.Live;

The PageManager CreatePageData() method returns a PageData instance. Use the PageData instance properties to set all the entries you normally see in the Titles and Properties for the page.

2012 Falafel Software

286

Sitefinity 5

3) Add the code below to assign the "Left Sidebar, Content" template.
pageData.Template = pageManager.GetTemplates() .Where(t => t.Title.Equals("Left Sidebar, Content")) .FirstOrDefault();

The page uses the default layout template if the PageData.Template property is not assigned. Use the PageManager.GetTemplates() method to list all possible templates you can assign. The LINQ expression compares against the Template Title property. 4) Add the code below to create a page instance.
// create the page instance as a child of the root node PageNode pageNode = pageManager.CreatePageNode(); PageNode parentNode = pageManager.GetPageNode(SiteInitializer.FrontendRootNodeId); pageManager.ChangeParent(pageNode, parentNode); pageNode.UrlName = "CarConduitBlogs"; pageNode.ShowInNavigation = true;

In particular, notice the reference returned by GetPageNode(). GetPageNode() passes a SiteInitializer (from the Telerik.Sitefinity.Abstractions namespace) property called FrontendRootNodeId. This is a Guid that identifies the site's root node. The PageManager ChangeParent() method makes the root node the parent for the page we're creating. 5) To marry the PageData to the PageNode, assign the PageNode.Page property, then save the changes. To publish the page, send a message through the WorkflowManager.
pageNode.Page = pageData; pageManager.SaveChanges(); // pub lish through the workflow WorkflowManager.MessageWorkflow(pageNode.Id, typeof(PageNode), null, "Publish", false, new Dictionary<string, string>());

2012 Falafel Software

Using the Sitefinity API

287

6) Run the application, then navigate to the Sitefinity Administrator Pages to view the new page.

Figure 268 --View ing the New Page

7) Select the Actions > Title & Properties link. The properties values set by the PageNode and PageData all show up in the Titles & Properties page.

Figure 269 --Title & Properties

2012 Falafel Software

288

Sitefinity 5

Tip!

To park your new page underneath some other node, you need to get its Guid identifier. Use the GetPageNodes() method to return all page nodes, then use LINQ to filter out the page you want to use as a parent. Each PageNode has an Id property -- a Guid suitable for passing to the ChangeParent() method.
PageNode homePageNode = pageManager .GetPageNodes() .Where(n => n.Title.Equals("Home")) .FirstOrDefault(); pageManager.ChangeParent(pageNode, homePageNode);

Now the tree of pages displays the new "CarConduit Blogs" page under the "Home" page instead of as a sibling.

Figure 270 --New Page Listed Under Hom e

2012 Falafel Software

Using the Sitefinity API

289

Show Hierarchy of Pages


While the PageData class knows about the header information for the page, the actual page instance is encapsulated in a PageNode object. Each PageNode has an Id Guid property that identifies it and a Parent property that itself is a PageNode. Using the Manager's GetPageNodes() method we can retrieve the nodes for all the pages in the web site and display them as a tree. The example below displays page titles in a RadTreeView control. 1) Drag a RadTreeView from the Toolbox onto an ASP.NET page. 2) In the Page_Load event handler, add the code below. There are a few things to note in the example below. We aren't handling security directly in this example, so we need to set the SuppressSecurityChecks property true to avoid security exceptions. The Select () clause projects the elements of the PageNode into something more compatible with the RadTreeView. RadTreeView expects a DataFieldID for the current node and a DataFieldParentID to point at the id for its parent. For root nodes, the PageNode.Parent object is null, so we check for that and pass Guid.Empty in those cases.
protected void Page_Load(object sender, EventArgs e) { PageManager manager = PageManager.GetManager(); manager.Provider.SuppressSecurityChecks = true; var list = manager.GetPageNodes() .ToList() .Select(p => new { Id = p.Id, ParentId = p.Parent == null ? Guid.Empty : p.Parent.Id, Title = p.Title }); RadTreeView1.DataSource = list; RadTreeView1.DataTextField = "Title"; RadTreeView1.DataFieldID = "Id"; RadTreeView1.DataFieldParentID = "ParentId"; RadTreeView1.DataBind(); }

2012 Falafel Software

290

Sitefinity 5

3) Run the example. Pages defined in your site should show up in tree form. You can refine the query to only return front end pages or provide other filtering.

Figure 271 --Tree of Pages

2012 Falafel Software

Using the Sitefinity API

291

Working with Content Items


The Sitefinity API is very consistent between modules, whether you are working with generic content, blogs, events or news. The first step is always to get the manager object. Generic content is a relatively simple starting point, so we will get a reference to the ContentManager .
ContentManager manager = ContentManager.GetManager();

ContentManager knows how to perform basic "CRUD" operations (Create, Read, Update, Delete): CreateContent() generates a ContentItem. ContentItem properties can then be populated with Title, Name, Author, and Content. Return a single ContentItem using the GetContent() method and passing a Guid. GetItems() returns an IQueryable<T> with all content items, suitable for "slicing-anddicing" with LINQ. There are also several methods for returning, Master, Temp and Live versions of a ContentItem. To update a ContentItem, get an instance of the item and simply edit its properties. To delete a ContentItem, use the Delete() method. Three other important ContentManager methods round out the field: RecompileItemUrls<T>(): This method needs to be called each time an item changes. The method generates a url for the item and saves the changes. Publish(): Newly created items are in Draft mode. Calling the manager's Publish() method makes managed content visible to the end user. SaveChanges(): This method commits any changes to the database.

2012 Falafel Software

292

Sitefinity 5

Creating an Item
The first API call always gets the manager for a specific module. The manager object can then be used to create some kind of item (ContentItem, BlogPost, etc.). The last few calls will be to RecompileItemUrls(), Publish() and SaveChanges(). The example below creates a generic content item, populates the properties and finally performs housekeeping methods to generate the item url, publish and save the item to the database.
ContentManager contentManager = ContentManager.GetManager(); contentManager.Provider.SuppressSecurityChecks = true; ContentItem item = contentManager.CreateContent(); // set item properties item.Title = "My Generic Content Title"; item.Name = "MyGenericContent"; item.Author = "Bob Smith"; item.Content = "My content <b>HTML</b>"; item.UrlName = "MyGenericContentUrl"; UserManager userManager = new UserManager(); userManager.Provider.SuppressSecurityChecks = true; User user = userManager.GetUsers() .Where(u => u.UserName.Equals("admin")) .FirstOrDefault(); item.Owner = user.Id; // generates the url and save changes, called each time "item" changes contentManager.RecompileItemUrls<ContentItem>(item); // has b een in draft till now, so pub lish contentManager.Lifecycle.Publish(item); // commit to datab ase contentManager.SaveChanges();

Setting the SuppressSecurityChecks property to True avoids having to deal with permissions issues for just now. See the Permissions section of this courseware for more information. You may also want to set the "Owner" for the item. An item's Owner is a Guid property and can be returned by way of the UserManager .
UserManager userManager = new UserManager(); userManager.Provider.SuppressSecurityChecks = true; User user = userManager.GetUsers() .Where(u => u.UserName.Equals("bsmith")) .FirstOrDefault();

The code above returns a User object from the Telerik.Sitefinity.Security.Model namespace. The User.Id property is the Guid that represents a particular user and can be assigned to an item's Ow ner property.

2012 Falafel Software

Using the Sitefinity API

293

// set item properties ... item.Owner = user.Id;

The resulting item displays in the list of Content Block items.


Figure 272 --The Resulting Item

Retrieving, Deleting and Editing Items


Each of the "FooManager" objects has a "GetFoo()" method that returns an IQueryable<T> of whatever kind of object you're working with. You can use the IQueryable<T> as a starting point for both iterating lists and selecting individual elements in the list. Retrieve a List of Content Items The ContentManager GetContent() method returns an IQueryable of ContentItem. You can use the entire list or filter using LINQ. For example, if you want to display all the generic content visible to the public, use a Where() clause to check the life cycle status of the item.
ContentManager contentManager = ContentManager.GetManager(); contentManager.Provider.SuppressSecurityChecks = true; IQueryable<ContentItem> items = contentManager .GetContent() .Where(i => i.Status == ContentLifecycleStatus.Master); foreach (ContentItem item in items) { string response = String.Format("{0}<br />{1}<br /><br />", item.Title, item.Content); Response.Write(response); };

2012 Falafel Software

294

Sitefinity 5

Retrieve an Instance, Deletion If you want to return a particular ContentItem, use the Where() clause to pinpoint a specific element in the list. The example below deletes a single item. First, a lambda expression in the Where() extension method returns a content item with a particular title. The FirstOrDefault() method returns a single instance of the item. Finally, the ContentManager Delete() method is passed the ContentItem to be deleted.
ContentManager contentManager = ContentManager.GetManager(); contentManager.Provider.SuppressSecurityChecks = true; ContentItem item = contentManager .GetContent() .Where(i => i.Title.Equals("My Generic Content Title")) .FirstOrDefault(); contentManager.Delete(item); contentManager.SaveChanges();

2012 Falafel Software

Using the Sitefinity API

295

Edit To edit an item, get an instance of the item and simply set it's properties. The example below gets a reference to a single generic content item and updates the Content property with text. Once you're done with setting properties, call the ContentManager SaveChanges() method to retain the new properties in the database.
ContentManager contentManager = ContentManager.GetManager(); contentManager.Provider.SuppressSecurityChecks = true; ContentItem item = contentManager .GetContent() .Where(i => i.Status == ContentLifecycleStatus.Master) .Where(i => i.Title.Equals("My Generic Content Title")) .FirstOrDefault(); item.Content = "New content set at " + DateTime.Now.ToLongTimeString(); contentManager.RecompileItemUrls<ContentItem>(item); contentManager.Lifecycle.Publish(item); contentManager.SaveChanges();

2012 Falafel Software

296

Sitefinity 5

Q & A...

Question : When I enter a news item, events, blog, etc there are 2 rows entered into the table for that record, Why is there 2 rows?

Answer: Each piece of content has 3 stages:


Master - This is the primary state of an item and always exists. You see only drafts in the backend. Temp - This is a copy of the item that exists to mark changes in an edit screen. It marks the item as locked. Live - This is a snapshot of the item that is visible on the public side.

2012 Falafel Software

Using the Sitefinity API

297

Publishing
For items that must be published through the lifecycle, e.g. News, Blogs, Pages, you will need to publish by sending a message to notify the workflow manager of the new status. The general pattern to do this is to create a dictionary with a single "ContentType" key that points to the FullName of the type you're working with. Then call the WorkflowManager. MessageWorkflow() method passing: The Guid id of the item. The type of the item. If you have a custom provider you can pass it, but typically this will be null. The name of the operation, i.e. "Publish". If the item is already checked out, this parameter should be true. The dictionary.
var bag = new Dictionary<string, string>(); bag.Add("ContentType", YourType.FullName); WorkflowManager.MessageWorkflow(ModuleItem.Id, TestType, null,"Publish", false, bag);

Here's an example of creating and publishing an News item:


NewsManager newsManager = NewsManager.GetManager(); Guid masterNewsId = Guid.NewGuid(); string newsTitle = "news title"; string newsContent = "news content"; NewsItem newsItem; newsItem = newsManager.CreateNewsItem(masterNewsId); newsItem.Title = newsTitle; newsItem.Content = newsContent; newsItem.DateCreated = DateTime.UtcNow; newsItem.PublicationDate = DateTime.UtcNow; newsItem.LastModified = DateTime.UtcNow; newsItem.UrlName = Regex.Replace(newsTitle.ToLower(), " ", "_"); newsManager.SaveChanges(); //Pub lish the news item through workflow var bag = new Dictionary<string, string>(); bag.Add("ContentType", typeof(NewsItem).FullName); WorkflowManager.MessageWorkflow(masterNewsId, typeof(NewsItem), null, "Publish", false, bag);

2012 Falafel Software

298

Sitefinity 5

Summary
This chapter explained how to work with the Sitefinity API. First you learned how to create a Sitefinity page programmatically and then how to display the hierarchy of pages in a tree view. You also created content programmatically and performed CRUD (Create Read Update Delete) operations against content items. Finally, you added a programmatically created content item to a page, on-the-fly.

2012 Falafel Software

15
Authentication and Security

300

Sitefinity 5

15

Authentication and Security


Operations in Sitefinity frequently require certain permissions. Permissions require authentication, that you are who you say you are, for Sitefinity to know what permissions to give you.

2012 Falafel Software

Authentication and Security

301

Objectives
This chapter demonstrates how to login and logout programmatically, how to create a user, how to create a role and how to assign a role to a user.

2012 Falafel Software

302

Sitefinity 5

Claims vs Forms Authentication


Using the default Claims Authentication within Sitefinity, you will no longer "hit the wall" when trying to integrate your site within a larger security framework. Prior to version 5.x, Sitefinity used Forms Authentication to verify user credentials and allow access to Sitefinity applications. Forms Authentication essentially retrieved the user's name/password and checked it against user data stored in the database for that particular application. That works well enough but comes up short in scenarios required by many organizations: "Single Sign On" (SSO) where you have several Sitefinity sites that should have only one login for the user. SSO allows you to show a single site to the user that is actually made up of multiple sites. When you need to use authentication provided from outside the Sitefinity application, e. g. Active Directory domains, another application or certificate authorities. When the login comes from a non-standard source such as biometric authentication. When authentication lifespan should not be tied to cookie expiration. Using Forms Authentication, the authentication information is stored in a cookie and the user is logged out when the cookie expires. Claims Authentication is a more robust approach that uncouples authentication from the application logic. Claims authentication uses these components: Subject is an entity that is being authenticated, e.g. a user. An Issuer makes claims about the subject and issues security tokens. A Claim is an assertion about the subject, e.g. the user's name or thumbprint. A Token is a digitally signed string created when the issuer makes a claim about a subject. The token contains authentic details about the subject. The Sitefinity Claims Authentication implementation doesn't directly impact backend administration or even API programming within the web site. The real boost comes in integrating with other Sitefinity sites, applications and services. Sitefinity REST web services for example require a call up front to retrieve the claims token. After that, you just pass the token in the request headers of each REST web service call.

2012 Falafel Software

Authentication and Security

303

Setting the Authentication Type


By default, user authentication is handled through Claims based authentication. If you have a site built with an older version of Sitefinity that uses web services, you may revert to Forms authentication. To toggle this setting, go to Administration > Settings (Basic Settings) > User Authentication.

Figure 273 --Reverting to Form s Authentication

For all projects going forward, Claims Authentication is the stronger choice.

2012 Falafel Software

304

Sitefinity 5

Login Programmatically
To login programmatically, use the SecurityManager object and call the AuthenticateUser() method. There are several overloads of this method that all take some combination of user name and password. The example below passes a Credentials object, that simply packages up the user name, password, persistence and provider. If the Persistent property is true, then the authentication cookie is retained between sessions.
Credentials credentials = new Credentials() { UserName = "admin", Password = "password", Persistent = true, }; var result = SecurityManager.AuthenticateUser(credentials); if (result == UserLoggingReason.Unknown) { // throw exception here }

AuthenticateUser returns a UserLoggingReason enum member that you check before taking action. For example, UserLoggingReason.Unknown indicates an invalid username or password. You can use the other members of UserLoggingReason if you need even more specific information about how the site is being used:
UserLoggingReason Enum Member Succe ss Use rLimitRe ache d Description Use r was succe ssfully re giste re d as logge d in The limit of maximum simultane ous logge d in use rs is re ache d Use r not found in any provide r Use r is alre ady logge d in from a diffe re nt IP addre ss Indicate s that the use r logical se ssion has e xpire d Use r has the authe ntication cookie but is not logge d in the database or use r is alre ady logge d out. More than one use r trying to login from the same IP but from diffe re nt compute rs. Invalid use rname or password spe cifie d.

Use rNotFound Use rLogge dFromDiffe re ntIp Se ssionExpire d Use rLogge dOff

Use rLogge dFromDiffe re ntCompute r

Unknown

2012 Falafel Software

Authentication and Security

305

UserLoggingReason Enum Member Ne e dAdminRights Use rAlre adyLogge dIn

Description Use r is not administrator to logout othe r use rs Use r alre ady is logge d in. We ne e d to ask the use r to logout or to logout some one e lse . Use r was re voke d: the use r was de le te d or use r rights and role me mbe rship was change d.

Use rRe voke d

2012 Falafel Software

306

Sitefinity 5

Logout Programmatically
To logout programmatically, simply call the SecurityManager static Logout() method. This logs out the user making the current request.
SecurityManager.Logout();

You can also use a Logout() overload if you need to pass specific credentials:
Credentials credentials = new Credentials() { UserName = "admin", Password = "password", }; SecurityManager.Logout(credentials);

Gotcha!

You must have administrative rights to logout other users or match the credentials of the user to perform the logout, otherwise an UnauthorizedAccessException is thrown.

2012 Falafel Software

Authentication and Security

307

Create a User
To create a user, first get an instance of the UserManager by calling GetManager(). Then call the CreateUser() method and pass the login name. Populate the returned User object properties, then finally call the SaveChanges() method.
UserManager userManager = UserManager.GetManager(); User user = userManager.CreateUser("ayamada"); user.Password = "password"; user.Email = "ayamda@mydomain.net"; user.FirstName = "Aiko"; user.LastName = "Yamada"; user.Comment = "Popular blogger"; userManager.SaveChanges();

Another overload of CreateUser() allows you to set many of the properties of the User at one time and also returns a MembershipCreateStatus. If the status is equal to Success, then you can set more properties of the user object and finally call the SaveChanges() method.
MembershipCreateStatus createStatus; UserManager userManager = UserManager.GetManager(); User user = userManager.CreateUser( // user name "ayamada", // password "password", // email "ayamda@mydomain.net", // security question "what is your favorite pet's name?", // security answer "spot", // isApproved true, // provider user key null, // create status out createStatus ); if (createStatus == MembershipCreateStatus.Success) { user.FirstName = "Aiko"; user.LastName = "Yamada"; userManager.SaveChanges(); }

2012 Falafel Software

308

Sitefinity 5

Roles and Permissions


You now have a user in the system, but what can they do? Not a thing. A new user is not associated with any roles in the system and therefore has no permissions to do anything. To give the user permissions to do something, you must add the person to a role. The basic elements to associating a role with a user are: Get an instance of a RoleManager for a particular providers. The built-in providers available out-of-the-box are listed in Settings > Security > Role Providers. Use the "AppRoles" provider when trying to get at roles already in the system, such as "Administrators" or "BackendUsers". For roles you create yourself, use the "Default" provider.

Figure 274 --List of Role Providers

Get a specific Role, e.g. "BackendUsers" or "Authors". Add the User to a Role. Save changes.

2012 Falafel Software

Authentication and Security

309

This walk-through demonstrates creating a user and adding that user to the "BackendUsers" and "Authors" roles. 1) Add the code below to create the User object and respond to the returned status. The code can be added to the Page_Load event of a standard ASP.NET page.
MembershipCreateStatus createStatus; UserManager userManager = UserManager.GetManager(); User user = userManager.CreateUser( "ayamada", "password", "ayamda@mydomain.net", "what is your favorite pet's name?", "spot", true, null, out createStatus ); if (createStatus == MembershipCreateStatus.Success) { userManager.SaveChanges(); // role code goes here } -->

2) Replace the comment "role code goes here -->" with the code below. The code returns a RoleManager for the built in "AppRoles". The GetRoles() method returns an IQueryable of Roles, suitable for LINQ expressions. The LINQ is used to single out the role named "BackendUsers", then the role for "Authors". The RoleManager AddUserToRole() method establishes the association between the two. Don't forget to call the SaveChanges() method for the RoleManager (not just the UserManager).
// get the b uilt in roles RoleManager roleManager = RoleManager.GetManager(SecurityManager.ApplicationRolesProviderName); // retrieve the "BackendUsers" role Role backendUserRole = roleManager.GetRoles() .Where(r => r.Name.Equals(SecurityManager.BackendUsersRoleName)))) .Single(); // retrieve the "Authors" role Role authorRole = roleManager.GetRoles() .Where(r => r.Name.Equals("Authors")) .Single(); // add the user to b oth roles roleManager.AddUserToRole(user, backendUserRole); roleManager.AddUserToRole(user, authorRole); // save the new role settings roleManager.SaveChanges();

2012 Falafel Software

310

Sitefinity 5

3) Run the application, then find the user in the Sitefinity Administration > Users list. Notice that the "BackendUsers" and "Authors" roles have been added.

Figure 275 --New User w ith Roles Assigned

2012 Falafel Software

Authentication and Security

311

Summary
This chapter demonstrated how to login and logout programmatically, how to create a user, how to create a role and how to assign a role to a user.

2012 Falafel Software

16
Using the Fluent API

Using the Fluent API

313

16

Using the Fluent API


The Fluent API is a simplified interface, or Facade, over the full Sitefinity API. It provides an easy-to-use syntax for being productive with Sitefinity development right away. The single entry point App followed by the method WorkWith() returns an instance of the Fluent API.
var fluent = App.WorkWith();

After the call to WorkWith() follows the specific interface you want to work with. For example, if you want to work with generic content items, you would write the code below, where ContentItem() is the gateway to all methods that access a single content item.
App.WorkWith() .ContentItem();

From there you can call one of the content item methods, such as CreateNew ();
App.WorkWith() .ContentItem() .CreateNew()

Using the Fluent API, you can continue to chain methods to perform some logical task in a single line of easy-to-read, maintainable code. The example below creates a new generic content item, assigns the properties, publishes the item and saves to the database.
App.WorkWith() .ContentItem() .CreateNew() .Do(c => { c.Title = "My Fluent Title"; c.Name = "MyFluentContent"; c.Content = "<h1>Fluent Content<h1>"; c.UrlName ="MyGenericContentUrl"; }) .Publish() .SaveChanges();

Notes

Notice the convention where each method is lined up vertically. Long chains of method calls are easier to read when structured this way.

2012 Falafel Software

314

Sitefinity 5

Objectives
This chapter demonstrates how the Fluent API works with pages and content items. You will learn how to upload images and documents. In particular, you will use a web service to load images to an Album en-masse. Finally, you will use the Fluent API to return lists of content items, filter, sort and select content items into useful subsets and then bind your results to ASP.NET controls.

2012 Falafel Software

Using the Fluent API

315

Fluent API Facades


App.WorkWith() returns a FluentSitefinity representing a single request to the fluent API. The FluentSitefinity class contains a series of methods that return facades for specific modules in Sitefinity including: Albums and Images Generic Content Items Blogs and BlogPosts Documents and Document Libraries Events Dynamic Data Pages News Items Videos and Video Libraries

2012 Falafel Software

316

Sitefinity 5

Working with Pages


Using the Fluent API, you can create new pages and perform operations against multiple pages at once. The Fluent syntax makes it easy to include methods that checkout draft versions of a page, publish and save changes to the database.

Creating Pages Programmatically


1) In Page_Load of an ASP.NET page in the Sitefinity project, add the code below. In a single line of Fluent code, this statement creates a standard page, populates the properties for the page, creates a draft of the page, saves the page to the database and publishes through the WorkflowManager.
SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); var pageId = Guid.NewGuid(); App.WorkWith() .Page() .CreateNewStandardPage(pageId) .Do(p => { p.Name = "MyFluentPage"; p.Title = "My Fluent Page"; p.Page.Title = "My Fluent Page"; p.Description = "My Fluent Page Description"; p.ShowInNavigation = true; p.UrlName = "MyFluentPage"; }) .CheckOut() .Publish() .SaveChanges(); // pub lish through the workflow var bag = new Dictionary<string, string>(); bag.Add("ContentType", typeof(PageNode).FullName); WorkflowManager.MessageWorkflow(pageId, typeof(PageNode), null, "Publish", false, bag); SecurityManager.Logout();

2) Run the application, then navigate to the Sitefinity Administrator Pages to view the new page.

2012 Falafel Software

Using the Fluent API

317

Figure 276 --New Page Added Using Fluent API

Show Hiearchy of Pages


To get page objects, simply use the Pages() method facade. If you're binding to some control that requires a hierarchical representation, such as RadTreeView, be sure to get both the Id of the current page and the Parent's Id property. The example below retrieves all pages in the system, projects properties into a new anonymous type and binds to a RadTreeView.
SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); var pages = App.WorkWith() .Pages() .Get() .ToList() .Select(p => new { Id = p.Id, ParentId = p.Parent == null ? Guid.Empty : p.Parent.Id, Title = p.Title, Published = p.ApprovalWorkflowState == "Published" }); RadTreeView1.DataSource = pages; RadTreeView1.DataTextField = "Title"; RadTreeView1.DataFieldID = "Id"; RadTreeView1.DataFieldParentID = "ParentId"; RadTreeView1.DataBind(); SecurityManager.Logout();

2012 Falafel Software

318

Sitefinity 5

The pages display listed in the RadTreeView.

Figure 277 --Pages From the Fluent API

2012 Falafel Software

Using the Fluent API

319

Working with Content Items


Creating Items
To create any kind of item with the Sitefinity Fluent API, first start with App.WorkWith() method to access all the available facades. This is followed by the specific facade you want to work with. The example below is using the NewsItem facade, followed by a call to CreateNew (). The Do() method contains a lambda expression that allows you to populate all the fields of the NewsItem object. Finally, a call to SaveChanges() retains the object in the database. There is no call to the Publish() method in this example. Instead, the PublicationDate is set to seven days in the future.
App.WorkWith() .NewsItem() .CreateNew() .Do(n => { n.Title = "Vintage Cars"; n.Content = "The Vintage Cards Field Guide helps locate hard to find parts"; n.Author = "Bob Smith"; n.SourceSite = "http://www.vcfg.net"; n.SourceName = "Vintage Cars Field Guide"; n.PublicationDate = DateTime.Now.AddDays(7); }) .SaveChanges();

The item shows up in the list of News content:

Figure 278 --The Fluent API Generated New s Item

2012 Falafel Software

320

Sitefinity 5

The Title and Properties for the news item reflect the property settings set in the Do() method.

Figure 279 --New s Item Title and Properties

2012 Falafel Software

Using the Fluent API

321

Uploading Images and Documents


You can add a new item that has text by simply calling CreateNew() and setting some properties within the Do() method lambda. How do you get binary objects like images or PDF files into the system? The short answer is that you have to perform an additional step of uploading the content. Fortunately, the Fluent API includes a method to handle this situation: the UploadContent() method takes a stream of bytes and a file extension. The partial example below shows the general pattern uploading a "jpg" image to an Album.
byte[] bytes = GetSomeData(); Stream stream = new MemoryStream(bytes); App.WorkWith() .Album(album.Id) .CreateImage() .Do(item => { item.Title = "My Title"; }) .CheckOut() .UploadContent(stream, ".jpg") .CheckInAndPublish() .SaveChanges();

2012 Falafel Software

322

Sitefinity 5

Uploading an Image To upload an image: 1. Get a reference to an Album. The example below gets an Album reference where the title is "Default Album". 2. Get a stream of bytes representing the image. The example below uses the WebClient object to download data directly from a given url. The example uses a url to one of the "built with Telerik controls" icons.

2012 Falafel Software

Using the Fluent API

323

3. Upload the byte stream to the album. To do this, first call CheckOut() on the album, then UploadContent() followed by CheckIn() and finally to Publish(). UploadContent () parameters takes the stream of bytes followed by the name of the extension (don't forget the leading ".").
SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); const string url = "http://www.telerik.com/libraries/company/builtwith_white.sflb"; using (var fluent = App.WorkWith()) { // get the alb um Album album = fluent.Albums() .Where(a => a.Title == "Default Library") .Get() .SingleOrDefault(); // download the image b yte stream WebClient webClient = new WebClient(); byte[] bytes = webClient.DownloadData(url); Stream stream = new MemoryStream(bytes); // upload the b ytes to the alb um fluent .Album(album.Id) .CreateImage() .Do(item => { item.Title = "Telerik Logo"; }) .CheckOut() .UploadContent(stream, ".gif") .CheckIn() .Publish() .SaveChanges(); SecurityManager.Logout();

The uploaded image shows with its title in the Default Album.

Figure 280 --The Uploaded Im age

2012 Falafel Software

324

Sitefinity 5

Uploading En-masse From a Web Service Tweets, blogs, web services and RSS feeds all offer the possibility of loading large blocks of content, all at one time. The Xdocument class along with LINQ can work with the Fluent API to move XML content to your web site. This is particularly useful for one-time migration tasks, but can be used for any occasion where a Url points to XML data. The general steps for uploading from an XML source that contains urls to images: 1. Create a custom class to contain each image title and url. 2. Get a list objects with image data from a Url with XML data. 3. Get an existing Album to contain the images. Create a new Album if necessary. 4. Upload the images. The walk-through that follows uses the Bing API to get a series of images. You will need to apply for a developer's application ID to complete the walk-through. To get an ID, follow the prompts at: http://www.bing.com/developers/

Notes

RSS feeds typically don't require an ID. Most of the public API REST services, such as Google, Flickr, Imgur, etc. all require an application ID. Some may also require additional authorization. Be aware that you are responsible for your use of any REST services, so be sure to read and follow the agreements and documentation.

2012 Falafel Software

Using the Fluent API

325

Create Custom Class We could use anonymous types to hold the results of the Bing request. Instead, we will create a custom object that can be passed easily between methods. 1) Create a new class in your project and name it "BingResult". 2) Replace the class code with the code below.
public class BingResult { public String Title { get; set; } public String Url { get; set; } }

Make Bing Request 1) In the code behind for the startup page in your project, add the GetBingResults() method below.
private static IEnumerable<BingResult> GetBingResults(String searchOn) { const string BingAppId = "<Your App ID string goes here>"; // see http://www.b ing.com/developers/ to get id // request url, along with app id and parameters string requestString = "http://api.bing.net/xml.aspx?" + "&AppId=" + BingAppId + "&Query=" + searchOn + "&Sources=Image" + "&Adult=Strict" + "&Image.Count=10"; // namespace used to qualify elements XNamespace ns = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia"; // load the url as an xdocument Xdocument document = XDocument.Load(requestString); // use LINQ to parse and project document elements to custom class IEnumerable<BingResult> results = from r in document.Descendants(ns + "ImageResult") select new BingResult { Title = r.Element(ns + "Title").Value, Url = r.Element(ns + "Thumbnail").Element(ns + "Url").Value }; return results; }

2012 Falafel Software

326

Sitefinity 5

The method defines a request to the Bing API using some of the query string parameters as defined in the Bing API documentation. The XDocument.Load() method does the grunt work of downloading from a given Url into an Xdocument. Xdocument exposes Elements, where each Element has a Value property. LINQ expressions make it easy to project results into another object type. In this case, the parsed results are projected into a collection of BingResult objects and returned. Get Album 1) In the code behind for the page, add the GetAlbum() method code listed below.
private static Album GetAlbum(String title) { // get an existing alb um with a given title Album album = App.WorkWith() .Albums() .Where(a => a.Title.Equals(title)) .Get() .SingleOrDefault(); // if the alb um doesn't exist, create it if (album == null) { App.WorkWith() .Album() .CreateNew() .Do(a => { a.Title = title; }) .Get(out album) .SaveChanges(); } return album; }

The method first uses the Fluent API to get an Album that has a particular title. If the Album doesn't exist, the second statement in the method creates the Album object.

2012 Falafel Software

Using the Fluent API

327

Upload Images to Album 1) Add a method to upload a single image using the information from a BingResult object, to a particular Album.
private static void UploadSingleImage(Album album, BingResult result) { // use Web Client to download image from url, get stream WebClient webClient = new WebClient(); byte[] bytes = webClient.DownloadData(result.Url); Stream stream = new MemoryStream(bytes); // create the Sitefinity Image, set the title and upload stream App.WorkWith() .Album(album.Id) .CreateImage() .Do(item => { item.Title = result.Title; }) .CheckOut() .UploadContent(stream, ".jpg") .CheckIn() .Publish() .SaveChanges(); }

This method first uses the WebClient object to download from an image url as a stream of bytes. Then the Fluent API creates a new Image object and uploads the image stream to the image. Putting It All Together 1) Add the code below to the Page_Load event handler for the startup page of your project.
protected void Page_Load(object sender, EventArgs e) { // add authentication here... String subject = "Model T"; IEnumerable<BingResult> results = GetBingResults(subject); Album album = GetAlbum(subject); foreach (BingResult result in results) { UploadSingleImage(album, result); } }

2012 Falafel Software

328

Sitefinity 5

The GetBingResults() method returns an IEnumerable of BingResult for a search on "Model T", the GetAlbum() method ensures there is an album with the title of "Model T", and finally, the results are uploaded, one-at-a-time to the album. 2) Replace the comment "add authentication here..." with the code below. Replace the user name and password with a valid user name and password for your Sitefinity web site that has permissions to create albums and images.
protected void Page_Load(object sender, EventArgs e) { SecurityManager.AuthenticateUser(new Credentials() { UserName = "admin", Password = "password" }); //. . . }

3) Run the application, then check the Images administration page to view the results. You should see images uploaded into the new album.

Figure 281 --Uploaded Im ages

2012 Falafel Software

Using the Fluent API

329

Uploading Documents Any kind of document can be uploaded to a Sitefinity Library as a stream. The pattern is parallel to the example in Upload Images to Album. You'll need to get a stream of bytes that contains your document. Bytes can come from a Url using WebClient methods or from your local file system using System.IO objects. This example assumes you have a "\Documents" folder in the project with one or more files. Server.MapPath() gets the physical directory path of "\Documents", then uses the DirectoryInfo GetFiles() method to access an IEnumerable of FileInfo. FileInfo, in turn, has an Open() method that returns a stream. In the code below, notice the UploadContent() method takes the FileInfo.Open() to get the byte stream and the FileInfo.Extension property to sense whether this file is a .doc, .pdf, .xlsx, etc.
SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); var path = Server.MapPath("~\\Documents"); var files = new DirectoryInfo(path).GetFiles(); // create the Sitefinity Image, set the title and upload stream using (var fluent = App.WorkWith()) { // get the default lib rary var defaultLibrary = fluent .DocumentLibraries() .Where(lib => lib.Title == "Default Library") .Get() .FirstOrDefault(); // get the stream for each file and upload foreach (var file in files) { fluent .Document() .CreateNew() .Do(doc => { doc.Parent = defaultLibrary; doc.Title = file.Name; }) .CheckOut() .UploadContent(file.Open(FileMode.Open), file.Extension) .CheckIn() .Publish() .SaveChanges(); } } SecurityManager.Logout();

2012 Falafel Software

330

Sitefinity 5

The uploaded documents are displayed in the library with the appropriate icons for each file type.

Figure 282 --Uploaded Docum ents

2012 Falafel Software

Using the Fluent API

331

Retrieving Collections of Content Items


To get a list of items, first start with App.WorkWith() to get at the Fluent API facades. Use the plural method name of whatever content you're interested such as New sItems or Albums. Get FluentSitefinity Methods How can you find the names of the methods to work with? You can look them up in the online documentation. You can also get the method names "straight from the horses mouth" using the Visual Studio. The App.WorkWith() method is actually a FluentSitefinity object. To peer inside FluentSitefinity: 1. From the View menu in Visual Studio, select the Class View menu option. 2. In the Class View pane, enter "FluentSitefinity" and press Enter. 3. The methods are listed in the lower window. In the screenshot below you can see the Images, NewsItems and Pages methods that will return collections that you can iterate or filter using a LINQ Where() method.

Figure 283 --Listing of FluentSitefinity Methods

2012 Falafel Software

332

Sitefinity 5

Coding the List The Fluent API facades have a complete set of methods to make LINQ style statements easier to code, including First(), Last(), Count(), Where(), Skip(), Take(), OrderBy(), OrderByDescending() and Get(). Filtering Minimally, you can use the Where() method to filter for Live content items, the Get() method to convert the facade into a LINQ friendly IQueryable and finally call ToList() to execute the query and return a generic List<> of the specific type you want to work with. The example below demonstrates getting a simple list of live news items, iterates the list and prints out the titles.
List<NewsItem> news = App.WorkWith() .NewsItems() .Where(n => n.Status == ContentLifecycleStatus.Live) .Get() .ToList(); foreach (NewsItem newItem in news) { this.Response.Write(newItem.Title + "<br />"); }

Sorting You can order the list using the OrderBy() or OrderByDescending method methods to sort the list by any column. Both methods take a lambda expression that can be used to reference the columns you want to sort on. Using the OrderByDescending() along with Take() methods you can get the top five news items based on the most recent publication date. The example below filters for all the live news items, sorts them in descending order and returns five items.
List<NewsItem> news = App.WorkWith() .NewsItems() .Where(n => n.Status == ContentLifecycleStatus.Live) .OrderByDescending(o => o.PublicationDate) .Take(5) .Get() .ToList(); foreach (NewsItem newItem in news) { this.Response.Write(newItem.Title + "<br />"); }

2012 Falafel Software

Using the Fluent API

333

Projections Use the Select() method to "project" the items properties into another class. This can be a custom class you write or an anonymous class. The example below projects NewsItem properties into a list of MyNewsItem objects. The Select() method takes a lambda expression that surfaces the properties of the NewsItem. For each NewsItem, a new MyNewsItem is created and populated with the NewsItem properties.
public class MyNewsItem { public String Title { get; set; } public String Description { get; set; } public String Summary { get; set; } } //. . . IEnumerable<MyNewsItem> news = App.WorkWith() .NewsItems() .Where(n => n.Status == ContentLifecycleStatus.Live) .Get() .ToList() .Select(ni => new MyNewsItem() { Title = ni.Title, Description = ni.Description, Summary = ni.Summary }); foreach (MyNewsItem newItem in news) { this.Response.Write(newItem.Title + "<br />"); }

Notes

The IEnumerable<MyNew sItem> new s in the example above could be stated as var new s. The longer syntax is used here for learning purposes so you can easily see what kind of objects we're working with.

2012 Falafel Software

334

Sitefinity 5

You can just as easily create an anonymous type without having to specifically code a "MyNewsItem" class. In the code example below, notice that in the Select() method lambda, the new keyword is used and is not followed by a class name. .Net creates an anonymous class where the property names correspond to the names in the lambda expression on the left, i.e. "Title", "Description" and "Summary".
var news = App.WorkWith() .NewsItems() .Where(n => n.Status == ContentLifecycleStatus.Live) .Get() .ToList() .Select(ni => new { Title = ni.Title, Description = ni.Description, Summary = ni.Summary });

2012 Falafel Software

Using the Fluent API

335

Binding Lists to Controls While this topic doesn't strictly relate to Sitefinity only, you may want to interact with ASP.NET controls within a standard ASP.NET page or a widget of a Sitefinity page. This topic describes how to populate controls with data from the Sitefinity Fluent API. To display and manipulate data, you will need to bind the Sitefinity data to a visual control. Binding involves setting properties on the control that specify where the data is and what columns of the data should be displayed. You can bind any object that implements IEnumerable including arrays and generic lists. The code below can be included in the Page_Load event handler of a standard page. The example creates a list of anonymous objects and binds to a standard ASP.NET DropDow nList control. Assign the list of Sitefinity items to the control's DataSource property. The DataTextField is assigned the property that you want to display in the control. The DataValueField can be assigned a property that you want to reference when the user selects an item in the list. Be sure to call the DataBind() method so that the binding takes place and the data displays in the control.
var news = App.WorkWith() .NewsItems() .Where(n => n.Status == ContentLifecycleStatus.Live) .Get() .ToList() .Select(ni => new { Id = ni.Id, Title = ni.Title, Description = ni.Description, Summary = ni.Summary }); ListBox1.AutoPostBack = true; ListBox1.DataSource = news; ListBox1.DataTextField = "Title"; ListBox1.DataValueField = "Id"; ListBox1.DataBind();

The screenshot below shows the titles of the two live news items in the system.

Figure 284 --Bound Control

2012 Falafel Software

336

Sitefinity 5

The specific control will typically have some event that allows you to retrieve the selected item. The ListBox control, for example, has a SelectedValue property. The DataValueField assigned in the binding, is available as the SelectedValue when the selection changes. The SelectedIndexChanged event handler code example below retrieves the SelectedValue (a string) and converts the string to a Guid. The Guid is the Id for a news item. Use this Guid in the Where() method lambda to retrieve the NewsItem object.
protected void List_SelectedIndexChanged(object sender, EventArgs e) { Guid id = Guid.Parse((sender as ListBox).SelectedValue); var newsItem = App.WorkWith() .NewsItems() .Where(ni => ni.Id.Equals(id)) .Get() .FirstOrDefault(); RightPane.ContentUrl = "http://www.bing.com/search?q=" + newsItem.Title; }

The NewsItem object is used to populate other controls. In this example, RadPane is displaying a Bing web search for the selected NewsItem Title.

Figure 285 --Selected New sItem Title Search

2012 Falafel Software

Using the Fluent API

337

Summary
This chapter demonstrated how the Fluent API works with pages and content items. You learned how to upload images and documents. In particular, you used a web service to load images to an Album en-masse. Finally, you used the Fluent API to return lists of content items, then filtered, sorted and selected content items into useful subsets and bound those results to ASP.NET controls.

2012 Falafel Software

17
Working with Forms

Working with Forms

339

17

Working with Forms


To work with Forms programmatically, you can use the standard API FormsManager . Using the FormsManager you can retrieve lists of forms, a single form description and all the entries for a form.

2012 Falafel Software

340

Sitefinity 5

Objectives
This chapter explains how to programmatically retrieve forms and form items. This chapter will also discuss how to get at the form entry column names and captions.

2012 Falafel Software

Working with Forms

341

Getting a List of All Forms


To list every form on your website, use the GetForms() method. The method returns an IQueryable of FormDescription objects. You can perform operations against each FormDescription using the FormsManager. The example below iterates the list looking for forms where the Name property contains the word "test" and deletes each matching instance.
protected void DeleteTestFormsButtonClick(object sender, EventArgs e) { SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); using (FormsManager formsManager = FormsManager.GetManager()) { var forms = formsManager.GetForms().Where(f => f.Name.ToLower().Contains("test")); foreach (var form in forms) { formsManager.Delete(form); } formsManager.SaveChanges(); } SecurityManager.Logout(); }

You can also bind the collection directly as a DataSource. The example below populates a RadComboBox with the names of each form. Notice that the DataValueField, a string property, contains the string representation of a Guid Id for a given form.
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { using (FormsManager formsManager = FormsManager.GetManager()) { RadComboBox1.DataSource = formsManager.GetForms().ToList(); RadComboBox1.DataTextField = "Title"; RadComboBox1.DataValueField = "Id"; RadComboBox1.DataBind(); RadComboBox1.SelectedIndex = 0; } } }

2012 Falafel Software

342

Sitefinity 5

The screenshot below shows the titles for each form in a RadComboBox.

Figure 286 --Form Titles Displayed in a RadCom boBox

2012 Falafel Software

Working with Forms

343

Retrieve a Single Form


You can use LINQ to filter Forms to access a specific member. If you have a Guid, you can use the GetForm() method and pass a Guid in the constructor.
protected void RadComboBox1_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e) { string id = RadComboBox1.SelectedValue; using (FormsManager formsManager = FormsManager.GetManager()) { FormDescription formDescription = formsManager.GetForm(new Guid(id)); /// access the FormDescription Title and collection of Entries. } }

2012 Falafel Software

344

Sitefinity 5

Retrieving Form Entry Values


To retrieve the responses from all the people that have used the form and entered data, use the FormsManager.GetFormEntries() method. Pass the FormDescription for the form as a parameter to GetFormEntries(). This will return a collection of FormEntry objects.

Retrieve a Single Column Value


You can use the FormEntry.GetValue() method and pass the name of the column (you can see the programmer-accessible name in the Sitefinity Administrator when editing the form). The example below iterates all form entries, retrieves a value for a field named "newtextbox" and adds the values to a ListBox control.
FormsManager formsManager = FormsManager.GetManager(); // Get the form named "sf_testform" var forms = formsManager.GetForms().Where(f => f.Name == "sf_testform"); foreach (var form in forms) { var records = formsManager.GetFormEntries(form); // Loop through all the response records for this form foreach (var record in records) { FormEntry fe = (FormEntry)record; // Grab the newtextb ox column value to display in a list b ox var TextBoxValue = fe.GetValue("newtextbox"); ListBox1.Items.Add(new ListItem() { Text = TextBoxValue.ToString() }); } }

Running in the browser, the ListBox displays the values for each entry.

Figure 287 --Displaying Form Values

2012 Falafel Software

Working with Forms

345

Retrieve All Values


You can bind a list of form entries directly to a control. The example below binds the list of FormEntry to the DataSource of a RadGrid.
protected void RadComboBox1_SelectedIndexChanged(object sender, Telerik.Web.UI.RadComboBoxSelectedIndexChangedEventArgs e) { string id = RadComboBox1.SelectedValue; using (FormsManager formsManager = FormsManager.GetManager()) { var form = formsManager.GetForm(new Guid(id)); RadGrid1.AutoGenerateColumns = true; var entries = formsManager.GetFormEntries(form); RadGrid1.DataSource = entries; RadGrid1.DataBind(); } }

This brings back all the information for each entry, including various Ids associated with the entry, DateTime values, source keys, etc. The dynamically created form entry fields are shown in the last columns on the right, i.e. "FormParagraphTextBox_C003" etc., that the actual user entries are contained in.

Figure 288 --Entries Data Bound to Grid

2012 Falafel Software

346

Sitefinity 5

Retrieve Form Entry Column Names and Captions


What if I don't want all columns? What if I only want the list of form entry field names and captions for the user entry? With a FormDescription you can spelunk into both the input Controls and output Entries of the form. As of this writing, to get the field names programmatically requires parsing the Properties of the Controls. The LINQ statement below gets both the MetaField property that holds the field name used to access a particular column in code and the Title property that acts as a label that the user sees when entering data to the form.
public class FormColumn { public string FieldName { get; set; } public string Caption { get; set; } } //. . . private static IEnumerable<FormColumn> GetFormColumns(FormDescription formDescription) { IEnumerable<FormColumn> columns = from c in formDescription.Controls let metaField = c.Properties .FirstOrDefault(p => p.Name.Equals("MetaField")) let labelField = c.Properties .FirstOrDefault(p => p.Name.Equals("Title")) where metaField != null select new FormColumn { FieldName = metaField .ChildProperties .FirstOrDefault(m => m.Name.Equals("FieldName")) .Value, Caption = labelField == null ? String.Empty : labelField.Value }; return columns; }

When the returned columns are bound to a grid, the result looks like the screenshot below.

Figure 289 --Form Colum n Data in Grid

2012 Falafel Software

Working with Forms

347

Show Only Form Entry Columns


Using the List of column names retrieved in the previous Topic, Retrieving Form Entry MetaData, you can iterate the meta data and only create grid columns for the user entry data. The example in the screenshot below has a checkbox that toggles between showing all columns and just the data entry columns of the form.

Figure 290 -- Form w ith All Colum ns

When the checkbox is off, only the data entry fields display. Also notice that the Captions for these columns display, not the form field control names.

Figure 291 --Data Entry Fields from the Form

2012 Falafel Software

348

Sitefinity 5

Create a RadGrid NeedDataSource event handler to reload the grid with the currently selected form data. NeedDataSource fires when the page is first loaded and in response to RadGrid Rebind() method calls.
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e) { string id = RadComboBox1.SelectedValue; using (FormsManager formsManager = FormsManager.GetManager()) { FormDescription formDescription = formsManager.GetForm(new Guid(id)); RadGrid1.DataSource = formsManager.GetFormEntries(formDescription); } }

The RadGrid PreRender event handler compares the column metadata retrieved from the form against the grid columns. The grid columns that don't match form entry columns are hidden. Grid columns that match a form entry are displayed and assigned a friendly caption for the HeaderText.
protected void RadGrid1_PreRender(object sender, EventArgs e) { RadGrid grid = sender as RadGrid; string id = RadComboBox1.SelectedValue; using (FormsManager formsManager = FormsManager.GetManager()) { var form = formsManager.GetForm(new Guid(id)); var formColumns = this.GetFormColumns(form); foreach (GridColumn gridColumn in grid.MasterTableView.AutoGeneratedColumns) { // get a grid column that matches one of the form entry columns FormColumn formColumn = formColumns.Where(c => c.FieldName.Equals(gridColumn.UniqueName)).FirstOrDefault(); // if we can't find a match, hide this column. // If the "All" checkb ox is checked, unconditionally show gridColumn.Visible = formColumn != null || ShowAllCheckbox.Checked; // if there is a match, use the form entry caption if (formColumn != null) { gridColumn.HeaderText = formColumn.Caption; } } } grid.Rebind(); }

2012 Falafel Software

Working with Forms

349

Summary
This chapter explained how to programmatically retrieve forms and form items. This chapter also discussed how to get at the form entry column names and captions.

2012 Falafel Software

18
Localization

Localization

351

18

Localization
The ability to localize your entire site to any language is baked right into Sitefinity. You can localize not only the text but any other content to be relevant to the culture of your website visitor. The back-end of the website is also fully localizable. All menu items, button text, labels, etc. are localizable. Predefined "Language Packs" for Sitefinity can be found at http://www.sitefinity.com/marketplace/modules.aspx.

2012 Falafel Software

352

Sitefinity 5

Objectives
In this chapter you will learn how to localize front end pages using Sitefinity Administration, how to localize strings in code, how to localize back end pages and how to use the Interface Labels & Messages page.

2012 Falafel Software

Localization

353

Localizing Front End Pages


In this next walk through we will add the Spanish language and localize a front-end page to reflect the language choice. 1) Select the Administration menu Settings option. 2) From the list on the left side of the page select the Languages option. 3) Click the Add languages... button. 4) Use the search box to locate "Spanish" in the list and select the check box.

Figure 292 --Selecting "Spanish"

5) Click the Done button. Now the new "Spanish" language entry shows up under the default "English" entry.

Figure 293 --Selected Languages

2012 Falafel Software

354

Sitefinity 5

Notes

Notice that the culture code shows up next to each full language name. Also notice that you can click the Set as default link to use any language as the default. Later, we'll look at how the user can select the language for themselves.

6) The Multilingual URLs section determines how the localized pages will be organized and accessed. Leave the default Directories setting. Using the Directories option, all languages for the site all come under the same domain, and where the directory name indicates the language. The localized page versions will use an industry standard, two letter "culture code" to describe the language. For example "es" is the culture code for Spanish. Using the Different domains option, the culture code is appended to the front of the domain. See the descriptions in the screenshot below each option to see how the URLs are setup.

Figure 294 --Language Access

7) You can even change the language for the backend system by clicking the Manage backend languages link and adding languages there. Leave the default setting for this example. 8) Click the Save changes button.

2012 Falafel Software

Localization

355

9) Select the Administration menu Pages option. This option will take extra time the because Sitefinity needs to accommodate the new languages by making database changes. When the list refreshes, all the pages in our site are "localization ready" and have a new Translations column.

Figure 295 --Localization Ready Pages

10)Click the ES Add link for the Welcome page.

Figure 296 --Adding a Page Translation

2012 Falafel Software

356

Sitefinity 5

11)Create a page (ES) displays so you can supply a new page Name, URL and Title in the appropriate language.

Figure 297 --Creating the Translated Page

Tip!

To test your pages without performing a production level translation, use Google's translation service at http://translate.google.com.

Figure 298 --Google's Translation Service

12)Click the Create and go to add content button.

2012 Falafel Software

Localization

357

13)Now you have the option of Copying from another language, or to Start from Scratch . This option is especially important if you have images that you want to copy between versions. Click the Copying from another language link. 14)The Copy content from another language dialog displays. The English language is the only version available for this page, so the drop down list is disabled. Select the "Keep all language versions synced " check box. Click the Done button to close the dialog.

Figure 299 --Copy Content Dialog

2012 Falafel Software

358

Sitefinity 5

15)The translated page displays. Notice the message at the top of the page that lets you know that the pages are synced and what kind of behavior you can expect while designing the page. Also notice that most of the widgets are not populated with content yet. Except for the Download List at the end of the page that shows the document titles.

Figure 300 --Translated Page

16)Click the Content block Edit button. 17)Paste "Bienvenido a CarConduit!" into the editor window. Click the Save button. 18)Click the Publish button. Publishing pushes out all the translations. .

2012 Falafel Software

Localization

359

19)View the page. Notice the Url in the address bar uses the culture code "es". The translated

content shows at the head of the page.

Figure 301 --The Translated Page

2012 Falafel Software

360

Sitefinity 5

User Language Selection


You can use the Language Selector widget right in your page so that the user can dynamically choose the language they want to view the page in. 1) Open the localized page for editing again. 2) In the Drag Widgets area to the right side to the page, locate the Navigation section and open it. Drag the Language selector widget to the top of the page. 3) Click the Language selector widget Edit button. In the Display language selector as... option, select Drop-down menu. Also notice the options to include the current language in the selector. What to do with languages without translations? You can Hide the link to the missing translation or Redirect to the home page....

Figure 302 --Configuring the Language Selector

4) Click the Save button to close the dialog.

2012 Falafel Software

Localization

361

5) Publish and view the page. Use the drop down language selection to show both translations of the page.

2012 Falafel Software

362

Sitefinity 5

Localizing In Code
Once Sitefinity is configured for multiple languages as described in the Localization section of this courseware, you can programmatically translate pages and content. The key is to change the UICulture property of the page before modifying PageData properties. The example below changes the UICulture to "ES", gets an instance of the page titled "Home" and changes the Title to "Casa".
protected void LocalizePageButtonClick(object sender, EventArgs e) { PageManager manager = PageManager.GetManager(); this.UICulture = "ES"; var page = manager.GetPageDataList() .ToList() .Where(p => p.Title == "Home") .Where(p => !p.IsBackend) .Single(); page.Title = "Casa"; manager.SaveChanges(); }

After running this code and navigating back to Pages, the "ES" edit button is now enabled and when "espanol" is selected from the languages drop down, the translated text "Casa" shows up.

Figure 303 --Localized Title

2012 Falafel Software

Localization

363

Localizable Strings
The Title and other localizable Sitefinity properties aren't strings but actually Lstring properties. Lstring is a localizable string that is sensitive to the current culture. In most cases you treat an Lstring like a standard string, and as long as you have the UICulture set, Sitefinity will place your string assignments into the storage for the proper culture.

2012 Falafel Software

364

Sitefinity 5

Localizing Back End Pages


Localizing back end pages is similar to localizing front-end pages, using the same mechanism from the Administration Settings > Languages to add languages. Click the Manage backend languages link to see the Add languages... button. Click Add languages... to display the Select languages dialog. Select one or more languages from the list and click the Done button. Finally, click the Save changes button on the Languages page.

Figure 304 --Adding Languages to the Backend

After clicking the Close languages for the backend system link, a drop down will allow you to choose the language for the backend system. Select a new language from the drop down list, then click the Save changes button.

Figure 305 --Choosing the Backend Language

There is no immediate change where you see the menu language change. You need to load translated Interface Labels & Messages to see the effect.

2012 Falafel Software

Localization

365

Interface Labels & Messages


The Administration > Interface Labels & Messages menu item displays a page that lists all the labels, captions and other text in the system that can be localized. These labels populate all text in the system including the Administration menu text, widget text and even the column headings in grid widgets. Each label can be edited to define the Invariant language (the default language) and for each language you have configured from the Administration > Settings > Languages. You can import "Language Packs" of these labels in .xlsx spreadsheet format. Sample language packs can be downloaded from the Sitefinity marketplace online.

Figure 306 --Interface Labels & Messages page.

Refresh the page to see all the resourced items in the system display in the corresponding language.

Figure 307 --Resourced Labels

2012 Falafel Software

366

Sitefinity 5

Click on an item in the list to edit the "Invariant" (default) language, and for each language you have defined.

Figure 308 --Saving a Translated Label

2012 Falafel Software

Localization

367

Summary
In this chapter you learned how to localize front end pages using Sitefinity Administration, how to localize strings in code, how to localize back end pages and how to use the Interface Labels & Messages page.

2012 Falafel Software

19
Working with Widgets

Working with Widgets

369

19

Working with Widgets


You can create widgets for your Sitefinity website by writing a user control or a custom control. A user control is easier to build using Visual Studio support but does not allow Sitefinity design time support and is not designed to be deployed across multiple web sites. A custom control is slightly more difficult to build, but does allow design time support and can be deployed as a single .dll across multiple web sites.

2012 Falafel Software

370

Sitefinity 5

Objectives
This chapter steps you through how to create user and custom controls available from the toolbox and usable within the page. You will also learn how to create designers for custom controls to assist your users in configuring the control. You will use a RadControls "RadComboBox" and "RadGrid" inside your page as well as perform CRUD operations against live data. You will see how to integrate a Silverlight control and how to make the Silverlight control and page communicate. Finally, you will create a custom form control.

2012 Falafel Software

Working with Widgets

371

User Controls
User controls are an easy way to encapsulate some set of controls and HTML layout in a single named control. User controls can be stuffed with standard ASP.NET controls, RadControls for ASP.NET or any other third party controls. The following shows how to build a control right in the Visual Studio designer, dragging and dropping controls from the Toolbox to create whatever layout you want and adding your own code-behind if necessary. Within your user control, you have a complete user interface. This is pure ASP.NET development where you can connect to databases: OpenAccess, MS SQL, Oracle or any other database you have a driver for. You can also use web services to get data from the "outside world" such as SalesForce or some other CRM product. Once the control is created, you register the control and it becomes a "first class citizen" in Sitefinity that can be used like any other widget and dropped into any Sitefinity content placeholder.

2012 Falafel Software

372

Sitefinity 5

Create a User Control


In this set of steps you create a user control that is a "bread sandwich". It really doesn't do anything meaningful yet 1) From the Visual Studio Solution Explorer, right-click the Sitefinity project and select Add > New Item. 2) In the Add New Item dialog, select Web > Web User Control . 3) Name the control "MyControl.ascx" and click the Add button. This will create the .ascx file and the associated code behind file.

Figure 309 --Adding the User Control

2012 Falafel Software

Working with Widgets

373

4) Drag a Label control from the Toolbox to either the Design or Source view of the MyControl.ascx control.

Figure 310 --Designing the User Control

5) Using the Properties pane, change the Label properties to the following: ID: "MyLabel" Text = "Hello Sitefinity!" 6) Build the project.

Register a User Control


For the user control to be recognized in Sitefinity and visible in the Sitefinity toolbox, you will need to register the control. You should create one or more Toolbox sections that will contain your control, then add your new widget your Toolbox section.

2012 Falafel Software

374

Sitefinity 5

Create a Toolbox Section A toolbox section is used to organize widgets and could be named for your organization e. g. "My Company Widgets" or for some category you choose e.g. "List Widgets", "New related widgets", etc. 1) From the Sitefinity menu, select Administration > Settings. 2) Click the Advanced link to see all the possible settings. 3) Select the Toolboxes > Toolboxes > PageControls > Sections option. 4) Click the Create new button. This will create a new Toolbox section. 5) Enter the following: Name: "MyControls". You can use this internal name later to access this section of widgets. Title: "My Controls". This text will be displayed in the user interface. Description : "These are my controls". This describes the section in the toolbox. ResourceClassId: leave this blank. You can use this later if you want to include an image, font or other resource for this specific section.

2012 Falafel Software

Working with Widgets

375

6) Click the Save changes button.

Figure 311 --Defining a Toolbox Section

2012 Falafel Software

376

Sitefinity 5

Add a Widget to the Toolbox 1) In Settings, navigate to the tools for your new section at Toolboxes > Toolboxes > PageControls > Sections > MyControls > Tools. There shouldn't be any tools listed there yet. 2) Click the Create new button.

Figure 312 --Creating a New Toolbox Item

3) Some of the fields on this page are specific to custom controls or controls within modules and can be left alone. Enter the following and leave the remaining fields blank: Control CLR Type or Virtual Path : "~/MyControl.ascx". In the case of a User Control, this is a virtual path to the control in the project. The leading tilde "~" indicates a path relative to the root of the website. Name: "MyControl" Title: "My Control" Description : "My Control Description"

2012 Falafel Software

Working with Widgets

377

4) Click the Save changes button.

Figure 313 --Adding the Toolbox Item

2012 Falafel Software

378

Sitefinity 5

Notes

All the information for configuring the widget ends up in a configuration file \App_Data\Sitefinity\Configuration\ToolboxesConfig.config.
... <add enabled="True" title="My Controls" description="These are my controls" resourceClassId="" name="MyControls"> <tools> <add enabled="True" type="~/MyControl.ascx" title="My Control" description="My Control Description" resourceClassId="" cssClass="" layoutTemplate="" moduleName="" name="MyControl" /> </tools> </add> </sections> </toolbox> </toolboxes> </toolboxesConfig>

Only ASP.NET specific configuration is found in the Web.Config file, all other Sitefinity specific configuration has been moved into separate, purpose specific, XML files in \App_Data\Sitefinity\Configuration.

2012 Falafel Software

Working with Widgets

379

Test the New Widget


1) From the Sitefinity menu, select Pages. 2) Open an existing page or create a new page to work with. 3) Scroll to the bottom of the list of widgets and find your new section and widget: 4) Drag the widget to a content area on the page. The widget should display the message.

Figure 314 --Adding the Widget to the Page

5) Notice that the Toolbox shows the title of the section as "My Controls" and the title of the control as "My Control". The actual content of the label displays in the widget itself when dropped on the page.

Gotcha!

If a message pops up "Type 'MyControl.ascx' cannot be resolved", go back to the Toolbox configuration and change the Control CLR Type or Virtual Path entry. If the control is in the root directory of the project, the correct path will be "~/MyControl. ascx". Production sites typically have controls grouped in a subdirectory, e.g. "/ MyControls", in which case Control CLR Type or Virtual Path will be "~/MyControls/ MyControl.ascx". Also, be sure to build the project so that the type is available when Sitefinity goes looking for it.

2012 Falafel Software

380

Sitefinity 5

Adding Code Behind


The widget shows up in the toolbox, can be dragged into the page, but so far has no real functionality. The next step is to add a property to the widget that can be set when designing the Sitefinity page. 1) In the Visual Studio Solution Explorer, open the MyControl.ascx.cs file for editing. 2) Add a new string property named "MyProperty". Decorate the property with the Category attribute, passing the category name "My Properties".
[Category("My Properties")] public string MyProperty { get; set; }

3) In the Page_Load event handler, assign "MyProperty" to the Text property of the Label.
protected void Page_Load(object sender, EventArgs e) { this.MyLabel.Text = this.MyProperty; }

4) Build the project. 5) Open the Sitefinity dashboard and navigate to the test page for your widget. You can either use an existing page or create a new page for this. 6) If "MyControl" isn't already on the page, drag it onto the page from the widgets listed to the right of the design area. 7) Click the Edit link found on the upper right of the control.

Figure 315 --Editing the Control Properties

8) Click the Categorized button.

Figure 316 --Categorizing Properties

2012 Falafel Software

Working with Widgets

381

9) Notice the "My Properties" category has appeared with "MyProperty" underneath it. Enter some text into MyProperty and click the Save button.

Figure 317 --Saving the Properties

10)The control now displays the text in the label.

Figure 318 --The Property Value Reflected in the Control

2012 Falafel Software

382

Sitefinity 5

Custom Controls
While Custom Controls are somewhat more difficult to build, they are more powerful and easier to deploy than User Controls. This is the recommended method for building production controls in Sitefinity websites.

The Game Plan


The steps to building a Custom Control are: 1) Create a Class Library Project. 2) Add a Layout Template (ascx file) to the class library. 3) Create a Custom Control that consumes the Layout Template, declares properties and initializes the control according to the property values. 4) Register the Custom Control in the Sitefinity administrator. 5) Test the Custom Control.

Create the Class Library Project


1) From the Visual Studio Solution Explorer, right-click the solution and select Add > New Project from the context menu. 2) In the Add New Project dialog, select the Class Library project type and make sure that "NET Framework 4" is selected in the drop down at the top of the form. Enter project properties: Name: "MyOrganization.MyControls".

Notes

As a convention, projects are often named akin to a namespace, in roughly the form shown below:
<Organization name>.<Functional category>.<specific control>

Location : Leave the default.

2012 Falafel Software

Working with Widgets

383

3) Click the OK button to create the project.

Figure 319 --Creating the Project

4) In the Solutions Explorer, right-click the References node, select Add Reference, locate and select "System.Web" and click the OK button to add the references and close the Add Reference dialog. Also add a reference to "Telerik.Sitefinity" by using the Browse tab of the Add Reference dialog, then locating the assembly in the Sitefinity install directory under \_EmptyProject\bin.

2012 Falafel Software

384

Sitefinity 5

Add a Layout Template

1) To the Solution Explorer, right-click the SitefinityWebApp and select Add > New Item... from the context menu. Select Web > Web User Control. Name the file "MyLayoutTemplate.ascx".

Figure 320 --Defining the Layout Tem plate

2) Also, in the Solution Explorer, cut the "MyLayoutTemplate.ascx" from the SitefinityWebApp project. Paste the file to the MyOrganization.MyControls project. Tip: You can also drag the file, while holding to the Shift key to move the file from one project to another. The solution should now look something like the screenshot below.

Figure 321 --The Tem plate in the Project

3) In the Solution Explorer, right-click the "MyLayoutTemplate.ascx" and select Properties from the context menu. Set the Build Action property to Embedded Resource.

2012 Falafel Software

Working with Widgets

385

Gotcha!

You may see an error "Unable to find resource..." if you forget this step.

4) In the Solution Explorer, double-click the "MyLayoutTemplate.ascx" file to open it for editing. 5) Drag a Label from the Toolbox to the end of the aspx markup.

Figure 322 --Adding a Label to the Layout Tem plate

2012 Falafel Software

386

Sitefinity 5

Create the Custom Control


Now that the class library is created you can add your custom control class to it. 1) In the Solution Explorer, right-click the default "class1.cs", select Rename from the context menu and set the name to "MyCustomControl.cs". 2) A dialog will display asking if you want to rename the underlying class. Select OK.

Figure 323 --Allow ing the Renam e

3) Add the "public" keyword and inherit the class from SimpleView. SimpleView has the basic functionality needed for any web control that has child controls and adds the Sitefinity-specific properties for handling templates and resources.
public class MyCustomControl: SimpleView { }

4) Right-click SimpleView and select Implement Abstract Class from the context menu.

2012 Falafel Software

Working with Widgets

387

5) Implement the LayoutTemplateName property. This should return the name of the project followed by the path to the layout template file. In this case, "MyCustomView.ascx" is in the root of the "MyOrganization. MyControls" project. SimpleView automatically reads the LayoutTemplateName property each time the widget is refreshed, e.g. just after editing any properties of the widget.
protected override string LayoutTemplateName { get { return "MyOrganization.MyControls.MyLayoutTemplate.ascx"; } }

6) Override the InitializeControls() method using the code below. This example gets a reference to the "Label1" control in the "MyCustomView.ascx" layout template. Label1's Text property is set to the value of MyCustomProperty - we will define MyCustomProperty in the next step of this walk-through. InitializeControls() runs right after the assignment of the LayoutTemplateName and allows you to access any controls in the layout template and initialize them.
protected override void InitializeControls(GenericContainer container) { Label label = container.GetControl<Label>("Label1", true); label.Text = this.MyCustomProperty; }

2012 Falafel Software

388

Sitefinity 5

Tip!

If you don't have a reference in the "using" (C#) or "Imports" (VB) to support a particular class, then class names may be underlined in red to flag the error. The easy way to fix this is to place your cursor on the class name. Notice the small blue underline and move your mouse over this area. From the drop down menu that appears, select the "using" option to automatically add the reference.

2012 Falafel Software

Working with Widgets

389

7) Add a property with a category to the custom control class.


[Category("My Category")] public string MyCustomProperty { get; set; }

Q & A...

Question : I want to hide the EnableViewState property so that the designer does not need to see it. Can I hide an existing property? Answ er : Yes, you can override any of the properties coming from CompositeControl and decorate these properties with the Browsable() attribute, passing false as the parameter. The example below hides the EnableViewState from view when editing the custom control.
[Browsable(false)] public override bool EnableViewState { get { return base.EnableViewState; } set { base.EnableViewState = value; } }

2012 Falafel Software

390

Sitefinity 5

8) Build the project. 9) Add the reference to your class library to the Sitefinity project. Right-click the SitefinityWebApp project and select Add Reference... from the context menu. In the Add Reference dialog that appears, select the Projects tab. Select your class library from the list and click the OK button. The class library should now show in the list of referenced assemblies:

Figure 324 --Referencing the Class Library

2012 Falafel Software

Working with Widgets

391

Register the Custom Control


1) From the Sitefinity menu, select Administration > Settings. 2) Click the Advanced link to see all the possible settings. 3) Select the Toolboxes > Toolboxes > PageControls > Sections option. 4) You can use the existing "MyControls" section created in the previous walk-through User Controls > Register a User Control > Create a Toolbox Section, or create a new section. 5) Navigate to the Tools node of the section and click the Create new button.

Figure 325 --Creating a new Tool Item

6) Enter the following settings: Control CLR Type or Virtual Path: "MyOrganization.MyControls.MyCustomControl, MyOrganization.MyControls". The basic naming scheme is:
<full name of class>,<name of the dll>

The full name of the class includes the entire namespace of the class. A comma follows the full class name. Next comes the name of the dll (without the dll extension). Another example if the namespace of the class is "InterSlice. VisualControls", the class name is "Spinner" and the dll is "InterSliceControls.dll", then CLR Type should be:
InterSlice.VisualControls.Spinner,InterSliceControls

2012 Falafel Software

392

Sitefinity 5

Name: "MyCustomControl" Title: "My Custom Control" Description : "My Custom Control Description"

Figure 326 --Defining the Tool Item

7) Click the Save changes button.

2012 Falafel Software

Working with Widgets

393

Test the Custom Control


1) From the Sitefinity menu, select Pages. 2) Open an existing page or create a new page to work with. 3) Scroll to the bottom of the list of widgets and find the section that you added your custom control to and the custom control itself: 4) Drag the widget to a content area on the page. 5) Click the Edit link. Notice that there are more properties found in the SimpleView and that "MyCustomProperty" is also included in the list. 6) Enter some text to MyCustomProperty and then click the Save button.

Figure 327 --Custom Control Displayed

2012 Falafel Software

394

Sitefinity 5

Custom Control Designers


By default, the Advanced designer for a custom control is a simple dump of every property picked up using reflection. This presents unwanted properties that can confuse non-programmers or allow property changes that can actually cause a widget to perform incorrectly.

Figure 328 --Advanced Designer

2012 Falafel Software

Working with Widgets

395

If you want a designer that is suitable for non-programmers to use, you will need to build a designer for the control and make it available to Sitefinity. The following walk-through leads you through creating a simple designer for the custom control created in the previous section of this Courseware. In the example, your designer will have styles and an image stored in a resource file and an HTML input control used to collect a value from the user for storage in "MyProperty" and display in the custom control. The walk-through will use the custom control created in the previous section Custom Controls.

Figure 329 --Designer for Custom Control

2012 Falafel Software

396

Sitefinity 5

The Game Plan


Creating a designer for a custom control involves a number of files that must all work together. You can only test the designer when all these pieces are in place. None of the individual steps are too complicated, but all of the pieces must be correct for the designer to display properly. Much of the code, particularly the JavaScript, is "boiler-plate" code that you can reuse for other projects. But first you need to get it working that one time. Be encouraged that all the code and screenshots are taken from a functioning example, so go slow, make sure of your spelling (including case sensitivity) and copy & paste where you can. The walk-through that follows builds off the previous Custom Controls section of this Courseware. The steps to building a custom control designer are: 1) Prepare resource files to be used by the designer Images Style sheet Designer JavaScript 2) Code the Designer 3) Register the Designer 4) Test the Designer

2012 Falafel Software

Working with Widgets

397

Preparing Resources
Everything used by the custom control and designer needs to be wrapped up in a dll -- no stand-alone files allowed. CSS files, JavaScript and Images all need to be stored and accessed as resources. The general steps to creating resource required by the designer are: 1) Create a \Resource directory in your class library project. The particular directory name is optional, but Telerik recommends this approach and we will follow the convention in this example. 2) Set the Build Action property of your resource file to "Embedded Resource". Resources not marked in this way will not end up in your dll and therefore can't be found. This is a key step that will cause a lot of fruitless debugging time if you forget. Get in the habit of setting the Build Action property first thing after adding it to the \Resource directory. 3) Make the resources available to requests. This is done various ways depending on where the resource is used. Register resources in AssemblyInfo.cs to expose resources to web requests. This is done by adding WebRequest attributes for each resource and is used for images referenced in the style sheet. Using the special Sitefinity ResourceFile tag in markup to include the resourced stylesheet so it can be used right in an ascx. The designer ascx will use the ResourceFile attribute to include the stylesheet resource so that the styles can be referenced directly in the ascx markup. JavaScript and ascx resource files will be referenced directly in the designer class code. Prepare Images 1) In the Solution Explorer, add a new folder to the MyOrganization.MyControls project and name it "Resources". 2) From the Windows Explorer, drag an image to the \Resources folder. You can borrow a copy of the "Logo.png" image from the "CarConduit" theme. 3) Set the image file's Build Action property to "Embedded Resource".

Gotcha!

Forgetting this step can eat up a lot of development time. Get in the habit of setting the Build Action right away after you add any resource.

2012 Falafel Software

398

Sitefinity 5

4) Open the \Properties.AssemblyInfo.cs for the class library.

Figure 330 --Opening Assem blyInfo.cs

5) Scroll to the bottom of the file and add the WebResource attribute as shown in the example below. The first parameter is the path to the image resource and the second is the MIME type.
[assembly: WebResource("MyOrganization.MyControls.Resources.logo.png", "image/png")]

Your image resource is now prepared and ready to be accessed from a style sheet.

2012 Falafel Software

Working with Widgets

399

Prepare the Stylesheet 1) Right-click the \Resources folder and select Add > New Item... 2) Select the Web > Style Sheet item type. Name it "Default.css" and click the Add button. 3) Set the file's Build Action property to "Embedded Resource". 4) Replace the content of the style sheet with the styles below. Notice that the backgroundimage style uses a WebResource tag to set the url for the image.
body { } .BackgroundStyle { background-color: White; background-image:url(<% = WebResource("MyOrganization.MyControls.Resources.logo.png") %>); background-position: center center; background-repeat: no-repeat; height: 150px; } .TitleStyle { font-size:large; color:Gray; padding:10px; } .MessageStyle { float: right; margin: 10px; position: relative; top: 65px; }

2012 Falafel Software

400

Sitefinity 5

Prepare Designer JavaScript The JavaScript resource created in this step gets loaded later in the designer class code. This code creates a client-side representation of the designer and allows interaction between the designer and the custom control. 1) Right-click the \Resources folder and select Add > New Item... 2) Select the Web > Jscript item type. Name it "MyDesigner.js" and click the Add button. 3) Set the Jscript file Build Action property to "Embedded Resource". 4) Copy the JavaScript below into the MyDesigner.js file. The code here will register a namespace, create a client-side instance of the designer class and register the designer class with ASP.NET.
// register the namespace Type.registerNamespace("MyOrganization.MyControls"); // create an instance of the designer class MyOrganization.MyControls.MyDesigner = function (element) { MyOrganization.MyControls.MyDesigner.initializeBase(this, [element]); } // add designer logic here --> // register the designer class MyOrganization.MyControls.MyDesigner.registerClass('MyOrganization.MyControls.MyDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase); if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

5) Replace the comment "add designer logic here" with the JavaScript below.
// add logic to the designer class MyOrganization.MyControls.MyDesigner.prototype = { initialize: function () { MyOrganization.MyControls.MyDesigner.callBaseMethod(this, 'initialize'); }, dispose: function () { MyOrganization.MyControls.MyDesigner.callBaseMethod(this, 'dispose'); }, // loads the current control settings // jQuery interacts with DOM, "#MessageText" is the id of a DOM element refreshUI: function () { var data = this._propertyEditor.get_control(); jQuery("#MessageText").val(data.MyCustomProperty); }, // called when user clicks save b utton applyChanges: function () { var controlData = this._propertyEditor.get_control(); controlData.MyCustomProperty = jQuery("#MessageText").val(); } }

2012 Falafel Software

Working with Widgets

401

This code has two sets of methods. The initialize() and dispose() methods create and discard the designer instance when the custom control's edit dialog appears and closes. This is "boiler-plate" code that just needs to be there and have the correct client-side namespace for the designer. The refreshUI() method loads the current settings for the custom control into properties of the designer. The call to get_control() retrieves the custom control instance and can be used to reference the custom control's properties. The "#MessageText" refers to a text input where the ID is "MessageText". JQuery puts all of this together by first digging into the DOM and getting the MessageText element instance, then the JQuery val() method sets a value for MessageText from the custom control's property. The applyChanges() method gets called when the user clicks the save button and does essentially the reverse of the refreshUI method. In this case, the value of the MessageText input control is assigned back to the custom control's property. In this example we're keeping it simple with just a single property, but typically, both methods will have a list of assignments, one for each property.

2012 Falafel Software

402

Sitefinity 5

Create the Designer ascx To create a visual layout for the custom control designer, you will need to create an ascx file resource. 1) Create an ascx file to represent the designer user interface. The problem is that you can't right-click the Resources folder and directly add an ascx for the Class Library project type. The trick is to create the ascx in the Sitefinity web site project, then move it over to the Resources folder. In the Solution Explorer, right-click the Sitefinity web site project Select Add > New Item... from the context menu. Select the Web > Web User Control item type. Name the web user control "MyDesigner.ascx" and click the Add button.

Figure 331 --Adding the ascx File

2) Drag the MyDesigner.ascx file from the SitefinityWebApp to the class library "MyOrganization.MyControls\Resources" folder. Hold the Shift key down while you drag to move the file instead of copying. 3) Set the ascx file's Build Action property to "Embedded Resource". 4) Open the MyDesigner.ascx to edit the markup.

2012 Falafel Software

Working with Widgets

403

5) At the bottom of the file, register the Telerik.Sitefinity assembly.


<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sitefinity" %>

6) Below the assembly registry, add the ResourceLinks tag below. The ResourceLinks control automatically loads resources and the ResourceFile represents a single resource in the ResourceLinks collection. The ResourceFile Name attribute points to the path of the resource file in the project. The AssemblyInfo points to the full name of the type that contains the resource. Adding the Static attribute and setting it true indicates that the resource is either an external or embedded resource (i.e. not part of a Telerik theme).
<sitefinity:ResourceLinks runat="server"> <sitefinity:ResourceFile Name="MyOrganization.MyControls.Resources.Default.css" AssemblyInfo="MyOrganization.MyControls.MyCustomControl, MyOrganization.MyControls" Static="true" /> </sitefinity:ResourceLinks>

7) Below the ResourceLinks tag, add the following markup. The markup sets up a basic layout that uses the styles from the Default.css style sheet resource file and also includes an HTML Input element that will collect data from the user.
<div class="BackgroundStyle"> <div class="TitleStyle"> CarConduit Designer</div> <input id="MessageText" type="text" class="MessageStyle" /> </div>

That completes the designer layout so that it can be referenced from the designer class.

2012 Falafel Software

404

Sitefinity 5

Code the Designer Class


The designer class pulls all the pieces you have prepared into a cohesive whole. 1) Right-click the class library project References and add System.Web.Extensions from the .NET tab. 2) Right-click the class library project and select Add > Class... from the context menu. Name the class "MyDesigner.cs" and click the Add button. 3) Add System.Web.UI and Telerik.Sitefinity.Web.UI.ControlDesign namespaces to your "using" (C#) or "Imports" (VB). 4) Inherit your class from ControlDesignerBase.
public class MyDesigner: ControlDesignerBase { }

5) Right-click the ControlDesignerBase class and select Implement Abstract Class from the context menu. The code should now look like the example below:
public class MyDesigner: ControlDesignerBase { protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) { throw new System.NotImplementedException(); } protected override string LayoutTemplateName { get { throw new System.NotImplementedException(); } } }

6) Replace the InitializeControls() method with the code below. This method determines what the user sees in the dialog when they click the custom control's Edit link. You can assign the ControlDesignerModes Simple, Advanced or Both . In this example, we will only show our "Simple" designer instead of the default "Advanced" designer.
protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) { base.DesignerMode = ControlDesignerModes.Simple; }

2012 Falafel Software

Working with Widgets

405

7) Replace the LayoutTemplateName property with the code below. When the designer needs the layout template, the MyDesigner.ascx markup will be used.
protected override string LayoutTemplateName { get { return "MyOrganization.MyControls.Resources.MyDesigner.ascx"; } }

8) Add an override for the TagKey property. This just specifies that we want a div wrapper tag around the layout template to make common styling easier.
protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } }

9) Add an override for the GetScriptReferences() method. This code pulls the MyDesigner.js file out of the resource and makes it available to the designer.
public override IEnumerable<ScriptReference> GetScriptReferences() { var res = new List<ScriptReference>(base.GetScriptReferences()); var assemblyName = this.GetType().Assembly.GetName().ToString(); res.Add(new ScriptReference("MyOrganization.MyControls.Resources.MyDesigner.js", assemblyName)); return res.ToArray(); }

That completes the designer class so that the class can be registered as the designer for the custom control.

Register the Designer


In the custom control itself, add the ControlDesigner attribute above the class declaration. This initializes a designer instance for use with this custom control.
[Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesigner(typeof(MyDesigner))] public class MyCustomControl : SimpleView

2012 Falafel Software

406

Sitefinity 5

Test the Designer


1) Build the solution in Visual Studio. 2) In the Sitefinity administration, navigate to the test page you used in for Custom Controls section of this courseware. 3) Click the Edit link of the custom control. If the steps up to this point are performed correctly, you should see the Simple designer. Styling should place the text "CarConduit Designer" in the upper left corner, using a large gray font. The image should be centered in a white background. The text input should appear in the lower right area. 4) The first time you see this text input, it may have the text "NULL" -- you will need to write safety code in the JavaScript refreshUI() method to fix this. For now, just enter some text into the text input and click the Save button.

Figure 332 --The Working Designer

5) When the designer dialog closes, the custom control should display the value entered in the designer.

Figure 333 --Designer Value Displayed in Control

2012 Falafel Software

Working with Widgets

407

Troubleshooting
Here are a few things to check if the designer is not displaying for your control: 1) Are all resources marked with a Build Action of "Embedded Resource"? 2) If the image doesn't show, does the AssemblyInfo.cs WebResource() attribute point to the correct image file name and path? Is the extension of the image and the MIME type correct and matching? 3) In the MyDesigner.js code: Do the method names have the proper case sensitive names? If you copy and paste the code from the example (recommended), did you get all of the code? Did you pick up any other characters that weren't part of the code? Does the namespace and class names throughout the JavaScript file agree? 4) Is the ControlDesigner attribute applied to the correct class? Make sure the attribute is sitting on top of the SimpleView class. 5) In the designer class check: Does the control descend from ControlDesignerBase? In the InitializeControls() method, is the DesignerMode assigned Simple or Both? If you're assigning Advanced, you will only see the default, Advanced designer. In the LayoutTemplateName property, is the path to the ascx control correct? In override of the GetScriptReferences() control, is the path to the JavaScript file resource correct? 6) In the Default.css file, if the image is not showing, verify that the WebResource() assignment to the background-image css selector uses the correct path. 7) Did you build the solution?

2012 Falafel Software

408

Sitefinity 5

Using RadControls for ASP.NET AJAX with Sitefinity


RadControls can be used in both User Controls and Custom Controls. ASP.NET AJAX support is included automatically by Sitefinity. From the Page properties you can optimize the support with the following options: Enable the Include RadScriptManager option to use a RadScriptManager instead of the standard ScriptManager. This can increase efficiency by combining scripts, causing fewer trips to the server. Select the Enable ViewState option when the page needs to remember the state of a control between refreshes. For example, if a combo box needs to retain the selected item after the user clicks something from the list.

Prepare the Project


Setup the page to enable ViewState for controls that retain state between postbacks and to include the RadScriptManager for better efficiency. 1) Create and register a user control as described in the User Controls section of this courseware. 2) In the Sitefinity administration menu, click the Pages link. 3) In the Actions drop down for the page containing the user control, select the Titles & Properties option. This will display the Edit a page dialog. 4) In the Edit a page dialog, select the checkboxes for Enable ViewState and Include RadScriptManager.

Figure 334 --Enabling View State and RadScriptManager

2012 Falafel Software

Working with Widgets

409

Display a Collection Using RadComboBox


The following walk-through demonstrates binding Roles to a RadComboBox. 1) In Visual Studio, drag a RadComboBox from the toolbox to the user control markup. Set the AutoPostBack property to "true". The markup at this point should look something like the example below.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="SitefinityWebApp.MyControl" %> <telerik:RadComboBox ID="RolesCombo" runat="server" AutoPostBack="true" Label="Roles "> </telerik:RadComboBox>

2) Add the code below to the user control code-behind in the Page_Load method. This will populate the RadComboBox with all the built-in role names and their Guid Id's.
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RoleManager manager = RoleManager.GetManager(SecurityManager.ApplicationRolesProviderName); RolesCombo.DataTextField = "Name"; RolesCombo.DataValueField = "Id"; RolesCombo.DataSource = manager .GetRoles() .ToList(); RolesCombo.DataBind(); } }

3) Build the solution. 4) Test the control in a Sitefinity page.

Figure 335 --Displaying Roles in RadCom boBox

2012 Falafel Software

410

Sitefinity 5

Silverlight Controls
Silverlight controls are designed to be hosted in ASP.NET applications and so can be hosted by controls for your Sitefinity web application just as easily. You can host your Silverlight control in a User Control or Custom Control. The example that follows uses a simple Silverlight Button control. For a more complex scenario that builds on this walkthrough, see the Communication between Custom Control and Silverlight example that displays Sitefinity information in a RadBook control.

The Game Plan


The steps to building a control that hosts a Silverlight control: 1) Follow the steps in the previous topic to create a Custom Control. 2) Create a Silverlight Control. 3) Integrate the Silverlight Control with the User Control. 4) Test the Widget.

2012 Falafel Software

Working with Widgets

411

Create a Silverlight Control


Creating a Silverlight control starts with creating a Silverlight application in the same solution as the Sitefinity web site and then adding code to the Sitefinity web site that loads the Silverlight user control into the ASP.NET custom control. 1) In the Solution Explorer, right-click the solution and select Add > New Project... from the context menu. 2) In the Add New Project dialog, select Silverlight > Silverlight Application. Name the application "MySilverlightApplication" and click the OK button.

Figure 336 --Creating a New Silverlight Application

2012 Falafel Software

412

Sitefinity 5

3) In the New Silverlight Application dialog that displays, leave the Host the Silverlight application... checkbox selected and the drop down should have the "SitefinityWebApp" already selected. In the Options section of the dialog, unselect the Add a test page that references the application checkbox. Click the OK button to create the Silverlight application and close the dialog.

Figure 337 --Hosting the Silverlight Application in the Sitefinity Web Site

Instead of creating a new web site to host the Silverlight control, the Sitefinity web site will now host the control.

2012 Falafel Software

Working with Widgets

413

4) In the "MainPage.xaml" editor, drag a Silverlight Button control from the Toolbox.

Figure 338 --Adding the Button

5) Add a Content attribute to the Button and set the value to "Click Me!". 6) Add a Click attribute to the Button. When you enter the equal "=" sign, IntelliSense will prompt for "<New Event Handler>". Select the "<New Event Handler>" option to create the event handler.

Figure 339 --Creating the New Event Handler

7) Right click the new Click attribute and select Navigate to Event Handler from the context menu.

Figure 340 --Navigating to the Event Handler

2012 Falafel Software

414

Sitefinity 5

8) In the button Click event handler add the code below to display a simple message box.
private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Clicked!"); }

9) Save and build the solution. Open the \SitefinityWebApp\ClientBin directory. Notice that the compiled Silverlight application is placed in a .xap file and included in the SitefinityWebApp directory:

Figure 341 --The Com piled Silverlight Application

At this point you have a very simple Silverlight control hosted by the Silverlight application.

2012 Falafel Software

Working with Widgets

415

Integrate the Silverlight Control with User Control


While you can reference the Silverlight application from the Sitefinity application at this point, the Sitefinity page doesn't yet know to load the Silverlight control. The following steps add JavaScript and HTML to the Custom Control that load the Silverlight plug-in and startup your Silverlight application. 1) In the "MyOrganization.MyControls" custom control project, open the "MyLayoutTemplate.ascx" file to edit the markup. At the end of the file, paste the "boiler plate" JavaScript code below. This code will handle any errors that might occur when loading Silverlight.
<script type="text/javascript"> function onSilverlightError(sender, args) { var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; } var errorType = args.ErrorType; var iErrorCode = args.ErrorCode; if (errorType == "ImageError" || errorType == "MediaError") { return; } var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n"; errMsg += "Code: " + iErrorCode + " \n"; errMsg += "Category: " + errorType + " \n"; errMsg += "Message: " + args.ErrorMessage + "

\n";

if (errorType == "ParserError") { errMsg += "File: " + args.xamlFile + " \n"; errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } else if (errorType == "RuntimeError") { if (args.lineNumber != 0) { errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } errMsg += "MethodName: " + args.methodName + " \n"; } throw new Error(errMsg); } </script>

2) Below that, add the markup below. This contains the Silverlight plug-in object. In particular, notice the "<param>" attribute with the name "source". This key parameter points to your Silverlight application.

2012 Falafel Software

416

Sitefinity 5

<div id="silverlightControlHost" style="height: 400px; width: 100%"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value='<%= ResolveUrl("~/ClientBin/MySilverlightApplication.xap") %>' /> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="windowless" value="true" /> <param name="minRuntimeVersion" value="4.0.50401.0" /> <param name="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" style="text-decoration: none"> <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style: none" /> </a> </object> </div>

3) Locate the tag starting with "<param name='source'. Verify that the "value" part of the tag so that the ResolveUrl() path matches the path to the .xap file for your Silverlight application. In the example, the Silverlight application is named "MySilverlightApplication", so the parameter should be:
<param name="source" value='<%= ResolveUrl("~/ClientBin/MySilverlightApplication.xap") %>' />

4) Build the solution.

2012 Falafel Software

Working with Widgets

417

Test the Widget


1) From the Sitefinity menu, select Pages. 2) Open an existing page or create a new page to work with. 3) Scroll to the bottom of the list of widgets and find your new section and widget: 4) Drag the widget to a content area on the page. The widget should display the Silverlight user control that contains the button. The width and height properties on the button have not been set, so the button takes up the entire Silverlight control area. The "Hello Sitefinity!" message in the label at the top of the user control is from the original Custom Controls topic and is not a Silverlight control.

Figure 342 --The Hosted Silverlight Control

5) Click the Preview button to display the page. Click the Silverlight, "Click Me!" button. The Silverlight MessageBox.Show () method fires and displays a dialog above the button.

Figure 343 --Testing the Event

2012 Falafel Software

418

Sitefinity 5

Communication between Custom Control and Silverlight


"So far so good" in that we have a Silverlight control functioning inside a custom control. It would be cool if we could get the Silverlight controls to talk with the custom control. This conversation can happen by using a JavaScriptSerializer object. JavaScriptSerializer can convert to and from JSON (JavaScript Object Notation). JavaScriptSerializer can be used from both the ASP.NET code-behind of the custom control and in the JavaScript of the ascx layout template. In practice, the custom control code-behind can query the Sitefinity using the Standard API or Fluent API. The results are serialized into JSON and stored in a hidden field. Every time properties are changed for the widget, the Silverlight plug-in is reloaded and a JavaScript event fires. During the event, JavaScript code reads the JSON data. When Silverlight application methods are tagged with a [ScriptableMember] attribute, methods can be called directly from JavaScript. This means that as the JSON data is read in, Silverlight methods can be called, passing along the Sitefinity data. The relationship is roughly:
Sitefinity API <-> Custom Control <-> ASCX Template <-> Silverlight Application

The New Game Plan


The example that follows creates a custom control that hosts a Silverlight control. The Silverlight control display images using an interface that appears as a "book", complete with turning pages, courtesy of the RadBook Silverlight control.

Figure 344 --Custom Control With RadBook

2012 Falafel Software

Working with Widgets

419

We will follow the path starting from the custom control all the way out to the Silverlight application to update our solution:
Custom Control -> ASCX Template -> Silverlight Application

The steps that need to be added to our solution to populate Silverlight controls using Sitefinity data are: 1) Modify the SimpleView custom control. Add the [RequireScriptManager] attribute to the class that enables JavaScriptSerializer functionality in the ascx JavaScript code. Add a method to extract Sitefinity images from an album and place them in a serialization-friendly Hashtable. Override the InitializeControls() method to receive the extracted images, serialize them and place them in a hidden field. The hidden field will be located in the Layout Template ascx. 2) Modify the Layout Template ascx markup. Add a hidden field tag. Add a JavaScript method that reacts when the Silverlight plug-in is loaded. This method gets the data out of the hidden field left by the custom control, de-serializes the data and calls a method in the Silverlight control. Add a parameter to the Silverlight plug-in that calls the JavaScript method when the plug-in loaded. 3) Modify the Silverlight application. Add a simple class used for storing data and binding. Add a "scriptable" method to the Silverlight application that accepts an instance of the data class. Add XAML markup to define the Silverlight user interface.

2012 Falafel Software

420

Sitefinity 5

Modify the Custom Control 1) In the Solution Explorer, right-click the References node and add references to Telerik. Sitefinity.Model, Telerik.OpenAccess and System.Runtime.Serialization . The two Telerik assemblies can be found under the Sitefinity installation directory. System. Runtime.Serialization can be found in the .NET tab of the Add Reference dialog. 2) In your "using" statement (C#) or "Imports" (VB), make sure you are referencing the following namespaces:
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Web; using System.Web.Script.Serialization; using System.Web.UI.WebControls; using Telerik.Sitefinity; using Telerik.Sitefinity.GenericContent.Model; using Telerik.Sitefinity.Web.UI;

3) In the MyCustomCode.cs code-behind, add the RequireScriptManager attribute to the custom control class.
[Telerik.Sitefinity.Modules.Pages.Web.UI.RequireScriptManager] public class MyCustomControl : SimpleView

4) Add the method below to extract images from an album.


private List<Hashtable> GetImages() { List<Hashtable> results = new List<Hashtable>(); //get IQueryab le of images from the Fluent API. var images = App.WorkWith().Images() .Where(i => i.Parent.Title == this.MyCustomProperty && i.Status == ContentLifecycleStatus.Live) .Get(); // get the b ase url string authorityUrl = this.Page.Request.Url.GetLeftPart(UriPartial.Authority); string authority = VirtualPathUtility.RemoveTrailingSlash(authorityUrl); // Add each full url and title to the hash tab le foreach (Telerik.Sitefinity.Libraries.Model.Image v in images) { Hashtable table = new Hashtable(); table.Add("Url", authority + v.MediaUrl); table.Add("Title", v.Title.ToString()); results.Add(table); } return results; }

2012 Falafel Software

Working with Widgets

421

5) Override the InitializeControls() method to receive and serialize the list of images. Replace the code from the previous example with the code below. The GetControl() method returns an instance of a HiddenField in the Template Layout ascx. GetImages() returns a Hashtable of image data that is serialized into a JSON string and assigned to the HiddenField Value.
protected override void InitializeControls(GenericContainer container) { HiddenField imagesField = container.GetControl<HiddenField>("imagesField", true); imagesField.Value = new JavaScriptSerializer().Serialize(GetImages()); ; }

Modify the Layout Template 1) In the Layout Template ascx (i.e. "MyLayoutTemplate.ascx"), replace the Label with a HiddenField tag with an ID of "imagesField" so we can reference it later.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyLayoutTemplate.ascx.cs" Inherits="SitefinityWebApp.MyLayoutTemplate" %> <%--Add HiddenField tag here--%> <asp:HiddenField ID="imagesField" runat="server" /> <script type="text/javascript"> ...

2) Add a new JavaScript method that will react when the Silverlight plug-in is loaded. The method retrieves the HiddenField data and re-hydrates it as an array of objects. For each element in the array, a method in the Silverlight application called SetItem() is called. SetItem() will be coded in an upcoming step.
function pluginLoaded(sender, args) { slCtl = sender.getHost(); var imagesField = $get('<%= imagesField.ClientID %>'); if (imagesField != null) { var imagesArr = Sys.Serialization.JavaScriptSerializer.deserialize(imagesField.value); for (idx in imagesArr) { slCtl.Content.mainPage.SetItem(imagesArr[idx]['Title'], imagesArr[idx]['Url']); } } }

3) Add a parameter to the object tag for the Silverlight plug-in. The parameter specifies what JavaScript method should be called when the plug-in loads. This parameter points back up to the pluginLoaded() JavaScript method.
<object . . .> <param name="onLoad" value="pluginLoaded" />

2012 Falafel Software

422

Sitefinity 5

Modify the Silverlight Application 1) Edit the App.xaml file of the Silverlight application. Replace the Startup event handler with the code below. This makes the main Silverlight page reachable through JavaScript code in the Layout Template ascx file.
private void Application_Startup(object sender, StartupEventArgs e) { var mainPage = new MainPage(); this.RootVisual = mainPage; HtmlPage.RegisterScriptableObject("mainPage", mainPage); }

2) Add a class file to the Silverlight project for storing Sitefinity image data:
public class SitefinityImage { public string Url { get; set; } public string Title { get; set; } }

3) Add references to the Silverlight project for Telerik.Window s.Controls and Telerik. Window s.Controls.Navigation assemblies.

2012 Falafel Software

Working with Widgets

423

4) Add XAML markup below to define the Silverlight user interface. First add a Resources section to define the DataTemplate that paints each page of the RadBook. This markup should be placed just below the Grid "LayoutRoot". The "PageTemplate" has a light gradient border, an Image bound to a field named "Url" and a TextBlock bound to a field named "Title".
<Grid.Resources> <DataTemplate x:Key="PageTemplate"> <Border BorderThickness="1" BorderBrush="LightGray"> <Border BorderThickness="5" Margin="10" Padding="5"> <Border.BorderBrush> <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5"> <GradientStop Color="#4B917835" Offset="0" /> <GradientStop Color="#77958787" Offset="1" /> <GradientStop Color="#2D8F8F8F" Offset="0.32" /> </LinearGradientBrush> </Border.BorderBrush> <StackPanel Margin="10"> <Image Width="200" Height="200" Source="{Binding Url}" Stretch="Uniform" /> <TextBlock Text="{Binding Title}" /> </StackPanel> </Border> </Border> </DataTemplate> </Grid.Resources>

2012 Falafel Software

424

Sitefinity 5

5) Add the XAML for the RadBook. Replace the Button control from the earlier example.
<telerik:RadBook x:Name="book" FoldSize="250,250" LeftPageTemplate="{StaticResource PageTemplate}" RightPageTemplate="{StaticResource PageTemplate}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" RightPageIndex="1" FontFamily="Comic Sans MS" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"> </telerik:RadBook>

6) Add a "Scriptable" method to the Silverlight control code behind that can be fired from JavaScript and executed on the Silverlight control. The ScriptableMember attribute marks this method so that it can be called from JavaScript. The method creates a new SitefinityImage data object, populates it with the title and url passed in and adds it to the RadBook items.
[ScriptableMember] public void SetItem(string title, string url) { this.book.Items.Add( new SitefinityImage() { Title = title, Url = url }); }

2012 Falafel Software

Working with Widgets

425

Test the Widget 1) Rebuild the application. 2) Run the application and navigate to your test page. 3) Click the Edit button of the widget. Enter the name of an Album that has images loaded. You can use either the Custom Control Designer created in a previous lesson or use the Advanced properties to enter a new value for MyCustomProperty. When the Edit dialog closes, the widget will be reinitialized

Figure 345 --Setting MyCustom Property

2012 Falafel Software

426

Sitefinity 5

4) The Silverlight RadBook shows up in the Widget, complete with data that originated from the Sitefinity API.

Figure 346 --RadBook in Sitefinity Widget

2012 Falafel Software

Working with Widgets

427

Custom Form Controls


The Form Builder comes out-of-the-box with form control widgets that appear on the right-hand side of the Form Builder screen. While these basic widgets are functional, you may need to store other information such as dates or use special purposes controls like RadCaptcha. Fortunately, Sitefinity makes it possible to create custom controls that show up in the Form Builder and write data to the database. So for example, you could have an event registration form that takes a name and email address. Forms can be submitted from either the front-end (on a published page on the site) or from the back-end (from inside the Dashboard in the Forms module). This walk-through demonstrates creating a simple form custom control. The control is automatically populated with the name of the currently logged-in user. This name can be changed in the Textbox before submitting the form.

The Game Plan


Creating a custom form control involves the following steps: 1. Preparing a class library that will hold the ascx template, JavaScript file and a class file to rule them all. 2. Populating a Control Template ascx file with the elements that will display in the form control widget. 3. Populating the Client Script File so that Sitefinity will be able to write to the database from the back-end user interface. 4. Populating the Class file is the largest chunk of code in the project and involves Building a Class Skeleton, Implementing FieldControlProperties, Implementing the InitializeControls() method and Adding FieldControl Script Properties. 5. Registering the Control. 6. Testing the Control.

2012 Falafel Software

428

Sitefinity 5

Setting Up the Custom Control Project


To set up the project that contains the form custom control: 1. From the Sitefinity Project Manager, select the project to contain the new control and click the Edit in Visual Studio button. 2. Add a new class library project and name it CustomFormControls. 3. Add a new class NamedTextBox.cs. This class will define the controls behaviour. 4. Add a "Resources" folder to the "CustomFormControls" project. 5. Add a new template NamedTextBox.ascx to the Resources folder. The ascx file will define the control template, setting the look and feel. Be aware that class library projects don't allow adding new ascx files directly. Instead, add a new ascx file project item to the "SitefinityWebApp" project and move it to the \Resources folder of the "CustomFormControls" project. 6. In the Solution Explorer, right-click the "NamedTextBox.ascx" entry and select Properties from the context menu. In the Properties pane, set the Build Action property to "Embedded Resource". 7. Add a new Jscript file "NamedTextBox.js" in the Resources folder. This will define the controls client-side implementation. Set the Build Action to "Embedded Resource". 8. Your solution should now have two projects and look something like the screenshot below.

Figure 347 --Custom Form Controls Project

2012 Falafel Software

Working with Widgets

429

9. Add all references highlighted in the screenshot below. These references will be needed to create a custom form control.

Figure 348 --Adding References

10.Open the \Properties\AssemblyInfo.cs file for editing. Add a reference to the resource JavaScript file to the end of the file.
[assembly: WebResourceAttribute("CustomFormControls.Resources.NamedTextBox.js", "text/javascript")]

11.While you're there, add a "using" reference to System.Web.UI in the AssemblyInfo.cs file. 12.In the Sitefinity web application project, add a reference to the class library project "CustomFormControls".

Populating the Control Template


1) Edit the NamedTextBox.ascx file. In the "CustomFormControls" project, open the \Resources\NamedTextBox.ascx file for editing. Add the Telerik.Web.UI assembly to provide access to the RadControls. Add this line to the bottom of the file.
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>

2012 Falafel Software

430

Sitefinity 5

Add markup for Label and RadTextBox controls. Notice the CssClass attribute that matches the Sitefinity styles.
<asp:Label runat="server" ID="Label1" CssClass="sfTxtLbl" Text="title label" /> <telerik:RadTextBox ID="TextBox1" CssClass="sfTxt" runat="server" /> <br /> <asp:Label runat="server" ID="Label2" CssClass="sfExample" Text="example Label" /> <br /> <asp:Label runat="server" ID="Label3" CssClass="sfExample" Text="description Label" />

For reference, here is the entire NamedTextBox.ascx file:


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NamedTextBox.ascx.cs" Inherits="SitefinityWebApp.NamedTextBox" %> <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %> <asp:Label runat="server" ID="titleLabel" CssClass="sfTxtLbl" Text="title label"></asp:Label> <telerik:RadTextBox ID="TextBox1" CssClass="sfTxt" runat="server"> </telerik:RadTextBox> <br /> <asp:Label runat="server" ID="exampleLabel" CssClass="sfExample" Text="example Label"></asp:Label><br /> <asp:Label runat="server" ID="descriptionLabel" CssClass="sfExample" Text="description Label"></asp:Label>

Populating the Client Script File


JavaScript is required to save form control data to the database. Without JavaScript, users can save control data from the front-end, but not from the back-end. The JavaScript code below creates a client-side representation of the form control that Sitefinity can reference and provides access to any elements in the control (such as the RadTextBox, in this example). 1) As an absolute minimum to get the control to work, add the JavaScript below. The JavaScript registers the controls namespace/class and allows the control to be rendered in the browser.
// register the client-side namespace Type.registerNamespace("CustomFormControls"); // Create the NamedTextBox client-side control CustomFormControls.NamedTextBox = function (element) { // add control references here -->

2012 Falafel Software

Working with Widgets

431

CustomFormControls.NamedTextBox.initializeBase(this, [element]); } // set control properties here --> // register the control in the namespace CustomFormControls.NamedTextBox.registerClass('CustomFormControls.NamedTextBox', Telerik.Sitefinity.Web.UI.Fields.FieldControl);

2) To provide access to the RadTextBox, replace the comment "add control references here -->" with the code below. This code adds getter and setter method that support RadTextBox client-side properties.
//set control properties CustomFormControls.NamedTextBox.prototype = { get_value: function () { return this._textbox.get_value(); }, set_value: function (value) { this._textbox.set_value(value); }, get_textbox: function () { return this._textbox; }, set_textbox: function (value) { this._textbox = value; } }

Populating the Class File


The class file pulls together all of the other pieces, including the JavaScript file and the ascx template file. This is the largest set of code to complete and involves the following steps: 1. Building the Class Skeleton. 2. Implementing FieldControl Properties. 3. Implementing the InitializeControls() Method. 4. Adding the FieldControl Script Properties.

2012 Falafel Software

432

Sitefinity 5

Building the Class Skeleton 1) Open the "NamedTextBox.cs" class file for editing. 2) To save time, add the following references to your "using" (C#) or "Imports" (VB) statements:
System.Collections.Generic; System.ComponentModel; System.Web.UI; System.Web.UI.WebControls; Telerik.Sitefinity.Data.Metadata; Telerik.Sitefinity.Metadata.Model; Telerik.Sitefinity.Model; Telerik.Sitefinity.Modules.Forms.Web.UI.Fields; Telerik.Sitefinity.Security; Telerik.Sitefinity.Web.UI.Fields; Telerik.Sitefinity.Web.UI.Fields.Enums; Telerik.Web.UI;

3) Inherit from FieldControl, right-click "FieldControl" and select Implement Abstract Class from the context menu. This step will create stub methods for the abstract class.

Figure 349 --Im plem enting FieldControl

4) Add IFormFieldControl to the declaration, right-click "IFormFieldControl" and select Implement Interface > Implement Interface from the context menu.

Figure 350 --Im plem enting IForm FieldControl

2012 Falafel Software

Working with Widgets

433

Implement FieldControl Properties 1) Implement the DescriptionControl, ExampleControl and TitleControl properties. Add properties that retrieve the controls from the ascx file.
protected internal virtual Label TitleLabel { get { return this.Container.GetControl<Label>("titleLabel", true); } } protected internal virtual Label DescriptionLabel { get { return Container.GetControl<Label>("descriptionLabel", true); } } protected internal virtual Label ExampleLabel { get { return this.Container.GetControl<Label>("exampleLabel", this.DisplayMode == FieldDisplayMode.Write); } }

Add DescriptionControl, ExampleControl and TitleControl properties below.


protected override System.Web.UI.WebControls.WebControl DescriptionControl { get { return this.DescriptionLabel; } } protected override System.Web.UI.WebControls.WebControl ExampleControl { get { return this.ExampleLabel; } } protected override System.Web.UI.WebControls.WebControl TitleControl { get { return this.TitleLabel; } }

2) Add public properties to support Example, Title and Description in the property editor.
public override string Example { get; set; } public override string Title { get; set; } public override string Description { get; set; }

3) Add support for the Value of the NamedTextBox form control. Add a property that retrieves the RadTextBox control from the ascx.

2012 Falafel Software

434

Sitefinity 5

protected internal virtual RadTextBox TextBox1 { get { return this.Container.GetControl<RadTextBox>("TextBox1", true); } }

Add a Value property to get and set using the RadTextBox Text property as storage.
public override object Value { get { return this.TextBox1.Text; } set { this.TextBox1.Text = value.ToString(); } }

4) Replace the LayoutTemplateName property with the code below. The property should return the path that points to the ascx file.
protected override string LayoutTemplateName { get { return "CustomFormControls.Resources.NamedTextBox.ascx"; } }

Implement InitializeControls 1) Replace the InitializeControls implementation with the code below. This method fires whenever the form displays or when the Edit dialog returns with changed values . The controls in the form control widget for Example, Title and Description are fed from the corresponding public properties. The RadTextBox is initialized from the SecurityManager.GetCurrentUserName() method.
protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) { this.ExampleLabel.Text = this.Example; this.TitleLabel.Text = this.Title; this.DescriptionLabel.Text = this.Description; this.TextBox1.Text = SecurityManager.GetCurrentUserName(); }

2012 Falafel Software

Working with Widgets

435

Add FieldControl Script Properties 1) Add the FieldControl methods overrides below to get client-side script references. The first method, GetScriptDescriptors(), allows the front-end control to pass values for back-end publishing. Descriptors are added for the client-side RadTextBox and the DisplayMode property (determines if the mode is in Read or Write mode). The second method, GetScriptReferences(), tells the control which script files it needs to have access to in order to function correctly. A script reference is added to our custom "NamedTextBox.js" stored in the Resources directory and to the Telerik "FieldDisplayMode.js".
public override IEnumerable<ScriptDescriptor> GetScriptDescriptors() { var descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID); descriptor.AddComponentProperty("textbox", this.TextBox1.ClientID); descriptor.AddProperty("displayMode", this.DisplayMode); return new [] { descriptor }; } public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences() { var scripts = new List<ScriptReference>(base.GetScriptReferences()) { new ScriptReference( "CustomFormControls.Resources.NamedTextBox.js", this.GetType().Assembly.FullName), new ScriptReference( "Telerik.Sitefinity.Web.UI.Fields.Scripts.FieldDisplayMode.js", "Telerik.Sitefinity"), }; return scripts; }

2012 Falafel Software

436

Sitefinity 5

Register the Control


Now for the fun part where we add it to the Form Builder and see it in action. 1) First off, build the solution and then run the Sitefinity project. 2) Inside Sitefinity administration, add configuration settings for the new control. From the Administration menu select Settings > Advanced > Toolboxes > Toolboxes > FormControls > Sections > Common > Tools Click the Create New button. 3) Enter the configuration settings for the form control. For the Control CLR Type or Virtual Path enter the assembly name followed by the control type. In this example the Control CLR Type or Virtual Path is CustomFormControls.NamedTextBox. Name = "NamedTextBox. Title = "Named TextBox".

Figure 351 --Configuring the Form Control

4) Build the solution.

2012 Falafel Software

Working with Widgets

437

Test the Control


1) Create a new form (Content > Forms > Create a form). 2) You should now see the custom form control at the bottom of the list of standard, outof-the-box controls. 3) Drag the new form control widget onto the form. Notice how the logged-in users name gets added automatically to the Named TextBox control.

Figure 352 --Adding the New Form Control Widget

4) Click the Edit button and fill in a value for the "Title" property. This will become the title above your control, as well as the column name that your controls data will save to in the database. 5) Put the form on a page to view the custom control. Press the Submit button to submit the form and save the text box value.

2012 Falafel Software

438

Sitefinity 5

6) View the form response you just created. In the Sitefinity administration, go to Content > Forms and click on the "Responses" link for the form you're testing.

Figure 353 --View ing Responses

7) Now you should see the value you submitted in the textbox. Notice also that the title for the textbox value column is Logged-In User. You've now successfully saved form data through the front-end. 8) Now to save form data through the back-end. On the same "Responses" screen you're currently on, click the Create a Response button on the top-right of the page. This will show you the same form as above, but using the Sitefinity administration instead of the published site. Click the Submit button to save the form's data. You've now successfully saved form data through the back-end.

2012 Falafel Software

Working with Widgets

439

Summary
This chapter stepped through how to create user and custom controls available from the toolbox and usable within the page. You learned how to create designers for custom controls to assist your users in configuring the control. You used RadControls "RadComboBox" and "RadGrid" inside your page. You saw how to integrate a Silverlight control and how to make the Silverlight control and page communicate. Finally, you created a custom form control.

2012 Falafel Software

20
Working with Modules

Working with Modules

441

20

Working with Modules


Sitefinity has numerous content modules right out of the box, e.g. "News", "Blogs", "Events", etc. The built in types cover many standard scenarios, but your organization may need to store custom data, for example "Press Releases", "Stock Quotes" or "Employee Bio". You will need an administration back-end page to enter new data and a widget to display the data in various formats in your pages. Modules allow you to extend Sitefinity with custom content administration pages and front end page widgets.

2012 Falafel Software

442

Sitefinity 5

Objectives
In this chapter you will work with modules to handle custom data. You will learn how to create a custom module, add content to the module and add the module widget to a page to view the data. You will also learn how to customize the backend table of module data.

2012 Falafel Software

Working with Modules

443

Create a Custom Module


The steps to create a custom module are: Create a Custom Module Add Module Content Add the Module to a Page In this example we will create a new module that lists quotations from famous people. Each entry will have a "Quote", the "Source" author and a "Picture" of the author. 1. From the Sitefinity main menu select Administration > Module Builder. 2. Click the Create a Module link.

Figure 354 --Creating a Module

3. Enter a Name and Description for the module as a whole and click the Continue button.

Figure 355 --Nam ing the Module

2012 Falafel Software

444

Sitefinity 5

4. In the Define a content type page that shows next, enter the singular name of the Content type. In this example we're working with Quotations, so we enter "Quotation". The Content type entry will automatically fill in the Developer name of this content type. You can alter the developer name, but be sure to remove any spaces.

Figure 356 --Developer Nam es

2012 Falafel Software

Working with Modules

445

5. Below the Content type is an area for adding a list of fields used to store the content. By default, the standard content Title is already in the list, but can be removed. Click the Add a field... button. Enter the Name of the field (again without spaces). From the drop down list, select the Type of data this field represents. Leave the Interface widget for entering data at its default. Click the Continue button to finish defining the field.

Figure 357 --Adding a Field

2012 Falafel Software

446

Sitefinity 5

Notes

There are at least two interface widgets listed for each type, the built-in editor for the type and a Custom... option where you're expected to enter the virtual path to a custom .ascx widget. If you want to prevent entry you can select the This is a hidden field checkbox. The hidden field can be accessed programmatically but not through the interface widget.

2012 Falafel Software

Working with Modules

447

6. To finish the field definition, provide a Label that will be shown in the widget and the Instructional text that will be shown as a prompt. Select the This is a required field checkbox to force entry in this field.

Figure 358 --Entering Label and Instructional Text

2012 Falafel Software

448

Sitefinity 5

7. Click the Limitations link to place constraints on entry. You can set a simple Min and Max number of characters that can be entered or define a Regular expression to exactly define what kind of entry is allowed. Click the Done button to finish creating the field.

Figure 359 --Setting Field Lim itations

8. Once all the fields are defined, select the field that will be used as the identifier of the content from the drop down list. The drop down list will only show Short Text fields that are marked as Required .

Figure 360 --Setting the Identifier

9. Click the Finish button to create the module. The module will now appear in three locations in Sitefinity: Administration > Module Builder: Use this option to add or change fields, edit the name and description, make changes to the backend screens and to activate/deactivate the module. Content > [your module name]: Use this option to add, update and delete data for your module, and to publish/unpublish rows of data.

2012 Falafel Software

Working with Modules

449

The Drag widgets list will include an icon that represents your module data. Drag the widget to the page to present the new data.

2012 Falafel Software

450

Sitefinity 5

Add Module Content


1. From the Content menu select your new content item. This example shows a new "Quotations" menu item for module of the same name.

Figure 361 --Selecting the Module

2. The first time you enter the screen you will see a "Create a [my module type] item". Click the link to create a new item.

Figure 362 --Creating a Module Item

2012 Falafel Software

Working with Modules

451

3. Enter the fields you defined when creating the module. When complete, click the Publish button.

Figure 363 --Entering the Content Fields

4. After adding several entries, you can see the quotations column and stock columns "Author" and "Publication Date" that come along with all content.

Figure 364 --Table of Module Data

2012 Falafel Software

452

Sitefinity 5

Customizing the Backend Grid


The stock backend grid shows only the identifying field and built-in content fields "Publication Date" and "Author". You can customize the backend grid to show the columns from your module. 1. To customize this list to include the quotation source and picture, select the menu Administration > Module Builder. 2. Select the link for your module. 3. Select the Backend screens tweaks link. 4. Click the Add / Remove columns in the table button.

Figure 365 --Editing the Table

2012 Falafel Software

Working with Modules

453

5. The "Author" column can be removed, so click the "x" icon to delete it.

Figure 366 --Rem oving the Author Colum n

6. Drag the columns from your module to the right end of the grid and drop them there.

Figure 367 --Adding a Custom Field

2012 Falafel Software

454

Sitefinity 5

7. The table should now look something like the screenshot below. Click the Save Changes button.

Figure 368 --The Table Layout

8. From the menu select Content > [your module]. The grid now shows the other columns defined in your module.

Figure 369 --The Custom ized Backend Table

2012 Falafel Software

Working with Modules

455

Add the Module to a Page


1. Drag the widget for your new module onto the page.

Figure 370 --Adding the Quotations Widget

2. The module will be listed using the default configuration and layout. The example below shows all published quotations in a list and the layout for each item shows the picture, quote and published date.

Figure 371 --The Quotations Widget on the Page

2012 Falafel Software

456

Sitefinity 5

3. The layout should be changed to show the quote source author instead of the published date. Click the Quotations widget Edit button.

Figure 372 --Editing the Widget

4. Click the List Settings link. 5. In the List template drop down, select "List of quotations"

Figure 373 --Selecting the Tem plate

6. Click the Edit selected template button. 7. In the Edit template screen, locate the line that starts '<sf:FieldListView ID="PublicationDate"' and remove the entire line.

Figure 374 --Editing the Tem plate

8. Leave the cursor just after the </h2> tag. 9. In the list to the right of the template, expand the Insert > Other data heading.

2012 Falafel Software

Working with Modules

457

10.Click the "Source" item. The How to insert... dialog should display.

Figure 375 --Inserting the Source Field

11.Click the Insert button. 12.The template should now look something like the screenshot below, with the TextField for "Source" inserted right after the </h2> tag holding the quotation.

The Edited Tem plate

13.Click the Save changes button of the Edit template page.. 14.Click the Save button on the Edit dialog. 15.The page will update in a moment and display the source author under the quotation.

Figure 376 --The Tem plated Widget

2012 Falafel Software

458

Sitefinity 5

Working with the Module in Code


You can build custom code against your new module starting from automatically generated examples. Access the code sample snippets from the Code reference for [my module] link found in the Module Builder.

Figure 377 --Show ing Code Sam ples

The list on the left has starting points for all the critical areas you're likely to need: create, delete, find by id, get a collection, filter, check in/out and integration with ASP.NET. Select from the list to display the custom code on the right.

Figure 378 --Show ing a Code Snippet

2012 Falafel Software

Working with Modules

459

The examples include a short explanation of the steps in the code and a list of the namespaces to include that make the code work. Here's the code that creates a quotation:
// Creates a new quotation item public void CreateQuotation() { DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(); Type quotationType = TypeResolutionService.ResolveType( "Telerik.Sitefinity.DynamicTypes.Model.Quotations.Quotation"); DynamicContent quotationItem = dynamicModuleManager.CreateDataItem(quotationType); // This is how values for the properties are set quotationItem.SetValue("Quotation", "Some Quotation"); quotationItem.SetValue("Owner", SecurityManager.GetCurrentUserId()); quotationItem.SetValue("PublicationDate", DateTime.Now); quotationItem.SetValue("Source", "Some Source"); LibrariesManager libraryManager = LibrariesManager.GetManager(); var image = libraryManager.GetImages().FirstOrDefault(); if(image != null) { quotationItem.AddImage("Picture", image.Id); } // You need to call SaveChanges() in order for the items to b e actually persisted to data store dynamicModuleManager.SaveChanges(); }

2012 Falafel Software

460

Sitefinity 5

We can tweak this code a bit to bring in a particular image from the library and to publish the module data so that its visible on a page. This example filters the images to look for a "live" version of an image titled "winston". At the end of the method, the item is saved.
public void CreateQuotation() { DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(); Type quotationType = TypeResolutionService.ResolveType( "Telerik.Sitefinity.DynamicTypes.Model.Quotations.Quotation"); DynamicContent quotationItem = dynamicModuleManager.CreateDataItem(quotationType); // This is how values for the properties are set quotationItem.SetValue("Quotation", "Some Quotation"); quotationItem.SetValue("Owner", SecurityManager.GetCurrentUserId()); quotationItem.SetValue("PublicationDate", DateTime.Now); quotationItem.SetValue("Source", "Some Source"); LibrariesManager libraryManager = LibrariesManager.GetManager(); var image1 = libraryManager.GetImages() .Where(i => i.Title.Equals("winston")) .Where(i => i.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live) .FirstOrDefault(); if (image1 != null) { quotationItem.AddImage("Picture", image1.Id); } dynamicModuleManager.Lifecycle.Publish(quotationItem); dynamicModuleManager.SaveChanges(); }

Using this code as a basis, you can publish a series of quotes for a single author. Winston Churchill authored more than his fair share of good quotes:
public void CreateQuotation() { string[] quotations = { "Ending a sentence with a preposition is something up with which I shall not put.", "An appeaser is one who feeds a crocodilehoping it will eat him last.", "If you are going to go through hell, keep going.", "History will be kind to me for I intend to write it.", "It has been said that democracy is the worst form of government except all the

2012 Falafel Software

Working with Modules

461

others that have been tried." }; DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(); Type quotationType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Quotations.Quotation"); LibrariesManager libraryManager = LibrariesManager.GetManager(); var image = libraryManager.GetImages() .Where(i => i.Title.Equals("winston")) .Where(i => i.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live) .FirstOrDefault(); foreach (string quote in quotations) { DynamicContent quotationItem = dynamicModuleManager.CreateDataItem(quotationType); quotationItem.SetValue("Quotation", quote); quotationItem.SetValue("Owner", SecurityManager.GetCurrentUserId()); quotationItem.SetValue("PublicationDate", DateTime.Now); quotationItem.SetValue("Source", "Winston Churchill"); if (image != null) { quotationItem.AddImage("Picture", image.Id); } dynamicModuleManager.SaveChanges(); } }

The quotations are added en-masse to the page.

Figure 379 --Program m atically Added Module Item s

2012 Falafel Software

462

Sitefinity 5

Summary
In this chapter you worked with modules to handle custom data. You learned how to create a custom module, add content to the module and add the module widget to a page to view the data. You also learned how to customize the backend table of module data.

2012 Falafel Software

21
Sitefinity Web Services

464

Sitefinity 5

21

Sitefinity Web Services


If you need your web site to "Talk to the outside world", then Sitefinity web services are the tool you're looking for. Web services can be used for any platform clients that can send and receive web traffic including iPhone, iPad, Winforms, Android and Windows Phone. Sitefinity web services closely parallel the Sitefinity user interface and cover the major areas of the product. Sitefinity web services are particularly suited to automating administrative tasks from remote locations.

2012 Falafel Software

Sitefinity Web Services

465

Objectives
This chapter demonstrates how to work with both Forms Authentication and, the new default, Claims Authentication. This chapter first shows how to get all the available web services and method calls. You will learn the basic steps in common with all web service method calls, how to log in and log out of Sitefinity from a web service and how to retrieve and parse information from a web service call.

2012 Falafel Software

466

Sitefinity 5

Getting Available Services and Methods


If you know the names of available services, you can query the service itself for the methods that it supports. To view the available methods for a service, the browser path is:
http://localhost:<port>/<project name>/sitefinity/Services/<service folder>/<service>.svc/help

So for example, the methods for dealing with Pages for the project "WebServicesDemo" at port 17968 can be viewed in the browser at this address:
http://localhost:17968/WebServicesDemo/sitefinity/Services/Pages/PagesService.svc/help

How do you find out the name of the web services? The best place to view the available services is right from the project in Visual Studio. 1) From the Sitefinity Project Manager, note the base URL for the project. This particular example is located on the local host, port 17968 where the project name is "WebServicesDemo". The website you use will likely have a different URL.

Figure 380 --The Project URL

2) Click the Edit in Visual Studio button for any project. 3) In the Visual Studio Solution Explorer, expand the Sitefinity/Services node. There are folders for each area that web services provides for.

Figure 381 --Webservices in Visual Studio Project

2012 Falafel Software

Sitefinity Web Services

467

4) Expand the Security folder. Inside are "svc" files representing services for MembershipSettings, Permissions, Roles and Users.

Figure 382 --Security Services

5) Add the path to the Pages service in the browser. Use the base url you noted from the Sitefinity Project Manager earlier and tack on "/sitefinity/Services/Pages/PagesService.svc/ help ".
http://localhost:17968/Quotations/sitefinity/Services/Pages/PagesService.svc/help

6) The browser will display a list of methods. Under each method, a table of text and links explains what each method can do and basic information on how that can be accomplished.

Figure 383 --Web Service Help

2012 Falafel Software

468

Sitefinity 5

7) Scroll down to the GetPagesAsTree method and take a moment to explore the table and the links. UriTemplate defines how the request url should be formatted. UriTemplate may have optional parameters surrounded in curly braces. The template tells us that the method to pass in the uri is "tree". Method is the HTTP method used to make the request. For example, a GET is used when the entire request is contained in the URL. A POST is used when additional data needs to be sent in the request stream. PUT is used to update a record with a particular ID. DELETE is used to remove a record with a particular ID. The method for the GetPagesAsTree is a POST. Request Format and Response Format can be either XML or JSON (JavaScript Object Notation). We will be working with JSON in upcoming examples. The GetPagesAsTree method can make a request in JSON format, while a second method GetPagesAsTreeInXml returns the equivalent XML document. Request Schema and Response Schema describe the data layout of the data being sent or received. Request Example and Response Example show sample JSON or XML data. 8) Click the GetPagesAsTree Response Example to display an unformatted JSON string.

Figure 384 --Unform atted JSON String

2012 Falafel Software

Sitefinity Web Services

469

Using a formatter, the JSON looks like the snippet below.


{ "Context":[ { "Key":"String content", "Value":"String content" } ], "IsGeneric":true, "Items":[ { "AdditionalUrlsRedirectToDefaultOne":true, "AllowMultipleUrls":true, "AllowParameterValidation":true, "AvailableLanguages":[ "String content" ], "FullUrl":"String content", "HasChildren":true, ...

2012 Falafel Software

470

Sitefinity 5

Anatomy of a Web Service Call


Whatever the platform, you can perform these basic steps to make a web service call and get the results: 1) Make a web request, passing the URL of the service method you want to call. Set the request method (e.g. "Post", "Get", etc.). Add the claims token to the request header. Optionally set the request content type. Add any POST or PUT data as a stream of bytes to the request. 2) Get the response. Read the response stream and consume the results.

2012 Falafel Software

Sitefinity Web Services

471

Using Claims Authentication


The following is a minimal representation of working with Claims Authentication. There is clearly more to do in a production environment to check inputs, keep track of statuses and react to exceptions. The example will demonstrate logging in and getting a token, calling the GetPages REST api, passing the token and logging out.

Logging in
Logging in using Claims Authentication is a two stage process: finding out where the security token service is and then actually authenticating through the service.

Finding the Security Token Service


The first step is to make a simple GET request to the Authenticate service. The request url is the base url of your application, e.g. "http://localhost:12345/MySite" followed by "/ Sitefinity/Authenticate". The request will return a response status "200 - OK" if the issuer or Security Token Service (STS) is on the same machine. If the status is "301 - Moved", then we're dealing with an external STS or a Single Sign On. This example only implements local authorization.
public void Login() { // initial request to determine if security token service is on the same machine HttpWebRequest initialRequest = (HttpWebRequest)WebRequest.Create(_baseUrl + "/Sitefinity/Authenticate"); initialRequest.Method = "get"; using (HttpWebResponse initialResponse = initialRequest.GetResponse() as HttpWebResponse) { // "OK" indicates the security token service is on the same machine // "302", i.e. "Moved" indicates that the site is using an external // security token service or a single sign on. In this case you would have get the // token from the location parameter in the response headers. if (initialResponse.StatusCode == HttpStatusCode.OK) { LocalServiceAuth(); } else if (initialResponse.StatusCode == HttpStatusCode.Moved) { // not implemented in this example } } }

2012 Falafel Software

472

Sitefinity 5

Authenticating With Security Token Service


Send out a second, POST request that includes "wrap_name" and "wrap_password" key/ value pairs passed in the request stream. If the user name or password is incorrect, the response status code will be "401 - Unauthorized". If the status code is "OK", parse the response and extract the token from the wrap_access_token key. You can use the HttpUtility class (from the System.Web assembly and namespace) to convert the response text into a NameValueCollection for easier handling.
private void LocalServiceAuth() { // make a new request, passing the user name and password in the request stream HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_baseUrl + "/Sitefinity/Authenticate"); request.Method = "post"; request.ContentType = "application/x-www-form-urlencoded"; byte[] data = Encoding.UTF8.GetBytes("wrap_name=" + _name + "&wrap_password=" + _password); request.ContentLength = data.Length; using (var writer = request.GetRequestStream()) { writer.Write(data, 0, data.Length); } using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // "OK" indicates we can retrieve the token. // You can also check for a "401", i.e. "Unauthorized" error that is // pass if the user name or password is incorrect. if (response.StatusCode == HttpStatusCode.OK) { using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { // The token will b e held in an element "wrap_access_token", extract this token and // store it for later calls var queryString = reader.ReadToEnd(); NameValueCollection col = HttpUtility.ParseQueryString(queryString); _token = col.GetValues("wrap_access_token")[0]; } } } }

2012 Falafel Software

Sitefinity Web Services

473

Logging Out
Logout is also uses a GET request, but where the Url ends with "/Sitefinity/SignOut". The token you saved during the login is added back into the request headers. The key to the headers collection is the constant HttpRequestHeader.Authorization and the value is 'WRAP access_token="mytokencharacters"'. The token is surrounded by escaped quotes. You can verify that the response status is "OK". In the example below, we're raising a custom exception if the status is other than "OK".
public void Logout() { if (!_token.Equals(String.Empty)) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_baseUrl + "/Sitefinity/SignOut"); request.Headers.Add(HttpRequestHeader.Authorization, "WRAP access_token=\"" + _token + "\""); request.Method = "get"; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode != HttpStatusCode.OK) { throw new ClaimsException("Logout failed."); } } } }

Listing Pages
The REST API calls follow a similar pattern to the Logout. A request is created to the service URL and the token is popped back into the header. If the response comes back with an "OK" status, you can use the JSON in the response stream to re-hydrate a plain old .NET object.
public PageData GetPages() { if (!_token.Equals(String.Empty)) { // setup the request to the pages service, defaults to the GetPages method HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_baseUrl + "/Sitefinity/Services/Pages/PagesService.svc"); request.Headers.Add(HttpRequestHeader.Authorization, "WRAP access_token=\"" + _token + "\""); request.Method = "get"; request.CookieContainer = new CookieContainer(); using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // everything's copacetic, keep going if (response.StatusCode == HttpStatusCode.OK) { using (StreamReader reader =

2012 Falafel Software

474

Sitefinity 5

new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { // get the response stream using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(reader.ReadToEnd()))) { // rehydrate the JSON into a matching plain old ob ject DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PageData)); return (PageData)serializer.ReadObject(stream); } } } } } return null; }

The C# object mirrors the key properties of the JSON object. This object need only include the properties of interest from the JSON object.
public class PageData { public PageDataItem[] Items { get; set; } } public class PageDataItem { public PageTitle Title { get; set; } public string Owner { get; set; } } public class PageTitle { public string Value { get; set; } }

2012 Falafel Software

Sitefinity Web Services

475

Converting JSON to Objects


The response returns a serialized, JSON string, form. You can't directly iterate the string, bind to the data to a control or do much else that's useful with it. To use JSON data, you need to "deserialize", that is, convert the JSON string representation of a page into an object representation of a page. The screenshot below shows an example of the returned JSON displayed in Notepad.

Figure 385 --Returned JSON

JSON is returned unformatted from the web service and can be difficult to read. You can use a JSON formatter to make the JSON intelligible (Google "JSON formatter", there are many JSON formatters out there, such as http://jsonformatter.curiousconcept.com/). From the formatter we get something that looks like the fragment below.
{ "Context":null, "IsGeneric":false, "Items":[ { "AdditionalUrlsRedirectToDefaultOne":true, "AllowMultipleUrls":false, "AvailableLanguages":[ ], "FullUrl":"\/WebServicesDemo\/project-status", "HasChildren":false, "Id":"65b618f9-eb68-4795-b60a-58fcd33d13bd", ...

2012 Falafel Software

476

Sitefinity 5

You need a .NET object whose properties map to the properties of the JSON . Fortunately, you don't need to map all the properties, just the properties you want to use. The full JSON listing for a single page object is several full screens long. If we only want the Title and the Owner of the page, then we're only looking at this part shown in a condensed view of JSON below. In JSON, the curly braces denote an object and square brackets enclose arrays. Each property is a name/value pair separated by a colon.
{ "Items":[ { "Title":{ "Value":"Project Status" }, "Owner":"Mr Telerik", }, }, ], }

2012 Falafel Software

Sitefinity Web Services

477

The .NET objects below map to the JSON string, where "PageData" represents the outermost object, "Items" is an array where each item has a "Title" and an "Owner". "Title" itself is another object that has a "Value" property.
public class PageData { public PageDataItem[] Items { get; set; } } public class PageDataItem { public PageTitle Title { get; set; } public string Owner { get; set; } } public class PageTitle { public string Value { get; set; } }

How do you convert JSON into object form? DataContractJsonSerializer from the System.Runtime.Serialization namespace has a ReadObject() method that munches JSON and spits out an object. The example below takes a string of JSON data, converts the JSON string to an array of bytes and feeds the array of bytes to a MemoryStream. A new DataContractJsonSerializer is created, passing the target object type to the constructor. The DataContractJsonSerializer ReadObject() method accepts the memory stream of JSON data and returns the object.
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PageData)); PageData pageData = (PageData)serializer.ReadObject(ms); }

2012 Falafel Software

478

Sitefinity 5

Exception Handling
You will want to wrap your GetResponse() calls in try..catch blocks to trap exceptions in the code and in the response headers. The example below shows the types of information you can rip out of the response headers. WebException includes an HTTP Response where you can interrogate the "X-Authentication-Error" value. The "ClaimsException" being thrown is a custom exception descending from ApplicationException.
try { using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { ... } } catch (WebException ex) { string authError = ex.Response.Headers["X-Authentication-Error"]; if (authError != null) { if (authError.Equals("TokenExpired")) throw new ClaimsException("Your security token has expired"); else if (authError.Equals("UserAlreadyLoggedIn")) throw new ClaimsException("Already logged in."); else if (authError.Equals("UserLoggedFromDifferentComputer")) throw new ClaimsException("Account in use from another computer or browser."); else throw new ClaimsException(ex.Message, ex.InnerException); } else { throw new ClaimsException(ex.Message, ex.InnerException); } }

2012 Falafel Software

Sitefinity Web Services

479

Walk-Through
This walk-through will demonstrate using Claims Authorization to login, call a Sitefinity REST API and log out.

Figure 386 --REST APIs and Claim s

Building the Pages Object 1. First, create a Windows form application in Visual Studio. 2. Add a PageObject.cs class to your project and replace with the code below.
public class PageData { public PageDataItem[] Items { get; set; } } public class PageDataItem { public PageTitle Title { get; set; } public string Owner { get; set; } } public class PageTitle { public string Value { get; set; } }

2012 Falafel Software

480

Sitefinity 5

Building the Claims Object Private Properties, Constants and Constructor 1. Add a new class "Claims.cs" to the project. 2. You will need the following references in the "using" clause.
using System; using System.Collections.Specialized; using System.IO; using System.Net; using System.Runtime.Serialization.Json; using System.Text; using System.Web;

3. Add private members to the Claims object that will store the base url, user name, password and returned claims token.
private string _name; private string _password; private string _baseUrl; private string _token = String.Empty;

4. Add constants to represent the service urls we want to reach:


private const string AuthenticateUrl = "/Sitefinity/Authenticate"; private const string SignOutUrl = "/Sitefinity/SignOut"; private const string GetPagesUrl = "/Sitefinity/Services/Pages/PagesService.svc";

5. Add a constructor that takes the user name, password and base url and stores these to the private members.
public Claims(string name, string password, string baseUrl) { _name = name; _password = password; _baseUrl = baseUrl; }

Helper Methods Add a GetRequest() method that will create and initialize an HttpWebRequest with the claims token and the HTTP method.
private HttpWebRequest GetRequest(string url, string method) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_baseUrl + url); if (!_token.Equals(String.Empty)) { request.Headers.Add(HttpRequestHeader.Authorization, "WRAP access_token=\"" + _token + "\""); } request.Method = method; return request; }

2012 Falafel Software

Sitefinity Web Services

481

Login Add a Login() method to the Claims object. This method will call the "Authenticate" url the initial time to determine if this is a local security token service.
public void Login() { // initial request to determine if security token service is on the same machine HttpWebRequest request = GetRequest(AuthenticateUrl, "get"); using (HttpWebResponse initialResponse = request.GetResponse() as HttpWebResponse) { // "OK" indicates the security token service is on the same machine // "302", i.e. "Moved" indicates that the site is using an external // security token service or a single sign on. In this case you would have get the // token from the location parameter in the response headers. if (initialResponse.StatusCode == HttpStatusCode.OK) { LocalServiceAuth(); } else if (initialResponse.StatusCode == HttpStatusCode.Moved) { // not implemented in this example } } }

Logout Add a Logout() method to the Claims class. It should simply make a request to the "SignOut" url.
public void Logout() { if (!_token.Equals(String.Empty)) { GetRequest(SignOutUrl, "get").GetResponse(); } }

2012 Falafel Software

482

Sitefinity 5

List Pages Add a GetPages() method to Claims.cs that returns a PageData object. It should make a call to the "GetPages" url and extract the PageData if the response status is "OK".
public PageData GetPages() { if (!_token.Equals(String.Empty)) { // setup the request to the pages service, defaults to the GetPages method HttpWebRequest request = GetRequest(GetPagesUrl, "get"); request.CookieContainer = new CookieContainer(); using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // everything's copacetic, keep going if (response.StatusCode == HttpStatusCode.OK) { using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { // get the response stream using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(reader.ReadToEnd()))) { // re-hydrate the JSON into a matching plain old ob ject DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PageData)); return (PageData)serializer.ReadObject(stream); } } } } } return null; }

2012 Falafel Software

Sitefinity Web Services

483

Designing the Windows Form Add the following components and properties to the design of the windows form. 1. Add three buttons named "btnLogin", "btnListPages" and "btnLogout". Set their Text properties to "Login", "List Pages" and "Logout", respectively. 2. Add a Label and set the Text property to "Base Url of Sitefinity Application". Add a TextBox below the Label and name it "tbBaseUrl". 3. Add another Label and set the Text property to "User Name". Add a TextBox below the Label and name it "tbUserName". 4. Add a Label and set the Text property to "Password". Add a TextBox below the Label and name it "tbPassword". 5. Add a TextBox to the bottom of the page and resize it to take up the remaining room on the form. Name the TextBox "tbOutput" and set it's ScrollBars property to "Both" and the MultiLine property to "True". 6. The finished design should look something like the screenshot below:

Figure 387 --Window s Form Design

2012 Falafel Software

484

Sitefinity 5

Coding the Windows Form 1. Add a private member to represent the Claims object.
private Claims _claims;

2. In the constructor, create the Claims instance.


private void Form1_Load(object sender, EventArgs e) { _claims = new Claims(tbUserName.Text, tbPassword.Text, tbBaseUrl.Text); }

3. Add a helper method to print text to the "output" text box.


private void Log(string message) { tbOutput.Text += Environment.NewLine + message; }

4. Add a Click event to the "Login" button and code the event handler:
private void btnLogin_Click(object sender, EventArgs e) { _claims.Login(); Log("Logged in"); }

5. Add a Click event to the "Logout" button and code the event handler:
private void btnLogout_Click(object sender, EventArgs e) { _claims.Logout(); Log("Logged out"); }

6. Add a Click event to the "List Pages" button and code the event handler. The PageData object returned from GetPages() will contain an Items array. Iterate the array and output the Title value for each page.
private void btnListPages_Click(object sender, EventArgs e) { var pageData = _claims.GetPages(); if (pageData != null) { foreach (var item in pageData.Items) { Log(item.Title.Value); } } }

7. Add a FormClosed event to the form and code the event handler to automatically log you out of Sitefinity when closing the form.

2012 Falafel Software

Sitefinity Web Services

485

private void Form1_FormClosed(object sender, FormClosedEventArgs e) { _claims.Logout(); }

Running the Application Run the application and test out logging in, listing pages in the site and logging out. Also try logging into the Sitefinity backend, run the Windows application and logout, then try navigating to another page within the backend. Sitefinity should navigate out to the login page.

2012 Falafel Software

486

Sitefinity 5

Using Forms Authentication


Forms Authentication has been left in the product for backwards compatibility. Likewise, this section has been left in the courseware, but Claims Authentication is the better choice for all your projects going forward.

Logging in Via Web Service


We have to login to Sitefinity before we can do anything, so the AuthenticateUser method is a good place to start. 1) Create a new Winforms application in Visual Studio. Open the default form for editing. 2) Add the members below to your form class. Modify the sitefinityHost string so that it points to a running Sitefinity site. Remember that you can get this string from the Sitefinity Project Manager URL column.
private const string sitefinityHost = "http://localhost:17968/WebServicesDemo"; private const string usersServiceUrl = "/Sitefinity/Services/Security/Users.svc/"; private static CookieCollection cookies;

3) Add a constant that will hold the JSON used to make the login request.
const string credentialsFormat = @" {{ ""MembershipProvider"":""{0}"", ""Password"":""{1}"", ""Persistent"":{2}, ""UserName"":""{3}"" }}";

4) Create a new Login() method. 5) In the Login() method, add code to configure the web request. First, the segments of the URL are assembled into a single string "url". Then an HttpWebRequest object is created and passed the constructed URL. The method here is "POST" because we need to add credential information later.
// configure and create the web request string url = String.Concat(sitefinityHost, usersServiceUrl, "Authenticate"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/json";

2012 Falafel Software

Sitefinity Web Services

487

6) Next, add code to handle cookies. If we have saved cookies that contain login information from a previous request, add them back into the request. The key part is to create the CookieContainer so that the response will have that available to store cookies in.
// if saved cookies are availab le, add them to the request request.CookieContainer = new CookieContainer(); if (cookies != null) { foreach (Cookie cookie in cookies) if (!cookie.Expired) request.CookieContainer.Add(cookie); }

7) Create credential information in JSON format and write the JSON string to the request stream. The "credentialsFormat" string provides a convenient way to populate the JSON string using the String.Format() method. The MembershipProvider is left blank to use the default provider. User name and password for the example Sitefinity site happens to be "admin" and "password". The Persistent parameter is set true to indicate that a cookie should be saved with the current authorization information.
// create JSON credential data and write to the request stream. string json = String.Format(credentialsFormat, String.Empty, "password", "true", "admin"); byte[] credentials = Encoding.UTF8.GetBytes(json); request.ContentLength = credentials.Length; using (var writer = request.GetRequestStream()) { writer.Write(credentials, 0, credentials.Length); }

2012 Falafel Software

488

Sitefinity 5

8) Get the response back and do something about it. Call the Request's GetResponse() method. This needs to be cast to an HttpWebResponse so that it knows about things like cookies. Speaking of cookies, you need to save off the response cookies into a private variable, so that you can reuse them for another call.
// get the response using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { cookies = response.Cookies; using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { string result = reader.ReadToEnd(); Debug.WriteLine(result); } }

9) Add a button to the form, create a Click event handler and add the Login() method to the button click event handler.
private void button1_Click(object sender, EventArgs e) { Login(); }

2012 Falafel Software

Sitefinity Web Services

489

10)From the Sitefinity Project Manager, select the project that you want to reach with web services and click the Go to Administration button. Verify that the URL in Sitefinity and the "sitefinityHost" string you defined earlier are matching exactly. 11)Run the application, click the button and observe the result in the Output window. It should return a "0". Other responses are failures of various types. You don't need to add the following code, but it is a reference to the codes returned by the login response.
public enum LoginCodes { Success = 0, UserLimitReached = 1, UserNotFound = 2, UserLoggedFromDifferentIp = 3, SessionExpired = 4, UserLoggedOff = 5, UserLoggedFromDifferentComputer = 6, Unknown = 7, NeedAdminRights = 8, UserAlreadyLoggedIn = 9, UserRevoked = 10, NotSet = 11 }

2012 Falafel Software

490

Sitefinity 5

Logging Out
Logging out is a variation on the same steps as Logging In. The changes to the Logout method are: A slightly different URL that ends with "Logout" instead of "Authenticate". The http "GET" method is used instead of "POST". No extra data is streamed into the request. A different result code, "true", is returned on success.

2012 Falafel Software

Sitefinity Web Services

491

In fact, they're similar enough that even for this simple code, a little refactoring is in order. Before we code a Logout() method, lets move the common features of Login() to another method. 1) Create a new method called InvokeRequest() using the code below. The information that differs are passed as parameters, i.e. the w ebMethod ("Authenticate" vs. "Logout"), httpMethod ("POST", "GET"), and data (an arbitrary array of bytes for credentials and unused by Logout()). This method returns the JSON response string.
private static string InvokeRequest(string webMethod, string httpMethod, byte[] data) { // configure and create the web request string url = String.Concat(sitefinityHost, usersServiceUrl, webMethod); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = httpMethod; request.ContentType = "application/json"; // if saved cookies are availab le, add them to the request request.CookieContainer = new CookieContainer(); if (cookies != null) { foreach (Cookie cookie in cookies) if (!cookie.Expired) request.CookieContainer.Add(cookie); } // write to the request stream. if (data != null) { request.ContentLength = data.Length; using (var writer = request.GetRequestStream()) { writer.Write(data, 0, data.Length); } } // get the response using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { cookies = response.Cookies; using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { return reader.ReadToEnd(); } } }

2012 Falafel Software

492

Sitefinity 5

2) Change the Login() method to use the code below. The Login() method now prepares the credentials, calls the new InvokeRequest() method and writes out the result.
private static void Login() { string json = String.Format(credentialsFormat, String.Empty, "password", "true", "admin"); byte[] credentials = Encoding.UTF8.GetBytes(json); string result = InvokeRequest(usersServiceUrl, "Authenticate", "POST", credentials); Debug.WriteLine(result); }

3) You will have to manually login to the site and then logout. Then retest the application. 4) Create a Logout() method using the code below. Add a second button to the form and call Logout() from the Click event handler of the button.
private static void Logout() { string result = InvokeRequest(usersServiceUrl, "Logout", "GET", null); Debug.WriteLine(result); }

5) Test the application. The result should return "true". You should be able to login and logout multiple times. When you logout from the application, you should be able to login directly to the Admin without a warning that another user is logged in.

Listing Pages
Returning a list of pages in Sitefinity is a representative example that you can adapt to other methods in the Sitefinity web service API. The short story is that using the code below with InvokeRequest() gets you a JSON string that represents an array of page objects.
private void ListPages() { const string pagesServiceUrl = "/Sitefinity/Services/Pages/PagesService.svc"; string result = InvokeRequest(pagesServiceUrl, "", "GET", null); Debug.WriteLine(result); }

2012 Falafel Software

Sitefinity Web Services

493

Walk-through
1) In the Solution Explorer, add a reference to the System.Runtime.Serialization assembly. This assembly can be found on the .NET tab of the Add Reference dialog. 2) Add a new class file to the project and name it PageObject.cs. Add the code below to the class file. Note that "PageData" is not the Sitefinity version of "PageData". This project has no Sitefinity references, and these are our own custom objects.
public class PageData { public PageDataItem[] Items { get; set; } } public class PageDataItem { public PageTitle Title { get; set; } public string Owner { get; set; } } public class PageTitle { public string Value { get; set; } }

3) In the code for the form, add a reference to the "using" (C#) or "Imports" (VB) section of the code for the System.Runtime.Serialization.Json namespace. 4) Add a ListBox to the form and name it "PagesListBox". Set the Text property to "List Pages". 5) Add a button to the form and name it "ListPagesButton". Double-click the button in the designer to create a Click event handler. 6) In the Click event handler for the button, add the code below. The "GET" call to PagesService returns a list of pages. The JSON string result is placed in a MemoryStream. The DataContractJsonSerializer reads the stream and creates a PageData object. The PageData Items array is used to populate the ListBox.
private void ListPagesButtonClick(object sender, EventArgs e) { const string pagesServiceUrl = "/Sitefinity/Services/Pages/PagesService.svc"; string result = InvokeRequest(pagesServiceUrl, "", "GET", null); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(result))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PageData)); PageData pageData = (PageData)serializer.ReadObject(ms); foreach (PageDataItem item in pageData.Items) { PagesListBox.Items.Add(item.Title.Value); }; }

2012 Falafel Software

494

Sitefinity 5

7) Run the application and Login. Click the "List Pages" button. The pages in the site should be displayed in the list box.

Figure 388 --Listing Pages

2012 Falafel Software

Sitefinity Web Services

495

What Next?
The code for this example is as simple as possible to demonstrate how the web services work without burying you in code. Production level communication with the web service will require additional infrastructure for robustness, and maintainability. You can build your own framework around the web service API to handle common tasks such as making web requests, handling cookies, deserializing responses, handling return codes from failed logins, etc. You can also get ideas from the Sitefinity Starter Kits that include code to wrap JSON calls and help with common tasks such as deserializing, logging in or listing pages.

2012 Falafel Software

496

Sitefinity 5

Summary
This chapter demonstrated how to work with both Forms Authentication and, the new default, Claims Authentication. This chapter first showed how to get all the available web services and method calls. You learned the basic steps in common with all web service method calls, how to log in and log out of Sitefinity from a web service and how to retrieve and parse information from a web service call.

2012 Falafel Software

22
Content Classification - Taxonomy

498

Sitefinity 5

22

Content Classification - Taxonomy


Sitefinity uses Categories and Tags to classify your content so that items can be found easily. Categories are a hierarchical arrangement suited to tiered information, e.g. (CEO > President > Vice President...), geographical areas (Europe > Eastern Europe > Bulgaria...) or biologic classification (Family > Genus > Species). Tags are a "flat" organization where each tag has no formal relationship to other tags. The word "Taxonomy" comes from ancient Greek root words meaning essentially "arrangement method". Telerik has chosen this word to describe a flexible way of classifying content that's not locked down to just hard-coded Categories or Tags. While Categories and Tags will handle most of your requirements, but you can also build your own custom classification, i.e. an organization that is neither a Category or Tag.

2012 Falafel Software

Content Classification - Taxonomy

499

Objectives
This chapter introduces the basic terminology for Taxonomies and shows how to traverse hierarchies of taxonomies and taxa. You'll learn about how to get statistics for a taxon, retrieve items by a category or tag and how to programmatically add categories and tags.

2012 Falafel Software

500

Sitefinity 5

Terminology
Taxonomy is the highest level "container" for classification information. "Categories" and "Tags" for example are the two predefined taxonomies in the system. A Taxonomy is represented in the Sitefinity system by the ITaxonomy interface and the Taxonomy abstract implementation class, with properties that include TaxonName and Taxa (an enumerable of individual categories, tags or custom taxa). Taxon is an individual category, tag or some custom item. When a user adds a category to a news item, they are adding Taxon. A Taxon is represented by the ITaxon interface and the Taxon abstract implementation class. Taxa is the plural of Taxon.

2012 Falafel Software

Content Classification - Taxonomy

501

Getting Started
The first step to working with taxonomies is to get a TaxonomyManager instance by calling the GetManager() method. With a TaxonomyManager, you can perform CRUD (Create, Read, Update, Delete) operations on taxonomies and individual taxon using methods: GetTaxonomy() GetTaxon() GetTaxa() CreateTaxon() CreateTaxonomy() Delete(<taxon, taxonomy>)

2012 Falafel Software

502

Sitefinity 5

Listing Taxonomies
You can retrieve either hierarchical or flat taxonomies. The code below retrieves all flat taxonomies and displays the Title in a list box. The list box displays a single item "Tags". You could also bind the DataTextField to the TaxonName property to display the singular "Tag" instead.
TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); IQueryable<FlatTaxonomy> taxonomies = taxonomyManager.GetTaxonomies<FlatTaxonomy>(); TaxonomyListBox.DataValueField = "Id"; TaxonomyListBox.DataTextField = "Title"; TaxonomyListBox.DataSource = taxonomies; TaxonomyListBox.DataBind();

To get all the possible tags in your system, make the GetTaxonomies() call twice, first with FlatTaxonomy as the type, then with HierarchicalTaxonomy . Use the LINQ Union () method to join the two lists together. The example below retrieves all taxonomies in the system that are built in, using the TaxonomyManager static IsTaxonomyBuiltIn() method.
TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); var flat = taxonomyManager .GetTaxonomies<FlatTaxonomy>() .ToList() .Where(t => TaxonomyManager.IsTaxonomyBuiltIn(t)) .Select(t => new { Id = t.Id, Title = t.Title.Value }); var hierarchical = taxonomyManager .GetTaxonomies<HierarchicalTaxonomy>() .ToList() .Where(t => TaxonomyManager.IsTaxonomyBuiltIn(t)) .Select(t => new { Id = t.Id, Title = t.Title.Value }); var taxonomies = flat.Union(hierarchical);

Figure 389 --Listing Taxonom ies

The result of the union is bound to a ListBox in the screenshot below and shows the flat "Tags" taxonomy and the hierarchical "Categories" taxonomy.

2012 Falafel Software

Content Classification - Taxonomy

503

Listing Taxa
This examples uses a sample set of data where the sample tags are "collecting" and "classic". Sample Category Taxa form the following hierarchy: "Europe" "Eastern Europe" "Bulgaria" Using the previous example in Listing Taxonomies, try adding a handler for the SelectedIndexChanged event to receive the SelectedValue. The SelectedValue is the Guid string for the Taxonomy. Create a new Guid object, passing the SelectedValue into the constructor. Call the TaxonomyManager GetTaxonomy() method and pass the Guid. Add a second ListBox to the form and bind it's DataSource to the Taxonomy Taxa property.
protected void TaxonomyListBox_SelectedIndexChanged(object sender, EventArgs e) { TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); Guid taxonomyId = new Guid(TaxonomyListBox.SelectedValue); ITaxonomy taxonomy = taxonomyManager.GetTaxonomy(taxonomyId); TaxaListBox.DataValueField = "Id"; TaxaListBox.DataTextField = "Title"; TaxaListBox.DataSource = taxonomy.Taxa; TaxaListBox.DataBind(); }

Selecting a Taxonomy from the first list box fires the SelectedIndexChanged event, the bound Taxonomy Id is retrieved and used to get the Taxonomy object. The Taxonomy Taxa collection is bound to the second list box.

Figure 390 --Listing Taxa

2012 Falafel Software

504

Sitefinity 5

Finding Frequently Used Categories and Tags


TaxonomyManager has a nice little goody hidden away called the GetStatistics() method that returns the MarkedItemsCount with the number of items marked with a given taxon. Other properties with possibilities are: The ApplicationName for the project that the statistic belongs to. DataItemType determines the kind of content the particular Taxon is being used in. StatisticType is the ContentLifecycleStatus used throughout Sitefinity to determine the state of the content item, i.e. Master, Temp or Live. The TaxonomyId and TaxonId Guids are both included so you can retrieve the corresponding objects. We can simply bind this information to a RadGrid in ASP.NET to see the bulk data. Assign the GetStatistics() result to the RadGrid DataSource.
TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); RadGrid1.DataSource = taxonomyManager.GetStatistics(); RadGrid1.DataBind();

The grid shows the raw statistic data.

Figure 391 --Statistics

If we filter and massage the data a bit with LINQ, we can get useful information to display. Statistics can be used to populate a RadTagCloud with "weighted" links, where taxons used in more places show in larger text.

Figure 392 --RadTagCloud w ith Statistics

2012 Falafel Software

Content Classification - Taxonomy

505

The code to accomplish this is listed below. Filter the results from GetStatistics() using Where() and making sure that the StatisticType is "Live". Project the items into a new anonymous type using Select(). You can save the TaxonId directly. To get the Title to display in each link, call the TaxonomyManager GetTaxon() method and pass the TaxonId. Get the Name property from the returned Taxon object. Finally, to get the comparative weight of each item, use the MarkedItemsCount.
private void ListStatistics() { TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); var statistics = taxonomyManager .GetStatistics() .Where(s => s.StatisticType == ContentLifecycleStatus.Live) .ToList() .Select(s => new { Id = s.TaxonId, Title = taxonomyManager.GetTaxon(s.TaxonId).Name, Weight = s.MarkedItemsCount, }) .OrderBy(s => s.Title).ToList(); StatisticsCloud.DataTextField = "Title"; StatisticsCloud.DataWeightField = "Weight"; StatisticsCloud.DataValueField = "Id"; StatisticsCloud.DataSource = statistics; StatisticsCloud.DataBind(); }

2012 Falafel Software

506

Sitefinity 5

Get Items by Category or Tag


What if I need to find all news items marked with the "Europe" Category or tagged "collecting". You can get at that functionality through the content database provider. The database provider can be reached through the manager of the particular content type you're working with, for example NewsManager.Provider. The provider has a GetItemsByTaxon() method that returns an IEnumerable of whatever content type you're working with. The steps are wrapped in the custom GetTaxonItems() method below that returns an IEnumerable<T> for a particular Taxon. The GetMappedManager() call returns the appropriate manager for the type you pass in. For example, if we pass in NewsItem, GetMappedManager() will return a NewsManager. The manager's Provider property is a DataProviderBase type, so you need to cast up to a ContentDataProviderBase that knows how to call GetItemsByTaxon() later in the method. You also need a TaxonomyPropertyDescriptor for the content type and taxon combination. Finally, you get to call GetItemsByTaxon(), passing in the information you've been hoarding up to this point. The returned IEnumerable is cast to IEnumerable<T> and returned from this method.
private static IEnumerable<T> GetTaxonItems<T>(ITaxon taxon) { // get the manager for the items, e.g. NewsManager var manager = ManagerBase.GetMappedManager(typeof(T)); // get the b ase content datab ase provider ContentDataProviderBase contentProvider = manager.Provider as ContentDataProviderBase; // get a taxonomy property descriptor for this item type and taxon TaxonomyPropertyDescriptor prop = TaxonomyManager.GetPropertyDescriptor(typeof(T), taxon); int? totalCount = 0; // use the GetItemsByTaxon() method to return IEnumerab le of items. var items = contentProvider.GetItemsByTaxon(taxon.Id, prop.MetaField.IsSingleTaxon, prop.Name, typeof(T), string.Empty, // filter string.Empty, // order b y 0, // skip 100, // take ref totalCount); return items as IEnumerable<T>; }

2012 Falafel Software

Content Classification - Taxonomy

507

To call the method, set the type to be the content type you're looking for and pass in the taxon to search on as a parameter. The example below is looking for all news items that are marked with a particular taxon.
IEnumerable<NewsItem> items = GetTaxonItems<NewsItem>(taxon);

If you bind the items directly against a grid, you will see all the columns for the content item type, in whatever life cycle status they happen to be in. The example below bridges off the previous RadTagCloud example and displays the NewsItems for the selected cloud tag.

Figure 393 --Listing Item s for a Taxon

You can boil this data down a bit using lambda expressions to look only for Live items and only showing certain columns. The code below handles the RadTagCloud ItemClick event. The event args for the handler include the Item.Value property that contains the Guid for the Taxon. You can use the TaxonomyManager.GetTaxon() method to retrieve the Taxon corresponding to the item the user clicked on. Now that you have the Taxon, call the custom GetTaxonItems() method and pass the taxon as a parameter.

2012 Falafel Software

508

Sitefinity 5

Next, a lambda expression filters for only "Live" Status items. Only the "Title" and "Url" columns are selected.
protected void StatisticsCloud_ItemClick(object sender, RadTagCloudEventArgs e) { TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); ITaxon taxon = taxonomyManager.GetTaxon(new Guid(e.Item.Value)); IEnumerable<NewsItem> items = GetTaxonItems<NewsItem>(taxon); var news = items .Where(n => n.Status == ContentLifecycleStatus.Live) .Select(n => new { Title = n.Title.Value, Url = n.Urls.FirstOrDefault().Url }); RadGrid1.DataSource = news; RadGrid1.DataBind(); }

The data bound in the grid looks something like the screenshot below.

Figure 394 --New s Item Data

2012 Falafel Software

Content Classification - Taxonomy

509

Adding Categories and Tags


To create a new taxon, use the TaxonomyManager CreateTaxon() method. Specify the type of taxon you want to create, i.e. HierarchicalTaxon or FlatTaxon . For HierarchicalTaxon, you need to specify the Parent. In the example below the Category "Eastern Europe" is retrieved using the GetTaxa() method and assigned to the new taxon's Parent property. Also notice programmatic login as a user with permissions to create a taxon.
SecurityManager.AuthenticateUser(String.Empty, "admin", "password", false); TaxonomyManager taxonomyManager = TaxonomyManager.GetManager(); // get the parent taxon HierarchicalTaxon EasternEuropeTaxon = taxonomyManager.GetTaxa<HierarchicalTaxon>() .ToList() .Where(t => t.Title.Value.Equals("Eastern Europe")) .SingleOrDefault(); // b uild a new taxon and place it underneath the parent HierarchicalTaxon HungaryTaxon = taxonomyManager.CreateTaxon<HierarchicalTaxon>(); HungaryTaxon.Name = "Hungary"; HungaryTaxon.Title = "Hungary"; HungaryTaxon.UrlName = "hungary"; HungaryTaxon.Parent = EasternEuropeTaxon; HungaryTaxon.Taxonomy = EasternEuropeTaxon.Taxonomy; taxonomyManager.SaveChanges(); SecurityManager.Logout();

Gotcha!

Notice that you need to assign the Taxonomy property, i.e. Category, Tag or a custom Taxonomy. Not assigning the Taxonomy property leads to a difficult-todiagnose "Null reference object" exception.

2012 Falafel Software

510

Sitefinity 5

Summary
This chapter introduced the basic terminology for Taxonomies and showed how to traverse hierarchies of taxonomies and taxa. You learned about how to get statistics for a taxon, retrieve items by a category or tag and how to programmatically add categories and tags.

2012 Falafel Software

23
Dynamic Data

512

Sitefinity 5

23

Dynamic Data
Each type of content in Sitefinity has just about every property you need. Almost. For example, news items have SourceName and SourceSite properties to track where the news comes from originally. What if you needed a "SourceDate" property to denote the date the source material was obtained? Sitefinity User objects have properties for UserName, LastActivityDate and Email. What if your organization needs to track "HireDate", "HireReason" and "NextReviewDate"? Sitefinity allows you to create custom fields without having to register them in codebehind or referencing libraries.

2012 Falafel Software

Dynamic Data

513

Objectives
In this chapter you'll learn how to add a new custom field to a content item from the Sitefinity back end. Then you'll use the DynamicData facade to programmatically list types and fields. Finally, you'll learn how to read and write custom field values.

2012 Falafel Software

514

Sitefinity 5

Adding Custom Fields


You can create your own custom fields that "come along for the ride" when the user enters data. Custom fields are associated with a specific type of data, for example, "NewsItem", "SitefinityProfile", "Document" etc. Custom fields can be created directly in Sitefinity administration. 1) In the Sitefinity Administration menu, select Content > New s. 2) Before proceeding, make sure that at least one news item is already created. See the Using Sitefinity > Content > News section for steps on creating news items. 3) Click the Custom Fields for new s link.

Figure 395 --Selecting Custom Fields Link

Notes

This link will only show when you have at least one news item created.

2012 Falafel Software

Dynamic Data

515

4) For this walk-through, choose Date and Time from the Type drop down list. Enter "ReviewDate" as the Name for the custom field. Click the Continue button to accept the custom field settings. You can choose a predefined data type from the Type drop down list. You can prevent the field from displaying in the editor by selecting the This is a hidden field check box. The Interface widget... will list an appropriate editor for the type and Custom (to use a custom control to edit the field). The Advanced section allows you to map the custom field data type against database types.

Figure 396 --Adding a Field

2012 Falafel Software

516

Sitefinity 5

5) In the Settings, Label and text tab, enter the Label "Review Date" and Instructional text as "Enter the date when the news item should be reviewed". Click the Done button to close the dialog. You can also enter a default in the Predefined value space. Quite often you will want a particular field filled out every time a content item is created, so check the Make required box for ensure that the user can't save the item without making an entry. The Limitations tab allows you to set minimum and maximum values and an error message if the user entry falls outside the range. The Appearance tab determines where the field will be shown in the backend.

Figure 397 --Custom Field Settings

2012 Falafel Software

Dynamic Data

517

6) The your new "ReviewDate" field should display in the list of custom fields for news item. Notice that the list starts out with Tags and Category classification field types and that these are considered to be custom fields.

Figure 398 --New Custom Field

7) Create a News Item. Scroll to the bottom of the news item to see your new custom "Review Date" field label and instruction text.

Figure 399 --The Custom Field in the New s Item

2012 Falafel Software

518

Sitefinity 5

8) Click the entry box to see the popup calendar editor.

Figure 400 --Popup Calendar

2012 Falafel Software

Dynamic Data

519

Notes

The Type drop down list also includes Short text, Long text, Multiple choice, Yes / No, Currency, Number and Classification. You can add multiple fields to a content type. The screenshot below shows examples of Date-Time, Long text, Multiple choice and Currency.

Figure 401 --Multiple Custom Fields

2012 Falafel Software

520

Sitefinity 5

Using the DynamicData Facade


What custom fields have been created on your Sitefinity web site? You can find this out programmatically using the Fluent API DynamicData facade. The DynamicData facade has methods to work with: Types: The item types that have custom fields, such as NewsItem or BlogPost. Fields: The custom fields. Each field has a long list of information including the field name and type.

2012 Falafel Software

Dynamic Data

521

Programmatically Listing Types


Use the code below to get the list of types. This example binds the list of types to a RadComboBox, displays the "ClassName" and stores the "Id" column as the value.
// get types that can have custom fields and aren't dynamic var itemTypes = App.WorkWith() .DynamicData() .Types() .Get() .Where(d => !d.IsDynamic) .ToList(); ItemTypeCombo.DataSource = itemTypes; ItemTypeCombo.DataTextField = "ClassName"; ItemTypeCombo.DataValueField = "Id"; ItemTypeCombo.DataBind();

The screenshot shows the result. The entries correspond not to custom field types, but to the types of Sitefinity items that can have custom fields. The check for !IsDynamic filters out types like "sf_ec_prdct_software" already created by Sitefinity or "sf_askcarconduitaquestion" which was created as a by product of creating a form.

Figure 402 --Item Types

2012 Falafel Software

522

Sitefinity 5

To retrieve this type from an item selected in this combo box, first get the Value property that contains a Guid string. Feed the string into the constructor of a Guid object. Use the Guid as a parameter to the Type() method. Use the Get() method to return a MetaType that in turn has the ClrType. It's this ClrType that corresponds to a particular item class, e. g. NewsItem, Event, BlogPost, etc. If the user selects "NewsItem" as in the screenshot above, the ClrType will be equivalent to typeof(NewsItem).
protected void ItemTypeCombo_SelectedIndexChanged(object sender, Telerik.Web.UI.RadComboBoxSelectedIndexChangedEventArgs e) { Guid itemTypeId = new Guid(e.Value); Type itemType = App.WorkWith() .DynamicData() .Type(itemTypeId) .Get() .ClrType; }

2012 Falafel Software

Dynamic Data

523

Programmatically Listing Fields


How can you query for all the custom fields in the entire system or for just a single item type (e.g. news items)? To get at all fields, bridge off the DynamicData() facade and call the Fields() method. The Get() method retrieves an IQueryable of MetaField. MetaField is where all the good stuff is: the CLR type, the SQL type for the database, if the field is hidden or not, limitations such as minimum and maximum value, its Guid ID and so on.

List All Fields


The code example below retrieves the metadata for all fields and all item types in the system.
var fields = App.WorkWith() .DynamicData() .Fields() .Get() .ToList();

If you assign "fields" from the code example to a RadGrid, the result looks something like the screenshot below. RadGrid generates columns automatically based on the data source and can be a big help by displaying a quick snapshot of your query results. From this grid we know that we have Id, FieldName and ClrType columns that we can work with.

Figure 403 --Fields Displayed in a Grid

2012 Falafel Software

524

Sitefinity 5

List Fields for a Type


If you want only the fields for a particular item type (e.g. NewsItem), the query syntax shifts slightly to use the Type() method and then the Fields property. The code example below passes the NewsItem type to the Type() method and returns a DynamicTypeFacade. The Get() method returns a MetaType and finally, the MetaType has a Fields collection. The example uses a Select statement to return a smaller set of columns.
var fields = App.WorkWith() .DynamicData() .Type(typeof(NewsItem)) .Get() .Fields .Select(f => new { Id = f.Id, FieldName = f.FieldName, ClrType = f.ClrType, DbType = f.DBType });

The results in a grid look something like the screenshot below.

Figure 404 --Fields Displayed in Grid

2012 Falafel Software

Dynamic Data

525

Walk-through
You can put the Programmatically Listing Types example together with the List Fields for a Type example to dynamically show all fields for a selected type. 1) In an ASP.NET web form, add a RadScriptManager, a RadComboBox and a RadGrid. Set the RadComboBox AutoPostBack property to "true". The markup should look like the example below. Note: be sure to drag these controls onto the page so that they are registered properly.
<form id="form1" runat="server"> <div> <telerik:RadScriptManager ID="RadScriptManager1" runat="server"> </telerik:RadScriptManager> <telerik:RadComboBox ID="ItemTypeCombo" Runat="server" AutoPostBack="True" DropDownWidth="200px" MaxHeight="200px"> </telerik:RadComboBox> <br /> <telerik:RadGrid ID="FieldsGrid" runat="server" > </telerik:RadGrid> </div>

2) In the code-behind, add the code below to the Page_Load event handler.
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // get types that can have custom fields and aren't internal var itemTypes = App.WorkWith() .DynamicData() .Types() .Get() .Where(d => !d.IsDynamic) .ToList(); ItemTypeCombo.DataSource = itemTypes; ItemTypeCombo.DataTextField = "ClassName"; ItemTypeCombo.DataValueField = "Id"; ItemTypeCombo.DataBind(); } }

3) In the page designer, double-click the RadComboBox to create a SelectedIndexChanged event handler.

2012 Falafel Software

526

Sitefinity 5

4) Replace the code for the SelectedIndexChanged event handler with the code below. The event handler converts the selected combo box item value back into a Guid. Next, the CLR type for the selected type is retrieved. Finally, all the fields for the selected item type are retrieved, reshaped to only use a few columns and bound to the grid.
protected void ItemTypeCombo_SelectedIndexChanged(object sender, Telerik.Web.UI.RadComboBoxSelectedIndexChangedEventArgs e) { // convert the Type id string b ack into a Guid Guid itemTypeId = new Guid(e.Value); // get the item CLR type, e.g. typeof(NewsItem) Type itemType = App.WorkWith() .DynamicData() .Type(itemTypeId) .Get() .ClrType; // get all fields for the selected type var fields = App.WorkWith() .DynamicData() .Type(itemType) .Get() .Fields .Select(f => new { Id = f.Id, FieldName = f.FieldName, ClrType = f.ClrType, DbType = f.DBType }); // display fields in the grid FieldsGrid.DataSource = fields; FieldsGrid.DataBind(); }

2012 Falafel Software

Dynamic Data

527

5) Run the application. Select an item type to see the fields for the type in the grid. In the screenshot below, the SitefinityProfile type is selected and shows three custom fields that have been manually added for "HireDate", "HireReason" and "ReviewDate".

Figure 405 --Fields for a Selected Type

2012 Falafel Software

528

Sitefinity 5

Reading and Writing Custom Field Values


The most frequently asked question about custom fields is "how do I read or write my custom field value"? The magic is in the DataExtensions class from the Telerik.Sitefinity. Model namespace. As the name suggests, the class contains extension methods, so you need to have Telerik.Sitefinity.Model in your "uses" (C#) or "Imports" (VB) section of code. The three key methods of DataExtensions that can be used with Sitefinity content items are: GetValue(<field name>) SetValue(<field name>, <value>) DoesFieldExist(<value>) For example, if we retrieve a particular NewsItem, we can call the SetValue() method from that NewsItem. The example below retrieves a NewsItem where the Title property is "Southern France Car Rally", then calls the SetValue() extension method, passing the field name "ReviewDate" and a DateTime 30 days into the future.
App.WorkWith() .NewsItems() .Where(n => n.Title.Equals("Southern France Car Rally")) .ForEach(n => n.SetValue("ReviewDate", DateTime.UtcNow.AddDays(30))) .SaveChanges();

A variation on this example uses the GetValue() method to pick up only the news items that have a null "ReviewDate" and sets the field values.
App.WorkWith() .NewsItems() .Where(n => !n.GetValue<DateTime?>("ReviewDate").HasValue) .ForEach(n => n.SetValue("ReviewDate", DateTime.UtcNow.AddDays(30))) .SaveChanges();

2012 Falafel Software

Dynamic Data

529

Summary
In this chapter you learned how to add a new custom field to a content item from the Sitefinity back end. Then you used the DynamicData facade to programmatically list types and fields. Finally, you learned how to read and write custom field values.

2012 Falafel Software

24
About Falafel

About Falafel

531

24

About Falafel

Falafel Software Inc, an 8 time Microsoft Gold Certified Partner providing consulting, training, and software development for enterprise and small business customers. Falafel has designed and built numerous high profile websites for major customers around the globe and serves as Telerik's premier Sitefinity training partner. Falafel Software offers a wide range of services to Sitefinity customers including: Complete website architecture, design and implementation services Immediate assistance and troubleshooting through our Consulting Express offering Providing Sitefinity online and on-site training for individual organizations Hosting Telerik's monthly online training for new and advanced Sitefinity users

2012 Falafel Software

532

Sitefinity 5

Support and Services


Falafel Software has a strong presence in the Sitefinity space, including some very wellknown Sitefinity engineers in the Sitefinity community. Our offerings include training, consultation, development, and we have released a host of custom modules and integrations to the Sitefinity marketplace. We are the company of choice for migrating to Sitefinity 5.

Training
Onsite Training: A highly knowledgeable Falafel Software trainer will come to you and provide your team with an enlightening 3-5 day class. This is the best way to ramp up quickly. Online Training: For companies that have team members in multiple locations or in situations where onsite training is not feasible, online training is a great option. Training Summit: If your team only has a few individuals in need of training, this open-enrollment option is the most cost effective solution. Learn more about our current Sitefinity offerings at http://www.falafel.com/Telerik/sitefinity/training.aspx.

Consulting

2012 Falafel Software

About Falafel

533

Our software consulting services cover the complete project lifecycle, from inception to deployment, including project management, architecture, software development, quality assurance, training, help desk and support. We can provide individual consultants, or a complete team. We can also help with troubleshooting, proof of concept pilot projects, technical due diligence, and evaluation of technology. Our consultants are some of the most experienced in the industry, with hundreds of man-years of combined consulting experience in many areas of expertise and several vertical markets.

Consulting Express
Falafel Consulting Express is a ONE hour consulting service with a Falafel team member via phone, email, Skype or Instant messaging that enables any customer worldwide to have access to the team for a quick technical problem or a GotoMeeting session to help find a resolution to a customer's blocking problem.

Sitefinity Web Design


Falafel Software's design team are experts in setting up well designed, easy to navigate, and easy to maintain websites using Sitefinity CMS. Add to that our experience with UI design and integration, and you can be sure that we are the right solution for your design needs. Learn more at http://design.falafel.com/index. aspx.

2012 Falafel Software

534

Sitefinity 5

SiteBoard

SiteBoard is the Sitefinity administrators mobile companion. Available on all the major smart clients, it enables the busy administrator to perform critical tasks on the fly, such as logging out users, publishing or un-publishing pages, and moderating blog comments. SiteBoard allows you to manage multiple Sitefinity sites from one easy-to-use mobile interface. SiteBoard uses the native Sitefinity REST API and native mobile client user interfaces to deliver maximum usability, functionality and performance.

2012 Falafel Software

About Falafel

535

Sitefinity Marketplace Items By Falafel


Falafel has been a very active contributor of modules to the Sitefinity marketplace. Marketplace items by Falafel: Events Map Plug-in Orders Module Events Rotator Plug-in Falafel Contacts Module for Sitefinity News Rotator Plug-in FormBuilder Module Falafel Content Slider Widget Sitefinity Connector for Facebook Sitefinity Connector for Twitter Sitefinity CSS Editor Falafel Twitter Feed Widget Events Registration Module Falafel Newsletter Group Importer

Other Resources
Go to http://blog.falafel.com/ for in-depth blogs on CMS, Silverlight, Mobile, Telerik controls and technology issues of the day.

2012 Falafel Software

536

Sitefinity 5

Go to Falafel TV for video on variety of technical subjects including CMS, Silverlight, Mobile and Testing.

Mobilize your Sitefinity applications with help from the Falafel Mobile team. Go to http://www.falafel.com/ mobiledevelopment.aspx for more information.

Contact Us Today!
For more info on Falafel Software, visit http://www.falafel.com or call 1-888-GOTFALAFEL (1- 888-468-3252).

2012 Falafel Software

537

Index

537

Index
-..DynamicData() 523

-<<form> tag <head> tag 258 258

AppRoles 308 Approval before publishing 178 ASP.NET 244, 276, 278, 289 Aspect ratio 237 AssemblyInfo.cs 397, 407, 428 AuthenticateUser 466, 486 AuthenticateUser() 304 Authorization 473 Authors 168 AutoPostBack 409 Average pages per visit 191 Average time on site 191

-22 levels of approval before publishing 178

-BBackend screens tweaks 452 Backenduser 171 BackendUsers 168, 308 based on 210, 256 blog engine 133 blog post 133 Blog posts 133, 136 Blog Posts widget 142 Blogs 86, 132 Blogs Insert 202 Blogs Insert... 199 Bounce Rate 191 Browsable() 386 Build Action 384, 397, 399, 400, 402, 428

-Aaccess_token 473 Actions 78 Add languages... 353 Add roles or users 173 Additional info 94 AddUserToRole() 308 Administration 443, 452 Administrators 168, 308 Advanced 94 Album 324, 327, 425 All content and pages 178 All pages under particular page 215 All published news 94 All published videos 123 Allow administrators to skip the workflow 178 Allow Comments 87, 133 Alternative Publishing 133 An item in the feed contains 133 Analytics 188 App.WorkWith() 315, 319, 327, 331, 332 App.xaml 422 App_Data 249, 376 App_Master 256, 260 Appearance 154, 514 ApplicationName 504 Applied To 198, 204 Apply Behavior 239
2012 Falafel Software

-CCascading Style Sheet 221 Categories 498 Categories and Tags 87 Categories Change 87 Category 380 Category attribute 380 Change Owner 78 Change Template 218 ChangeParent() 285 CheckIn() 322, 327 CheckOut() 316, 322, 327 Claims Authentication 302, 471, 486 Class Library 382 Class Library Project 382 Classes 62

Sitefinity 5

Classification 52, 265 Click to add a description 106 ClrType 521, 523 Code reference for modules 458 CompositeControl 386 Computed style 225 Configuration 279 Configuring the Google Analytics widget 188 Confirmation options 154 Contact information 101 Content 52 Content Block 87 ContentDataProviderBase 506 ContentItem 291, 293, 294 ContentLifecycleStatus 285, 332 ContentManager 291, 293, 295 ContentPlaceholder 256, 260, 263, 265 ControlDesigner 405, 407 ControlDesignerBase 404 ControlDesignerModes 404 Controls 346 ControlType 376, 391, 436 CookieCollection 486 CookieContainer 486 Copy content from another language 353 Copy in clipboard 188 Count() 332 Create a Blog 133 Create a child of the selected page 81 Create a child page 78 Create a content item 87 Create a form 154, 437 Create a group of rules 233 Create a library 146 Create a list item 128 Create a news item 94 Create a Page 44, 263 Create a post 136 Create a Response 437 Create a role 169 Create a Template 252, 260 Create a user 171 Create an Album 106 Create and return to templates 210, 260 Create as child page 112 Create New Template 202 Create this album 106 Create this list 128

Create this template 202 CreateContent() 291 CreateDataItem 458 CreateImage() 327 CreateNew() 319, 321 CreateNewStandardPage() 316 CreatePageData() 285 CreateTaxon() 501, 509 CreateTaxonomy() 501 CreateUser() 307 Credentials 304, 306 CRUD 273, 291 CSS 221, 225 CSS widget 222 Custom Control 369, 410 Custom Control Designer 425 Custom Controls 382, 406, 408 Custom Fields 514

-Ddashboard 191 Data 52 DataBind() 335 DataContractJsonSerializer 475, 482, 493 DataExtensions 528 DataFieldID 289 DataFieldParentID 289 DataItemType 504 DataSource 335, 341, 345 DataTextField 335 DataValueField 335, 341 Default 308 Delete() 291, 294 Descendants 325 Description and Keywords 44 Design 233 Designers 168 Different domains 353 Directories 353 directory structure 249 DirectoryInfo 329 Do() 319 Document Link widget 149 Document Manager 67 Document Object Model 225 documents 146 DoesFieldExist 528
2012 Falafel Software

539

Index

539

DOM 225, 400 Download from Publisher 248 DownloadData 327 Drag layout elements 62, 212 Drag widgets 52, 215 DropDownList 335 DynamicContent 458 DynamicData 520 DynamicData() 521, 523, 525 DynamicModuleManager 458 DynamicTypeFacade 524

-EEdit layout element 222 Editors 168 Element 325 Elements 325 Embed link to this file 146 Embedded Resource 384, 397, 399, 400, 402, 407 Enable caching 44 Enable ViewState 44, 408 EnableViewState 386 Enter Content 52 Entries 346 Events 86, 87 Expandable list 131 Export CSV 160 Extension 329

Fluent API 273, 316, 324, 326, 331, 332 FluentSitefinity 315, 331 form 154 Form Builder 427 Format Stripper 52, 67 FormatString 215 FormDescription 341, 344, 346 FormEntry 344 FormsManager 341, 344 freecsstemplates.org 256 From already uploaded 52, 149 From selected library 123 From your computer 52 Frontend Themes 251, 259 FrontendRootNodeId 285

-GGenerate Thumbnails 119 Generic content list 87 Get Analytics Accounts 188 Get() 332 GetAlbum() 326, 327 GetBingResults() 325 GetContent() 291, 293 GetControl() 420 GetCurrentUserName() 434 GetFiles() 329 getfirebug.com 225 GetForm() 343 GetFormEntries() 344 GetForms() 341 GetItems() 291 GetItemsByTaxon() 506 GetManager() 276, 285, 291, 293, 307, 344, 458, 501 GetMappedManager() 506 GetPageDataList() 276 GetPageNode() 285 GetPageNodes() 285, 289 GetResponse() 486 GetRoles() 308 GetScriptDescriptors() 435 GetScriptReferences() 404, 407, 435 GetStatistics() 504 GetTaxa() 501, 509 GetTaxon() 501, 506 GetTaxonomies() 502

-FFieldControl 432 FieldName 435, 523 Fields 524 FileInfo 329 FileInfo.Extension 329 FileInfo.Open() 329 Find & Replace 67 Fine tune the selected type 112, 123 Firebug 225 First Time Setup and Configuration 188 First() 332 FirstOrDefault() 294 FlatTaxon 509 FlatTaxonomy 502 Fluent 316, 331, 332
2012 Falafel Software

Sitefinity 5

GetTaxonomy() 501, 503 GetTemplates() 285 GetValue 528 GetValue() 344 Go to Analytics 188 Google Analytics 188 group other pages 44 Guid 285, 292 Guid.Empty 289

-HHashTable 418, 420 HD2 236 HeaderText 347 hidden field 514 HiddenField 420 HierarchicalTaxon 509 HierarchicalTaxonomy 502 Host the Silverlight application... 411 HTC 236 HTC Incredible 236 HTML 225 HTML Editor 67 HTML included in the <head> tag 44 HtmlPage 422 HtmlTitle 285 HttpRequestHeader 473 HttpStatusCode 481 HttpUtility 471 HttpWebRequest 480, 482, 486 HttpWebResponse 481, 482, 486 Hyperlink 67

Insert a video 123 Insert this Link 52 Instructional text 154 Interface Labels & Message 365 Interface Labels & Messages 6, 352, 365 Interface widget... 514 Invariant language 365 iPad 2 236 iPhone 236 iPhone 4 236 iPhone 4s 237 IQueryable 291, 293, 332, 341 IQueryable<T> 293 IsBackendPage 276 IsTaxonomyBuiltIn() 502 ITaxonomy 500

-JJavaScript 188, 225, 396, 400, 406, 415, 418, 421, 428, 430 JavaScript Object Notation 418, 466 JavaScriptSerializer 418 JQuery 400 JScript 400, 428 JSON 418, 466, 473, 475, 486, 490, 495

-KKeep all language versions synced 353

-LLabel 154, 372 Language Packs 365 Language selector widget 360 Languages 364 Last() 332 Layout 212, 225, 254 LayoutTemplateName 386, 404, 433 Levels to include 215 LibrariesManager 458 library 146 lightbox 112 Limit the items in the feed 133 Limitations 154, 514 Link to a CSS file 222
2012 Falafel Software

-IIEnumerable 325, 327, 329 IFormFieldControl 432 Image gallery 112 Image Manager 52, 67, 128 Images 86 Images Gallery 112 Implement Abstract Class 404 Include RadScriptManager 44, 408 InitializeControls 434 InitializeControls() 386, 418 Insert a document or other file 149

541

Index

541

LinkTo 52 LINQ 273, 285, 291 list 128 list item 128 List Items widget 131 List Settings 94, 142, 199 List template 94, 142 ListBox 344 Live 291, 293, 332 Localization 362 Location 101 Login 52 Login name widget 215 Logout 173 Logout() 306 Lstring 363

NameValueCollection 471 Navigation 52 Navigation widget 215 NeedAdminRights 304 NeedDataSource 347 New visits rate 191 News 86, 87 NewsItem 319 Newsletters 52 No limit and paging 94 No Restrictions 154 Notify users by email 178 Number of daily visits 191

-OOne entry per IP 154 One entry per username 154 Open() 329 OrderBy() 332 OrderByDescending 332 OrderByDescending() 332 Orientation 237 Other data 202 Overlay 123 Owner 292

-MMake required 154, 514 Manage 86 Manage backend languages 353 Manage Pages 80 MarkedItemsCount 504 Marketplace 247, 249 Master 258, 291, 293 Master Page 246, 256 master pages 244, 249 Match case 67 Match whole words 67 Media Manager 67 MembershipCreateStatus 307 MembershipProvider 486 MemoryStream 327, 493 meta tags 258 MetaField 346, 435, 523 MetaType 521 Method 466 Module Builder 443, 452 More actions 81 More formatting options 52 Multilingual URLs 353 Multiple choice widget 154

-Ppage template 209 Page Templates 80, 210, 222, 252, 260 Page views 191 PageControls 374, 376, 391 PageData 276, 285, 289, 362 PageManager 276, 285 PageNode 285, 289 Pages() 317 PageTemplate 422 Paragraph box widget 154 Parent 289 Paste From Word 67 Paste Word 52 Permission 166 Permissions 166, 169, 173 Permissions for all pages 80 Persistent 304, 486 pluginLoaded() 421

-NName for developers


2012 Falafel Software

154

Sitefinity 5

Predefined value 514 PreRender 347 Properties.AssemblyInfo.cs 397 PublicationDate 319 Publish 79 Publish() 291, 292, 316, 322, 327

Roles 168 RSS 132, 141, 324 RSS feed 141 RSS or Atom to generate rules 233

133

-RRadBook 410, 418, 422, 425 RadComboBox 409 RadControls 52 RadGrid 345, 347 RadScriptManager 44, 408 RadTagCloud 504, 506 RadTreeView 289, 317 Range 154 ReadObject() 475 Really Simple Syndication 132 Rebind() 347 RecompileItemUrls() 292 RecompileItemUrls<T>() 291 Redirect to a page... 154 RegisterScriptableObject 422 Remove Link 67 Request Example 466 Request Format 466 Request Schema 466 Require SSL 44 RequireScriptManager 418, 420 Resize images... 106 Resize the image width to... 215 Resolution 237 ResolveUrl() 415 ResourceClassId 374 ResourceFile 397 ResourceLinks 402 Response Example 466 Response Format 466 Response Schema 466 Responses for... 160 Responsive and Mobile design 233 REST 273, 324, 473 Restore template to default 202 Restrictions 154 role 166, 169 Role Providers 308 RoleManager 308

-SSamsung Galaxy Tab 236 Save a Draft 87 Save as Draft 79 SaveChanges() 285, 291, 292, 295, 307, 316, 319, 327 Schedule Publish 136 ScriptableMember 418, 422 ScriptManager 408 Scripts and Styles 52, 222 Search 52 Search Engine Optimization 87 search engines 44 Search Options 67 Search... 81 Sections 374, 376, 391 Security Token Service 471 SecurityManager 304, 306, 434 Select a masterpage 260 Select a template 254 Select another Template 210, 260, 263 Select another template... 254 Select documents or other files 146 Select image gallery type 112 Select roles or users 178 Select() 289, 333 Selected Album... 112 SelectedIndexChanged 335 SelectedValue 335 Send for Approval 183 SEO 87 Services 466 SessionExpired 304 Set approvers 178 Settings 374, 391 Settings & configurations 178 SetValue 528 Show in Navigation 44 Silverlight 411 SimpleView 386 Single Item Settings 94, 142
2012 Falafel Software

543

Index

543

Single Sign On 471 Sitefinity API 273, 291 Sitefinity Marketplace 247 Sitefinity REST services 273 Sitefinity Starter Kits 495 Sitefinity Template 246, 256 SitefinityWebApp 274, 384, 402, 428 SiteInitializer 285 Skip() 332 Smart phone 233 Smartphones 233 SolarFlare 247, 248, 252, 254 Sort blog posts 142 Sort news 94 SourceName 512 SourceSite 512 Spell Check 67 Static 402 StatisticType 504 Stream 327 StreamReader 482, 486 STS 471 Style Sheet 399 Success 304 SuppressSecurityChecks 285, 289, 292, 316 Symbols 67 System.Runtime.Serialization 420, 475, 493 System.Runtime.Serialization.Json 493 System.Web 471 System.Web.Extensions 404 System.Web.UI 404

-TTables 67 TagKey 404 Tags 265, 498 Take() 332 Taxa 500, 503 Taxon 500, 506 TaxonId 504 TaxonName 502 Taxonomy 498, 500, 503 TaxonomyId 504 TaxonomyManager 501, 506, 509 TaxonomyPropertyDescriptor 506 Telerik OpenAccess 420 Telerik.Sitefinity 382, 402
2012 Falafel Software

Telerik.Sitefinity.Abstractions 285 Telerik.Sitefinity.Data.Metadata 432 Telerik.Sitefinity.Metadata.Model 432 Telerik.Sitefinity.Model 420, 432, 528 Telerik.Sitefinity.Modules.Forms.Web.UI.Fields 432 Telerik.Sitefinity.Security 432 Telerik.Sitefinity.Security.Model 292 Telerik.Sitefinity.Web.UI.ControlDesign 404 Telerik.Sitefinity.Web.UI.Fields 432 Telerik.Sitefinity.Web.UI.Fields.Enums 432 Telerik.Web.UI 429, 432 Telerik.Windows.Controls 422 Telerik.Windows.Controls.Navigation 422 Temp 291, 293 Template 246, 260, 263, 285 Template name 199, 202 Text box size 154 Textbox widget 154 Theme 246, 252, 256, 260 themes 221, 249 This is a hidden field 514 This user can access site backend 171 Thumbnail 119 Thumbnail strip 112 Thumbnails + Detail page 112, 123 Thumbnails + Overlay 112, 123 Title & Properties 51, 285 Title for Search Engines 44 Titles and dates 198, 199, 202 ToList() 332 Toolboxes 374, 376, 391 ToolboxesConfig.config 376 Total Map Points 191 Traffic origin 191 Transform the layout 239 Type() 524 TypeResolutionService 458

-UUICulture 362, 363 UnauthorizedAccessException 306 Union() 502 Unknown 304 Unlock 78 Unpublish 136 Upload documents or other files 146

Sitefinity 5

Upload images 106 Upload new videos 123 UploadContent 327 UploadContent() 321, 322, 329 UriTemplate 466 Url name 133 Use limit 94 Use paging 94 Use template 210, 260, 263 Use the selected template as a default template... 218 Use your own .master file 260 User 171, 292, 307 User Control 369, 410 User Controls 371, 408 UserAlreadyLoggedIn 304 UserLimitReached 304 UserLoggedFromDifferentComputer 304 UserLoggedFromDifferentIp 304 UserLoggedOff 304 UserLoggingReason 304 UserManager 292, 307 UserNotFound 304 UserRevoked 304

'WRAP 473 Wrapper 62 Write CSS 222

-XXAML 422 X-Authentication-Error 478 XDocument 324, 325 XDocument.Load() 325 XNamespace 325

-Vval() 400 Video gallery View a page Visual Studio 123 173 274, 278

-WWeb Form 274 Web User Control 372, 384 WebClient 322, 327 WebException 478 WebRequest 397 WebResource 397, 399 WebResource() 407 Where() 276, 293, 294, 332, 335 Which image to upload 215 Who can View a page? 173 widget templates 198, 204, 249 workflow 178 WorkWith() 315, 319, 327, 331, 332
2012 Falafel Software

Potrebbero piacerti anche