atomsite.net

The AtomPub server for .NET

Information - Browsing Technical

  1. Logging

    Just like the rest of AtomSite, the logging infrastructure is modular.  Out of the box, AtomSite is configured to use regular TraceSouce logging. The log data goes directly through the debug system. You can view it with debug view.  However, if your site is deployed, you may want to log to a file so you can view the logs of your remote server.

    Default Logging Setup (web.config)

    DefautLogging

    The default logging setup uses the default log listener.

    Recommended Logging Setup (web.config)

    RecommendedLogging

    This logging setup removes the default listener and replaces it with a file log.  Only warnings, errors, and fatal errors will be logged to this file.  When debugging, you can change the source switch value to Verbose to get more information.

    The built-in TextWriterTraceListener does not work in medium trust.

    Posted by JarrettV on March 28 at 1:45 PM

  2. TODO List

    FIXED Unapprove link doesn't work in Manager for non-blog collections
    DONE  Add Edit User support
    DONE  Installed, Online, Upload filter on Themes
    DONE  Update Users page in Manager
    ADDED Role Manager, need to add modify, inherit, scope support

    Better theme thumbnails
    DONE Add upload theme support
    DONE Delete theme
    Clone theme

    Change site when (new collection/workspace)
    FIXED Fix href when new collection created
    Delete workspace and delete collection in Manager

    Show not implemented on non-finished links

    DONE Widget scoping, asset group, master page, areas improvements, additional descriptions

    Widget configuration popups, individualized per widget
    Widget area hints
    Widget page hints

    Widget include scope filtering
    Add context specification upon including widgets

    FIXED Fix CSS for response for QuickPub
    Force pending entries to update upon quickpub draft
    Update counts in right now widget upon approve, delete
    Update counts upon approve, delete in Entries and Annotations
    DONE Delete user

    Better user names when logging in with google OpenId

    DONE Update counts for items, authors, contributors in workspace, collection settings
    Fix support for multi-folder, multi-subdomin, add new multi-domain in AtomSite Manager

    Update more of the code to properly use ModelBinders

    CDN Manager and setting

    Posted by JarrettV on March 03 at 1:52 PM

  3. Plugin Development Basics

    This tutorial will step you through the process of building a simple contact form plugin.  This plugin will display a form on the page that will collect contact information.  This plugin is included as a core plugin in version 1.4.

    Step 1: Create the Input Form Widget

    First, start by creating a model to hold the data for contact form (/plugins/Contact/ContactModel.cs):

    public class ContactModel : BaseModel
    {
        public string EntryId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Message { get; set; }
    }
    

    This view model will be used to strongly type the data to the view.

    Next, create a partial view that uses the above model to display the contact form (/themes/default/ContactWidget.ascx):

    <%@ Control Language="C#" AutoEventWireup="true" Inherits="ViewUserControl<ContactModel>" %>
    
    <div id="contact">
      <h4>Send A Message</h4>
      <form method="post" action="<%= Url.Action("SendMessage", "Contact") %>">
        <fieldset>
          <%= Html.Hidden("entryId", Model.EntryId) %>
    
          <label for="name">Name <small>(required)</small></label><%= Html.ValidationMessage("name") %>
          <%= Html.TextBox("name", Model.Name) %>
    
          <label for="email">Email <small>(required)</small></label><%= Html.ValidationMessage("email") %>      
          <%= Html.TextBox("email", Model.Email) %>
    
          <label for="phone">Phone</label><%= Html.ValidationMessage("phone") %>
          <%= Html.TextBox("phone", Model.Phone) %>
    
          <label for="message">Message <small>(required)</small></label><%= Html.ValidationMessage("message")%>
          <%= Html.TextArea("message", Model.Message, 4, 100, null) %>
          
          <%= Html.ValidationMessage("error") %>
          <input type="submit" value="Send Message" />
        </fieldset>
      </form>
    </div>
    

    This form has inputs and validation messages for each of the fields.  The submit button will post to the SendMessage action of the Contact Controller.

    Step 2: Create the Controller

    Create the controller to handle the display of the contact form widget and the post of the form data (/plugins/Contact/ContactController.cs).  The the following Action method will display the contact form widget partial view:

    public ActionResult ContactWidget(Include include)
    {
        ContactModel model = new ContactModel();
        model.EntryId = EntryId.ToString();
        return PartialView("ContactWidget", model);
    }
    

    Also create the action that will handle the form post:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SendMessage(ContactModel model)
    {
        LogService.Info("SendMessage");
        ValidateContactModel(model);
    
        if (this.ModelState.IsValid)
        {
            //TODO: support both ajax and full page
            try
            {
                // get contact configuration
                var contact = new ContactAppWorkspace(Workspace).Contact;
                SendContactMessage(contact, model);                
                return PartialView("ContactSuccess", model);
            }
            catch (Exception ex)
            {
                LogService.Error(ex);
                ModelState.AddModelError("error", "An unexpected error occured, please contact the webmaster.");
            }
        }
        return PartialView("ContactWidget", model);
    }
    

    This method expects AJAX form posts but it can be expanded to use a full page if needed.  Take a look at the source code to see the implementation of the ContactAppWorkspace, ValidateContactModel, and SendContactMessage.

    When the user posts the form, if there are any errors, the form is returned with the errors displayed.  If there are no errors, the success partial view is returned.

    Step 3: Add Success View

    Add the following code to a new partial view that accepts the strongly typed ContactModel from before (/themes/default/ContactSuccess.ascx):

    <%@ Control Language="C#" AutoEventWireup="true" Inherits="ViewUserControl<ContactModel>" %>
    <div id="contact">
        <h4>Thank You!</h4>
      <p class="response"><strong>Your message was sent successfully.</strong> We will get back to you as soon as possible.</p>
      <p>
      Name: <%= Model.Name %><br />
      Email: <%= Model.Email %><br />
      Phone: <%= Model.Phone %><br />
      Message: <%= Model.Message %>
      </p>
    </div>
    

    Step 4: Add Ajax and Style Assets

    Let's add some jQuery that will turn our form into an AJAX post (/js/default/Contact.js):

    $(document).ready(function () {
      $('#contact form').live('submit', function () {
        $.post($(this).attr('action'), $(this).serialize(), function (data) {
          $("#contact").replaceWith($(data));
        });
        return false;
      });
    });
    

    The above jQuery posts the form to the action and redisplays the response.  Since it is using a live event, the submit function is rewired if the response contains the error form.

    Let's add some style information to make the form look better (/css/default/Contact.css):

    #contact label small {color:#666}
    #contact input[type=text], #contact textarea {display:block; width:90%; margin-bottom:0.8em}
    #contact input[type=text] {width:40%}
    #contact .field-validation-error {color:#FF4444; margin-left:1em}
    #contact .input-validation-error {color:#900; background-color:#FFDFDF}
    #contact .response strong {color:#008800}
    

    Step 5: Register Plugin

    For the widget to be recognized, we need to register it as part of the plugin.  Create the ContactPlugin that derives from Plugin (/plugins/ContactPlugin.cs):

    public class ContactPlugin : BasePlugin
    {
        public ContactPlugin(ILogService logger) : base(logger) { }
        
        public override void Register(IContainer container, List<SiteRoute> routes, ViewEngineCollection viewEngines, ModelBinderDictionary modelBinders, ICollection<Asset> globalAssets)
        {
          RegisterController<ContactController>(container);
          RegisterCompositeWidget(container, "ContactWidget", "Contact", "ContactWidget", new string[] { "Contact.css", "Contact.js" });
        }
    }
    

    This code notifies the plugin system that our plugin has a controller and a composite widget that calls the ContactWidget action in the ContactController.  It also has two assets, Contact.css and Contact.js needed by the widget.  These assets will get added to the page anytime this widget is used.

    Step 6: Include the Widget into the Contact Page

    We are ready to include the widget on our contact page.  We will use the new inline-widget support to include the widget into the content of our page.  Open the contact.xml file from the www pages collection and add the following include line (/App_Data/www/pages/contact.xml):

    <svc:include name="ContactWidget" />

    <atom:content type="xhtml">
    <div>
      <p>
        You can contact me via email <strong><a href="mailto:admin@example.com">admin@example.com</a></strong> or feel free to leave a comment on my blog.
      </p>
      <svc:include name="ContactWidget" />
    </div>
    </atom:content>
    

    This tells the system to include the widget into the content of the page.

    You are done, you should now be able to view the contact form on the contact page.  If there are errors, the form will redisplay with the error messages.

    image

    In the next part, we will look at adding configuration settings for this plugin to the AtomSite Manager.

    Posted by JarrettV on February 20 at 12:05 PM

  4. CDN for Assets

    AtomSite supports content delivery networks for improving the performance of asset downloads.  A CDN allows you to spread the assets your site needs across multiple servers.  Web browsers can download the site faster because it can make multiple calls when assets are separate domains.

    Adding New CDN Locations in AtomSite

    You can add CDN locations in AtomSite by adding a <cdn> element in the service.config <service> element.  For example:

    <svc:cdn>
      <svc:asset name="jquery.tools-1.1.1.min.js" url="http://cdn.jquerytools.org/1.1.1/tiny/jquery.tools.min.js"/>
    </svc:cdn>

    If there are multiple locations for the same asset, AtomSite will always use the first location.

    Default CDN Locations

    The default CDN locations in AtomSite (for version 1.3) are shown below.

    <cdn xmlns="http://atomsite.net/info/Service">
      <!-- These are the default CDN asset locations, when multiple, always uses first one -->
      <!-- These locations can be overridden in the <service> element of the service.config -->
      <asset name="reset-fonts-grids-2.7.0.css" url="http://yui.yahooapis.com/2.7.0/build/reset-fonts-grids/reset-fonts-grids.css"/>
      <asset name="jquery-1.3.2.min.js" url="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"/>
      <asset name="jquery-1.3.2.min.js" url="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js"/>
      <asset name="jquery.tools-1.1.1.min.js" url="http://cdn.jquerytools.org/1.1.1/tiny/jquery.tools.min.js"/>
    </cdn>
    Posted by JarrettV on September 21 at 1:06 PM

  5. Service

    AtomSite.net Service.config File Example

    <?xml version="1.0" encoding="utf-8"?>
    <service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:svc="http://atomsite.net/info/Service" xmlns:file="http://atomsite.net/info/FileRepository" xmlns:plug="http://atomsite.net/info/Plugins" xml:base="http://atomsite.net">
      <svc:admin>JarrettV</svc:admin>
      <workspace svc:default="true" svc:theme="atomsite">
        <atom:title>atomsite.net</atom:title>
        <atom:subtitle>The AtomPub server for .NET</atom:subtitle>
        <collection href="blog.atom" svc:default="true" file:path="App_Data\blog\" svc:bloggingOn="true" svc:trackbacksOn="true" svc:defaultView="BlogListing">
          <atom:title>News Blog</atom:title>
          <atom:id>tag:atomsite.net,2008:blog</atom:id>
          <atom:logo>media/Logo.png</atom:logo>
          <atom:icon>media/Icon.png</atom:icon>
          <categories fixed="no">
            <atom:category term="AspNet" label="Asp.Net" />
            <atom:category term="CSharp" label="C#" />
            <atom:category term="AtomSite" />
            <atom:category term="BlogSvc" />
            <atom:category term="XLinq" label="Linq to Xml" />
            <atom:category term="Linq" label="Linq to Objects" />
            <atom:category term="DLinq" label="Linq to Sql" />
            <atom:category term="WCF" />
            <atom:category term="MVC" />
            <atom:category term="Website" />
            <atom:category term="Release" />
            <atom:category term="jQuery" />
            <atom:category term="WLW" />
            <atom:category term="Manager" />
          </categories>
          <svc:page name="BlogEntry">
            <svc:area name="sidetop">
              <svc:include name="BlogSearchWidget" />
              <svc:include name="RaterWidget" />
            </svc:area>
            <svc:area name="sidemid">
              <svc:include name="BlogCategoryCloudWidget">
                <svc:id>tag:atomsite.net,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogRecentWidget">
                <svc:title>Recent Entries</svc:title>
                <svc:id>tag:atomsite.net,2008:blog</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="content">
              <svc:include name="BlogCommentsWidget" />
              <svc:include name="BlogAddCommentWidget" />
            </svc:area>
            <svc:area name="tail">
              <svc:include name="BlogTrackbackWidget" />
            </svc:area>
          </svc:page>
          <svc:page name="BlogListing">
            <svc:area name="sidetop">
              <svc:include name="BlogSearchWidget" />
            </svc:area>
            <svc:area name="sidemid">
              <svc:include name="BlogRecentWidget">
                <svc:title>Recent Entries</svc:title>
                <svc:id>tag:atomsite.net,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogArchiveWidget">
                <svc:id>tag:atomsite.net,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogCategoriesWidget">
                <svc:id>tag:atomsite.net,2008:blog</svc:id>
              </svc:include>
            </svc:area>
          </svc:page>
        </collection>
        <collection href="info.atom" file:path="App_Data\info\" svc:dated="false" svc:ratingsOn="false" svc:bloggingOn="true">
          <atom:title type="html">Information</atom:title>
          <atom:id>tag:atomsite.net,2008:info</atom:id>
          <categories fixed="no">
            <atom:category term="Release" />
            <atom:category term="Technical" />
            <atom:category term="Features" />
            <atom:category term="About" />
          </categories>
          <svc:page name="BlogEntry" template="yui-t2">
            <svc:area name="sidetop">
              <svc:include name="BlogEntrySimpleWidget">
                <svc:id>tag:atomsite.net,2008:info,Index</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="sidemid"></svc:area>
            <svc:area name="content">
              <svc:include name="BlogSearchWidget" />
              <svc:include name="RaterWidget" />
            </svc:area>
            <svc:area name="tail"></svc:area>
          </svc:page>
          <svc:page name="BlogListing" template="yui-t2">
            <svc:area name="sidetop">
              <svc:include name="BlogEntrySimpleWidget">
                <svc:id>tag:atomsite.net,2008:info,Index</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="sidemid"></svc:area>
            <svc:area name="content">
              <svc:include name="BlogSearchWidget" />
            </svc:area>
          </svc:page>
          <svc:author>Kristin</svc:author>
        </collection>
        <collection href="media.atom" file:path="media\" svc:annotationsOn="false" svc:ratingsOn="false" svc:syndicationOn="false" svc:visible="false">
          <atom:title>Media</atom:title>
          <atom:id>tag:atomsite.net,2008:media</atom:id>
          <accept file:ext="png">image/png</accept>
          <accept file:ext="jpg">image/jpeg</accept>
          <accept file:ext="gif">image/gif</accept>
        </collection>
        <collection href="plugins.atom" file:path="App_Data\plugins\" svc:dated="false" svc:ratingsOn="true" svc:bloggingOn="true" svc:trackbacksOn="false" svc:defaultView="BlogListing" svc:defaultEntryView="PluginEntry" svc:extPluginOn="true">
          <atom:title>Plugins</atom:title>
          <atom:id>tag:atomsite.net,2009:plugins</atom:id>
        </collection>
        <collection href="themes.atom" file:path="App_Data\themes\" svc:dated="false" svc:ratingsOn="true" svc:bloggingOn="true" svc:trackbacksOn="false" svc:defaultView="ThemeListing" svc:defaultEntryView="ThemeEntry" svc:extThemeOn="true">
          <atom:title>Themes</atom:title>
          <atom:id>tag:atomsite.net,2009:themes</atom:id>
          <svc:page name="ThemeEntry">
            <svc:area name="content">
              <svc:include name="BlogCommentsWidget" />
              <svc:include name="BlogAddCommentWidget" />
            </svc:area>
            <svc:area name="sidetop">
              <svc:include name="BlogSearchWidget">
                <svc:scope>collection</svc:scope>
              </svc:include>
            </svc:area>
          </svc:page>
          <svc:page name="ThemeListing">
            <svc:area name="sidetop">
              <svc:include name="BlogSearchWidget">
                <svc:scope>collection</svc:scope>
              </svc:include>
            </svc:area>
          </svc:page>
        </collection>
      </workspace>
      <svc:page width="doc4">
        <svc:area name="nav">
          <svc:include name="MenuCustomWidget">
            <svc:item href="/" text="Home" selected="false" />
            <svc:item href="/info/Download.xhtml" text="Download" selected="false" />
            <svc:item href="/blog.xhtml" text="Blog" selected="false" />
            <svc:item href="/info/Overview.xhtml" text="Docs" selected="true" />
            <svc:item href="/plugins.xhtml" text="Plugins" selected="false" />
            <svc:item href="/themes.xhtml" text="Themes" selected="false" />
            <svc:item href="http://www.codeplex.com/blogsvc/WorkItem/List.aspx" text="Support" selected="false" />
          </svc:include>
        </svc:area>
        <svc:area name="foot">
          <svc:include name="AccountStatusWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AccountLogin">
        <svc:area name="content">
          <svc:include name="OpenIdLoginWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AtomPubResource">
        <svc:area name="content">
          <svc:include name="AnnotateListWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="BlogHome">
        <svc:area name="content">
          <svc:include name="BlogEntrySimpleWidget">
            <svc:id>tag:atomsite.net,2008:info,Welcome</svc:id>
          </svc:include>
          <svc:include name="BlogSummaryWidget">
            <svc:count>3</svc:count>
            <svc:id>tag:atomsite.net,2008:blog</svc:id>
          </svc:include>
          <svc:include name="BlogRecentWidget">
            <svc:title>Doc Updates</svc:title>
            <svc:count>6</svc:count>
            <svc:id>tag:atomsite.net,2008:info</svc:id>
          </svc:include>
          <svc:include name="BlogSearchWidget" />
          <svc:include name="BlogEntrySimpleWidget">
            <svc:id>tag:atomsite.net,2008:info,CoreTechs</svc:id>
          </svc:include>
          <svc:include name="BlogCategoryCloudWidget" />
          <svc:include name="BlogEntrySimpleWidget">
            <svc:id>tag:atomsite.net,2008:info,Contribute</svc:id>
          </svc:include>
        </svc:area>
        <svc:area name="sidetop"></svc:area>
        <svc:area name="sidemid"></svc:area>
      </svc:page>
      <svc:page name="AdminDashboard">
        <svc:area name="dashboardLeft">
          <svc:include name="AdminRightNowWidget" />
          <svc:include name="AdminRecentAnnotationsWidget" />
        </svc:area>
        <svc:area name="dashboardRight">
          <svc:include name="AdminQuickPubWidget" />
          <svc:include name="AdminPendingEntriesWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsEntireSite">
        <svc:area name="settingsLeft">
          <svc:include name="AdminWorkspacesWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminAdministratorsWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsWorkspace">
        <svc:area name="settingsLeft">
          <svc:include name="AdminCollectionsWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminPeopleWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsCollection">
        <svc:area name="settingsLeft">
          <svc:include name="AdminAcceptsWidget" />
        </svc:area>
        <svc:area name="settingsMiddle">
          <svc:include name="AdminCategoriesWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminPeopleWidget" />
        </svc:area>
        <svc:area name="settingsTabs">
          <svc:include name="LiteralWidget">&lt;li&gt;&lt;a href="#blogSettings"&gt;Blog Settings&lt;/a&gt;&lt;/li&gt;</svc:include>
        </svc:area>
        <svc:area name="settingsPanes">
          <svc:include name="BlogSettingsWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminEditEntry">
        <svc:area name="editEntryContent">
          <svc:include name="AdminCKEditorWidget" />
        </svc:area>
      </svc:page>
      <svc:widget name="BlogAddCommentWidget">
        <svc:area name="commentator">
          <svc:include name="OpenIdModalWidget" />
        </svc:area>
      </svc:widget>
    </service>
    

    JVance.com Service.config File Example

    <?xml version="1.0" encoding="utf-8"?>
    <service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:svc="http://atomsite.net/info/Service" xmlns:file="http://atomsite.net/info/FileRepository" xmlns:plug="http://atomsite.net/info/Plugins" xml:base="http://jvance.com/" svc:theme="jvance">
      <svc:admin>Jarrett</svc:admin>
      <workspace svc:default="true">
        <atom:title>jvance.com</atom:title>
        <atom:subtitle>.net, c#, asp.net, linq, htpc, woodworking</atom:subtitle>
        <collection svc:dated="true" svc:default="true" href="/blog.atom" file:path="blog/" svc:bloggingOn="true" svc:trackbacksOn="true">
          <atom:title>Jarrett's Tech Blog</atom:title>
          <atom:id>tag:jvance.com,2008:blog</atom:id>
          <categories>
            <atom:category label="ASP.NET" term="ASPNET" />
            <atom:category label="BlogEngine.NET" term="BlogEngineNET" />
            <atom:category term="BlogSvc" />
            <atom:category label="C#" term="CSharp" />
            <atom:category term="Computers" />
            <atom:category term="HTPC" />
            <atom:category term="WCF" />
            <atom:category term="Woodworking" />
            <atom:category term="MVC" />
            <atom:category term="jQuery" />
            <atom:category term="AtomSite" />
          </categories>
        </collection>
        <collection href="/pages.atom" file:path="pages/" svc:dated="false" svc:bloggingOn="true" svc:trackbacksOn="true">
          <atom:title>Pages</atom:title>
          <atom:id>tag:jvance.com,2000:pages</atom:id>
          <categories>
            <atom:category term="Software" />
          </categories>
        </collection>
        <collection href="/media.atom" file:path="media/" svc:visible="false" svc:syndicationOn="no">
          <atom:title>Blog Media</atom:title>
          <atom:id>tag:jvance.com,2000:media</atom:id>
          <accept file:ext="png">image/png</accept>
          <accept file:ext="jpg">image/jpeg</accept>
          <accept file:ext="gif">image/gif</accept>
        </collection>
      </workspace>
      <svc:page width="doc3" template="yui-t6">
        <svc:area name="nav">
          <svc:include name="MenuCustomWidget">
            <svc:item href="/" text="Home" selected="false" />
            <svc:item href="/blog.xhtml" text="Blog" selected="false" />
            <svc:item href="/pages/category/Software.xhtml" text="Software" selected="false" />
            <svc:item href="/pages/Contact.xhtml" text="Contact" selected="true" />
          </svc:include>
          <svc:include name="BlogSearchWidget" />
        </svc:area>
        <svc:area name="foot">
          <svc:include name="AccountStatusWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AccountLogin">
        <svc:area name="content">
          <svc:include name="OpenIdLoginWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AtomPubResource">
        <svc:area name="content">
          <svc:include name="AnnotateListWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="BlogHome">
        <svc:area name="head">
          <svc:include name="LiteralWidget">
            &lt;link rel="openid.server" href="http://www.myopenid.com/server" /&gt;
            &lt;link rel="openid.delegate" href="http://jarrettv.myopenid.com/" /&gt;
          </svc:include>
        </svc:area>
        <svc:area name="content">
          <svc:include name="BlogSummaryWidget">
            <svc:count>10</svc:count>
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
        </svc:area>
        <svc:area name="sidemid">
          <svc:include name="BlogEntrySimpleWidget">
            <svc:id>tag:jvance.com,2008:pages,About</svc:id>
          </svc:include>
          <svc:include name="BlogEntrySimpleWidget">
            <svc:id>tag:jvance.com,2008:pages,Blogroll</svc:id>
          </svc:include>
          <svc:include name="BlogRecentCommentsWidget">
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
        </svc:area>
      </svc:page>
      <svc:page name="BlogEntry">
        <svc:area name="sidetop">
          <svc:include name="RaterWidget" />
        </svc:area>
        <svc:area name="sidemid">
          <svc:include name="BlogCategoryCloudWidget">
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
          <svc:include name="BlogRecentWidget">
            <svc:title>Recent Entries</svc:title>
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
        </svc:area>
        <svc:area name="content">
          <svc:include name="BlogCommentsWidget" />
          <svc:include name="BlogAddCommentWidget" />
        </svc:area>
        <svc:area name="tail">
          <svc:include name="BlogTrackbackWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="BlogListing">
        <svc:area name="sidemid">
          <svc:include name="BlogRecentWidget">
            <svc:title>Recent Entries</svc:title>
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
          <svc:include name="BlogArchiveWidget">
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
          <svc:include name="BlogCategoriesWidget">
            <svc:id>tag:jvance.com,2008:blog</svc:id>
          </svc:include>
        </svc:area>
      </svc:page>
      <svc:page name="AdminDashboard">
        <svc:area name="dashboardLeft">
          <svc:include name="AdminRightNowWidget" />
          <svc:include name="AdminRecentAnnotationsWidget" />
        </svc:area>
        <svc:area name="dashboardRight">
          <svc:include name="AdminQuickPubWidget" />
          <svc:include name="AdminPendingEntriesWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsCollection">
        <svc:area name="settingsTabs">
          <svc:include name="LiteralWidget">&lt;li&gt;&lt;a href="#blogSettings"&gt;Blog Settings&lt;/a&gt;&lt;/li&gt;</svc:include>
        </svc:area>
        <svc:area name="settingsPanes">
          <svc:include name="BlogSettingsWidget" />
        </svc:area>
        <svc:area name="settingsLeft">
          <svc:include name="AdminAcceptsWidget" />
        </svc:area>
        <svc:area name="settingsMiddle">
          <svc:include name="AdminCategoriesWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminPeopleWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsEntireSite">
        <svc:area name="settingsLeft">
          <svc:include name="AdminWorkspacesWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminAdministratorsWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminSettingsWorkspace">
        <svc:area name="settingsLeft">
          <svc:include name="AdminCollectionsWidget" />
        </svc:area>
        <svc:area name="settingsRight">
          <svc:include name="AdminPeopleWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminEditEntry">
        <svc:area name="editEntryContent">
          <svc:include name="AdminCKEditorWidget" />
        </svc:area>
      </svc:page>
      <svc:widget name="BlogAddCommentWidget">
        <svc:area name="commentator">
          <svc:include name="OpenIdModalWidget" />
        </svc:area>
      </svc:widget>
    </service>
    

    PoshCode.org Service.config Example File

    <?xml version="1.0" encoding="utf-8"?>
    <service xmlns="http://www.w3.org/2007/app" xmlns:files="http://atomsite.net/info/FileRepository" xmlns:plug="http://atomsite.net/info/Plugins" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:svc="http://atomsite.net/info/Service" xml:base="http://beta.PoshCode.org">
      <!-- To authorize access to the entire site, add administrators here. -->
      <svc:admin>Jaykul</svc:admin>
      <svc:admin>Oisin</svc:admin>
      <workspace svc:default="true" svc:theme="scriptinggames">
        <atom:title>PoshCode.org</atom:title>
        <atom:subtitle>PowerShell Script Repository</atom:subtitle>
        <!-- To authorize access to this workspace, add authors or contributors here. -->
        <collection href="code.atom" xmlns:code="http://schemas.poshcode.org/code" files:path="App_Data\code\" svc:default="true" svc:dated="false" svc:ratingsOn="true" svc:bloggingOn="true" svc:annotationsOn="true" svc:trackbacksOn="true" svc:showGravatars="g" svc:gravatarDefault="identicon" svc:defaultSearchView="CodeEntries" svc:defaultView="CodeEntries" svc:defaultEntryView="CodeEntry" svc:codeExtensionOn="true">
          <atom:title type="html">Code</atom:title>
          <atom:id>tag:poshcode.org,2008:code</atom:id>
          <atom:logo>media/PoshCode.png</atom:logo>
          <atom:icon>media/PoshCodeIcon.png</atom:icon>
          <code:licenses default="Public Domain">
            <atom:link rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/" title="Public Domain" />
            <atom:link rel="license" href="http://opensource.org/licenses/ms-pl.html" title="Microsoft Public License" />
            <atom:link rel="license" href="http://opensource.org/licenses/ms-rl.html" title="Microsoft Reciprocal License" />
          </code:licenses>
          <code:languages default="PowerShell 1.0">
            <code:language label="PowerShell 1.0" version="1.0" defaultExtension=".ps1">powershell</code:language>
            <code:language label="PowerShell 2.0" version="2.0" defaultExtension=".ps1">powershell</code:language>
            <code:language label="VBScript" defaultExtension=".vbs">vbscript</code:language>
          </code:languages>
          <categories fixed="yes" scheme="tag:poshcode.org,2008:categorytype/event">
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 1" term="SG09Adv1" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 2" term="SG09Adv2" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 3" term="SG09Adv3" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 4" term="SG09Adv4" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 5" term="SG09Adv5" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 6" term="SG09Adv6" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 7" term="SG09Adv7" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 8" term="SG09Adv8" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 9" term="SG09Adv9" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Advanced Event 10" term="SG09Adv10" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 1" term="SG09Beg1" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 2" term="SG09Beg2" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 3" term="SG09Beg3" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 4" term="SG09Beg4" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 5" term="SG09Beg5" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 6" term="SG09Beg6" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 7" term="SG09Beg7" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 8" term="SG09Beg8" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 9" term="SG09Beg9" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/event" label="Scripting Games 2009 - Beginner Event 10" term="SG09Beg10" />
          </categories>
          <categories fixed="no" scheme="tag:poshcode.org,2008:categorytype/tag">
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" label="static methods" term="StaticMethods" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" label=".Net" term="DotNET" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" label="code generation" term="CodeGeneration" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" label="compiled cmdlets" term="CompiledCmdlets" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" label="Imported From PoshCode 1.0" term="ImportedFromPoshCode" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="PSCX" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="CodePlex" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="PowerGUI" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="Trivial" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="ShayLevy" label="Shay Levy" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/tag" term="test" />
          </categories>
          <categories fixed="no" scheme="tag:poshcode.org,2008:categorytype/verb">
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Import" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Add" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Aggregate" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="ConvertFrom" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="ConvertTo" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Convert" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="CXNew" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Disconnect" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Expand" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Export" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Format" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Get" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Invoke" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Join" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="New" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Out" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Ping" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Pop" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Push" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Read" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Remove" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Resize" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Resolve" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Scroll" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Select" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Send" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Set" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Skip" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Split" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Start" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Stop" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Take" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Test" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Write" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/verb" term="Upload" />
          </categories>
          <categories fixed="no" scheme="tag:poshcode.org,2008:categorytype/noun">
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Method" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="PathVariable" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Object" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Base64" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="MacOs9LineEnding" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="UnixLineEnding" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="WindowsLineEnding" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Xml" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="TerminalSession" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Archive" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Bitmap" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Byte" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Hex" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="ADObject" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Clipboard" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="DhcpServer" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="DomainController" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="DriveInfo" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="ExportedType" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="FileVersionInfo" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="ForegroundWindow" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Hash" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="MountPoint" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="OleDbData" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="OleDbDataSet" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="PEHeader" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Privilege" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="PSSnapinHelp" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Random" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="ReparsePoint" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="ShortPath" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="SqlData" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="SqlDataSet" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="TabExpansion" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="WebService" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Apartment" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="OleDbCommand" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="SqlCommand" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="String" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Hardlink" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Junction" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Shortcut" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Symlink" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Host" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="EnvironmentBlock" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Assembly" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Table" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Text" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="SmtpMail" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="FileTime" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="VolumeLabel" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Process" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="PscxPath" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Scroll" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="BZip2" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="GZip" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Tar" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="Zip" />
            <atom:category scheme="tag:poshcode.org,2008:categorytype/noun" term="File" />
          </categories>
          <svc:page name="BlogHome">
            <svc:area name="content">
              <svc:include name="BlogEntrySimpleWidget">
                <svc:id>tag:poshcode.org,2008:blog,Welcome</svc:id>
              </svc:include>
              <svc:include name="CodeSummaryWidget">
                <svc:title>Newest Code Submissions</svc:title>
                <svc:count>10</svc:count>
                <svc:page>0</svc:page>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
              </svc:include>
              <svc:include name="BlogSummaryWidget">
                <svc:title>Latest News</svc:title>
                <svc:count>1</svc:count>
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
              <svc:include name="CodeTopRatedWidget">
                <svc:title>Highest Rated</svc:title>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
                <svc:count>20</svc:count>
                <svc:sort>rating</svc:sort>
              </svc:include>
              <svc:include name="BlogRecentWidget">
                <svc:title>More News</svc:title>
                <svc:count>6</svc:count>
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="sidetop"></svc:area>
            <svc:area name="sidemid"></svc:area>
          </svc:page>
          <svc:page name="CodeEntry">
            <svc:area name="content">
              <svc:include name="BlogCommentsWidget" />
              <svc:include name="BlogAddCommentWidget" />
            </svc:area>
            <svc:area name="sidetop">
              <svc:include name="CodeMetaWidget" />
            </svc:area>
            <svc:area name="sidemid">
              <svc:include name="BlogRecentWidget">
                <svc:title>Newest Contributions</svc:title>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
              </svc:include>
              <svc:include name="CodeTopRatedWidget">
                <svc:title>Highest Rated</svc:title>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
                <svc:sort>rating</svc:sort>
              </svc:include>
            </svc:area>
            <svc:area name="tail">
              <svc:include name="BlogTrackbackWidget" />
            </svc:area>
          </svc:page>
          <svc:page name="CodeEntries">
            <svc:area name="content" />
            <svc:area name="sidetop"></svc:area>
            <svc:area name="sidemid">
              <svc:include name="CodeTopRatedWidget">
                <svc:title>Highest Rated</svc:title>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
                <svc:sort>rating</svc:sort>
              </svc:include>
              <svc:include name="BlogRecentWidget">
                <svc:title>Newest Contributions</svc:title>
                <svc:id>tag:atomsite.net,2008:code</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="tail" />
          </svc:page>
          <svc:roleMatrix>
            <!-- AtomPub Actions-->
            <svc:roleAction name="GetServiceDoc" admin="True" author="True" contrib="True" user="False" anon="False" />
            <svc:roleAction name="UpdateServiceDoc" admin="True" author="True" contrib="False" user="False" anon="False" />
            <svc:roleAction name="GetCollectionFeed" admin="True" author="True" contrib="True" user="False" anon="False" />
            <svc:roleAction name="CreateEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="False" />
            <svc:roleAction name="GetEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="True" />
            <svc:roleAction name="UpdateEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="False" />
            <svc:roleAction name="DeleteEntryOrMedia" admin="True" author="True" contrib="False" user="False" anon="False" />
            <svc:roleAction name="PeekEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="True" />
            <!-- Additional Actions -->
            <svc:roleAction name="GetFeed" admin="True" author="True" contrib="True" user="True" anon="True" />
            <svc:roleAction name="GetAnnotations" admin="True" author="True" contrib="True" user="True" anon="True" />
            <svc:roleAction name="Annotate" admin="True" author="True" contrib="True" user="True" anon="True" />
            <svc:roleAction name="ApproveEntryOrMedia" admin="True" author="True" contrib="True" user="False" anon="False" />
            <svc:roleAction name="ApproveAnnotation" admin="True" author="True" contrib="True" user="True" anon="False" />
            <svc:roleAction name="AddCategory" admin="True" author="True" contrib="True" user="True" anon="False" />
            <svc:roleAction name="RemoveCategory" admin="True" author="True" contrib="True" user="True" anon="False" />
            <svc:roleAction name="RateEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="False" />
          </svc:roleMatrix>
        </collection>
        <collection href="blog.atom" files:path="App_Data\blog\" svc:default="false" svc:dated="false" svc:ratingsOn="false" svc:bloggingOn="true" svc:annotationsOn="true" svc:trackbacksOn="true" svc:showGravatars="g" svc:gravatarDefault="identicon" svc:defaultSearchView="BlogListing" svc:defaultView="BlogListing" svc:defaultEntryView="BlogEntry" svc:codeExtensionOn="false">
          <atom:title>Development 'blog</atom:title>
          <!-- BlogSvc supports many of the same fields for a collection as specified for 
                a feed.  These fields will automatically get inherited by the feed. -->
          <atom:id>tag:poshcode.org,2008:blog</atom:id>
          <atom:logo>media/AtomSite.png</atom:logo>
          <atom:icon>media/Icon.png</atom:icon>
          <!-- To authorize access to this collection, add authors or contributors here. -->
          <categories fixed="no">
            <atom:category term="About" />
            <atom:category term="Contribute" />
            <atom:category term="CSharp" label="C#" />
            <atom:category term="AtomSite" />
            <atom:category term="XLinq" label="Linq to Xml" />
            <atom:category term="Linq" label="Linq to Objects" />
            <atom:category term="DLinq" label="Linq to Sql" />
            <atom:category term="WCF" />
            <atom:category term="MVC" />
            <atom:category term="Website" />
            <atom:category term="Release" />
            <atom:category term="jQuery" />
            <atom:category term="WLW" />
          </categories>
          <svc:page name="BlogEntry">
            <svc:area name="sidetop">
              <svc:include name="RaterWidget" />
            </svc:area>
            <svc:area name="sidemid">
              <svc:include name="BlogCategoriesWidget">
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogRecentWidget">
                <svc:title>Recent Entries</svc:title>
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
            </svc:area>
            <svc:area name="content">
              <svc:include name="BlogCommentsWidget" />
              <svc:include name="BlogAddCommentWidget" />
            </svc:area>
            <svc:area name="tail">
              <svc:include name="BlogTrackbackWidget" />
            </svc:area>
          </svc:page>
          <svc:page name="BlogListing">
            <svc:area name="sidetop"></svc:area>
            <svc:area name="sidemid">
              <svc:include name="BlogRecentWidget">
                <svc:title>Recent Entries</svc:title>
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogArchiveWidget">
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
              <svc:include name="BlogCategoriesWidget">
                <svc:id>tag:poshcode.org,2008:blog</svc:id>
              </svc:include>
            </svc:area>
          </svc:page>
        </collection>
        <!--
             This collection allows image uploads.  Change/add mime-types to allow
             other forms of data.
          -->
        <collection href="media.atom" files:path="media\" svc:annotationsOn="false" svc:ratingsOn="false" svc:syndicationOn="false" svc:visible="false">
          <atom:title>Media</atom:title>
          <atom:id>tag:atomsite.net,2008:media</atom:id>
          <accept files:ext="png">image/png</accept>
          <accept files:ext="jpg">image/jpeg</accept>
          <accept files:ext="gif">image/gif</accept>
        </collection>
      </workspace>
      <svc:page width="doc4" template="yui-t2">
        <svc:area name="head">
          <svc:include name="OpenSearchHeaderLink" />
        </svc:area>
        <svc:area name="nav">
          <svc:include name="MenuCustomWidget">
            <svc:item href="/" text="Home" />
            <svc:item href="/code" text="Code" />
            <svc:item href="/blog" text="Dev Blog" />
            <svc:item href="http://getsatisfaction.com/PoshCode/products/PoshCode_poshcodeorg_20" text="Feedback" />
          </svc:include>
          <svc:include name="OpenSearchWidget" />
          <svc:include name="AccountStatusWidget" />
        </svc:area>
        <svc:area name="foot">
          <svc:include name="AccountStatusWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AccountLogin">
        <svc:area name="content">
          <svc:include name="OpenIdLoginWidget" />
          <svc:include name="LiveIdLoginWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AtomPubResource">
        <svc:area name="content">
          <svc:include name="AnnotateListWidget" />
        </svc:area>
      </svc:page>
      <svc:page name="AdminDashboard">
        <svc:area name="dashboardLeft">
          <svc:include name="AdminRightNowWidget" />
          <svc:include name="AdminRecentAnnotationsWidget" />
        </svc:area>
        <svc:area name="dashboardRight">
          <svc:include name="AdminQuickPubWidget" />
          <svc:include name="AdminPendingEntriesWidget" />
        </svc:area>
      </svc:page>
      <svc:widget name="BlogAddCommentWidget">
        <svc:area name="commentator">
          <svc:include name="OpenIdModalWidget" />
        </svc:area>
      </svc:widget>
      <svc:roleMatrix>
        <!-- AtomPub Actions-->
        <svc:roleAction name="GetServiceDoc" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="UpdateServiceDoc" admin="True" author="True" contrib="False" user="False" anon="False" />
        <svc:roleAction name="GetCollectionFeed" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="CreateEntryOrMedia" admin="True" author="True" contrib="False" user="False" anon="False" />
        <svc:roleAction name="GetEntryOrMedia" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="UpdateEntryOrMedia" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="DeleteEntryOrMedia" admin="True" author="True" contrib="False" user="False" anon="False" />
        <svc:roleAction name="PeekEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="True" />
        <!-- Additional Actions -->
        <svc:roleAction name="GetFeed" admin="True" author="True" contrib="True" user="True" anon="True" />
        <svc:roleAction name="GetAnnotations" admin="True" author="True" contrib="True" user="True" anon="True" />
        <svc:roleAction name="Annotate" admin="True" author="True" contrib="True" user="True" anon="True" />
        <svc:roleAction name="ApproveEntryOrMedia" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="ApproveAnnotation" admin="True" author="True" contrib="True" user="False" anon="False" />
        <svc:roleAction name="AddCategory" admin="True" author="True" contrib="True" user="True" anon="False" />
        <svc:roleAction name="RemoveCategory" admin="True" author="True" contrib="True" user="True" anon="False" />
        <svc:roleAction name="RateEntryOrMedia" admin="True" author="True" contrib="True" user="True" anon="False" />
      </svc:roleMatrix>
    </service>
    
    Posted by JarrettV on August 06 at 7:31 PM

  6. Asset Combination

    Asset combination reduces the number of requests made to download a page resulting in faster load times. Also, with smart caching techniques, less data is transferred on subsequent requests.  Assets can be better organized into functional groups for smart asset combination requests.  The development experience is simplified due to improvements in organizing assets.  For example, widgets/pages can have their own stylesheet and javascript files making things easier to manage and locate.

    Caching

    For performance reasons, these files are marked with a far-future cache expiration as recommended by YUI Slow.  However, if a user installs a plugin (i.e. adds new script or styles to the combination) we need a way to tell the browser there is a new js/css file to download rather than using the cached version.  AtomSite is able to use an MD5 hash of the combined script/css file to ensure the file is re-downloaded.

    For example:
    <link rel='stylesheet' type='text/css' href='/css/combined/admin.css?v=881BC213842E88672045FA63BA6CD055' />

    AtomSite also uses the MD5 hash for the ETag so that smart browsers only re-download when any of the scripts within the combined group changes.

    Grouping

    Assets can be organized into groups depending on when or where they are displayed.  The master view controls the groups loaded when as a content view is rendered.  For example, the default group is the "site" group and it is requested from the Site.master view.  Another major group is the "admin" group which is requested from the Admin.master view.

    AssetGroupingAssets2

    The master view will request assets that it needs to work.  Also, each content view may have additional assets that they require.  Further, since each view can be composited with widgets, those individual widgets may require additional assets. 

    The idea behind grouping is that there are certain functional areas of a website that will reuse or share assets.  For example, CS.2 is shared between two widgets.  Another content page will likely reuse the same widgets.

    By grouping and combining assets, we can minimize the number of asset requests across similar functional areas of a website.

    AssetGroupingDisabled

    When group combining is disabled, there will be one request to the server for each unique asset.

    AssetGroupingCombine

    When group combine is enabled, there are far fewer requests.  Notice that non-grouped , or global assets (such as framework assets like jQuery) are not combined.  These assets are usually part of a CDN.

    AssetGroupingCombineAndMinify

    Furthermore, we can reduce the download size of the combined assets by minification.  We use Yahoo! UI Library: YUI Compressor for .Net to minify both javascript and css.

    Development

    Assets should be included into a group based on their usage in a functional area of the application. Pages and widgets are responsible for registering their assets in groups as needed.  The groups are requested by the master view through the underlying PageModel.

    Lets say you develop a new forum plugin.  It would make sense to have a new asset group called "forum" that all the pages and widgets register their assets in.  This allows for a large functional area (like a forum) to download all the combined assets in one request when a user loads a any forum page.

    Please see the Admin plugin for an example of how asset grouping is used in a functional area.

    Settings

    You can disable this feature in the web.config application settings. Also, you can control whether the combined scripts get minified. These settings make it easier to debug during development.

    Disabled
    CSS and Javascript files are not combined and will be included individually as link or script tags.
    Combine
    The CSS/JS files are combined based on the group they are registered with. Note: only widget assets that are included get combined.
    CombineAndMinify (default)
    Same as above but the assets also get minified using the YUI minification library.
    Posted by JarrettV on August 04 at 6:07 PM

  7. Search Widget

    The search widget provided by the blog plugin was built to be flexible enough to search at any scope within the system.  You can specify the scope when you include the widget.  There are three possible values for the scope:

    Scope Description
    site Searches all collections in all workspaces
    workspace (default) Searches all collections in the current workspace
    collection Searches only in the current collection

    Below is an example of how to include the search widget in the content area of the home page.  The widget will search the entire site.

    <svc:page name="BlogHome">
      <svc:area name="content">
        <svc:include name="BlogSearchWidget">
          <svc:scope>site</svc:scope>
        </svc:include>
      </svc:area>
    </svc:page>
    

    Configure in AtomSite Manager new

    Now you can easily choose the scope in the AtomSite manager.  Just browse to the area where you have the search widget and choose configure.

    BlogSearchWidget

    And you'll get a nice choose a scope dialog.

    SelectScope

    When searching at the collection scope, the search box will post to an address like:
    http://example.com/{collection}/search.xhtml?term=

    In single workspace mode, the search at service scope and workspace scope post to the same address:
    http://example.com/search.xhtml?term=

    In multi-folder workspace mode, the search will post to the following addresses for service, workspace, and collection scopes:
    http://example.com/search.xhtml?term=
    http://example.com/{workspace}/search.xhtml?term=
    http://example.com/{workspace}/{collection}/search.xhtml?term=

    Posted by JarrettV on July 22 at 10:18 PM

  8. Themes

    1. Overview
    2. Themes Location
    3. Cascading Theme
    4. Changing Theme
    5. Default Theme Layout
    6. Content and Include Areas
    7. Page Widths and Column Templates
    8. Changing Includes
    9. Writing a Basic Theme
    10. Advanced Themes

    Overview

    AtomSite has a very flexible theme system.  A theme is just a collection of assets dropped into the various asset theme folders.  You can control which theme is used at either the workspace or collection level.  The default theme contains standard content and include areas.  You can easily control what is included in these areas.  You can create a basic theme, that just includes a CSS stylesheet or you can do advanced modifications to the markup for the master page, individual pages, and even individual controls or widgets.

    Through the use of YUI Grids and the widget include system, there is a significant amount of modification possible without having to modify the default markup.  In fact, this whole site you're looking at http://atomsite.net is itself a simple theme that is just a CSS file and some images on top of what is provided out of the box.

    Theme Asset Locations

    Themes are stored in the varioius asset directories in the root of your application.  Each theme has its own directory that shares the name of the theme. For example, two very basic themes; "blue", "hibiscus":

    Theme Name Asset Type Location
    blue CSS /css/blue/blue.css
    Image /img/blue/bg.jpg
    View /themes/blue/BlogEntry.aspx
    Javascript /js/blue/BlogEntry.js
    hibiscus CSS /css/hibiscus/hibiscus.css
    Image /img/hibiscus/flower.png
    View /themes/blue/BlogComment.ascx

    For basic themes, the name of the stylesheet should match the name of the theme.

    Cascading Theme

    Themes can be built on top of the default theme.  The default theme contains all the files needed for displaying a website.  To simplify theme development, a designer does not need to re-invent these files for a new theme.  Therefore, if a required file is not provided by a theme, it will automatically fall-back and use a file from the default theme.  For example, a basic theme that only provides a CSS file and some image files will always fall-back to the default theme for how the markup is rendered.

    Changing Themes

    Themes can be controlled at two different scopes: workspace and collection.  Changing a theme at the workspace level will apply the theme to all collections within that workspace.  However, if you specify a different theme at the collection level, it will override the theme set at the workspace level.

    Setting a theme at the workspace level

    TODO: post image of service.config file here

    Setting a theme at the collection level

    TODO: post image of service.config file here

     

    Default Theme Layout

    The following diagram shows the default layout within the Site.Master file.  Please note the usage of YUI Grids layout.  This allows the side column to appear on either the left or the right. The built-in flexibility in this layout should support a large percentage of all common site layouts.

    Theme Layout

    Content and Include Areas

    In the above Site.Master Layout diagram, the areas marked with [icon] are content areas.  The areas marked with [icon] are include areas (for widgets).

    Content Areas

    More details coming soon

    Include Areas

    More details coming soon

     

    Page Widths and Column Templates

    The PageWidth can be controlled for each individual page at any scope.  Also, the column width can be controlled by using the PageTemplate (also at any scope).

    YUI Page Widths
    doc
    750px centered (good for 800x600)
    doc-2
    950px centered (good for 1024x768)
    doc-3
    100% fluid (good for everybody)
    doc-4
    974px fluid (good for 1024x768)
    doc-custom
    custom page width (set in CSS)
    YUI Column Templates
    yui-t1
    160px side column on left
    yui-t2
    180px side column on left
    yui-t3
    300px side column on left
    yui-t4
    180px side column on right
    yui-t5
    240px side column on right
    yui-t6
    300px side column on right

    Changing Includes

    Changing Page Includes

    More details coming soon

    Changing Widget Area Includes

    More details coming soon

    Writing a Basic Theme

    Starting with blank slate, CSS, images

    No markup changes, just CSS and YUI doc width or template changes

    Finally, you can theme individual Page views using an #id selector in your CSS as the body tag always has the id of the PageName.

    More details coming soon

     

    Writing an Advanced Theme

    Custom markup, with custom full site layouts and CSS and YUI doc widths

    Altering Site.Master, page markup, widget markup, etc.

    Creating new Content areas

    Creating new Include areas

    Cons of Advanced Themes, Compatibility, Upgradability, non-standard include areas

    More details coming soon

    Posted by JarrettV on March 25 at 1:38 PM

  9. Known Issues

    Release 1.0

    • Wizard does not trim whitespace off of the name when filling out the basic settings

     

    Release 0.9

    • Install to virtual folder (sub-folder) will result in 401 and/or 404 errors in Live Writer
      • add slash onto end of base address in service.config file, xml:base="http://localhost/AtomSiteDemo/">
    • Login path is incorrect in web.config and may cause problems with failed logins or OpenId logins

      <forms loginUrl="~/Login.xhtml"/>

      should say

      <forms loginUrl="~/Account/Login"/>

    Posted by JarrettV on March 24 at 8:40 AM

  10. Annotations and Comments

    Overview

    AtomSite has full featured support for annotations (also known as comments). Annotations can be turned on/off at the collection level or individual entry level. You can require annotations to be approved before they are visible. AtomSite is built to support paging and threading of annotations. AtomSite supports annotations in accordance with Atom Threading Extension.

    Control

    AtomSite supports multiple methods for controlling if an entry supports annotations. The first method is by modifying the configuration setting called annotationsOn on the collection.

    annotationsOn
    true = annotations are on
    false = annotations are off

    You can gain granular control over who is allowed to annotate by changing the role matrix at either the service, workspace or collection level. As shown below, the default role matrix allows anyone to annotate.

    <svc:roleAction name='Annotate' admin='True' author='True' contrib='True' user='True' anon='True'/>
    

    You can also control annotations at the entry level by the allowAnnotate setting on each entry.

    Finally, annotations can be controlled by an expiration date set by the annotateDaysOpen setting.* Annotations on an entry will appear closed after X number of days past the published date.

    Approvals

    When an annotation is created, the annotation may be automatically approved depending on their role. As seen below in the default role matrix, users and anonymous users comments must be approved by an administrator, author, or contributor.

    <svc:roleAction name='ApproveAnnotation' admin='True' author='True' contrib='True' user='False' anon='False'/>
    

    Annotations that have not been approved will only show to authorized users. The unapproved annotations will show up as red. When the annotation is successfully approved, it fades to green (via jQuery). The website supports approving individual annotations or all annotations at the same time.

    Paging

    AtomSite was designed to support paging comments. This is valuable when an entry has too many annotations that may slow the page down. The backend and service layer already support paging.  In the future, a theme will be available that supports this paging on the front-end.

    Threading

    As mentioned earlier, annotations are created by posting an entry to any existing entry. Since every annotation is an entry, this allows you to thread the entries. In the blogosphere, this is known as nested comments.

    The backend does support threading comments. However, there is not yet first class support for this on the front-end. It is scheduled for a future release.

    Technical

    AtomSite supports new annotations by posting an entry to the address of any existing entry. The user's browser talks directly to the service using an ajax request.

    POST /blog/2008/08/24/BlogSvcNowSupportsComments.atom HTTP/1.1
    x-requested-with: XMLHttpRequest
    Accept-Language: en-us
    Referer: http://atomsite.net/blog/2008/08/24/BlogSvcNowSupportsComments.xhtml
    Accept: application/xml, text/xml, */*
    Content-Type: application/atom+xml;type=entry
    UA-CPU: AMD64
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Win64; x64;
    .NET CLR 2.0.50727; SLCC1; .NET CLR 3.5.21022; .NET CLR 3.5.30428; .NET CLR 3.5.30729)
    Host: blogsvc.net
    Content-Length: 196
    Connection: Keep-Alive
    Pragma: no-cache
    Cookie: ASP.NET_SessionId=fr1fix55vfyqiivzypp05b55
    
    <entry xmlns='http://www.w3.org/2005/Atom'>
      <title>Comment</title>
      <author>
        <name>Test</name>
        <email>test@test.com</email>
        <uri>http://test.com</uri>
      </author>
      <content type='html'>Test</content>
    </entry>
    
    HTTP/1.1 201 Created
    Cache-Control: private
    Content-Type: text/plain
    Location: http://atomsite.net/blog/2008/08/24/BlogSvcNowSupportsComments/Comment.atom
    Server: Microsoft-IIS/7.0
    X-AspNet-Version: 2.0.50727
    X-Powered-By: ASP.NET
    Date: Sun, 24 Aug 2008 20:47:19 GMT
    Content-Length: 67
    
    ..snip..
    

    The response will now contain a cookie to remember anonymous user details. If the request is from an AJAX call it will return the html to add the web page, otherwise it will return the Atom entry.

    $.ajax({
      type: "POST",
      url: "<%= AnnotationHref %>",
      data: "<entry xmlns='http://www.w3.org/2005/Atom'>
          <title>Comment</title>
          <author>
            <name>" + parse($('#txtName').val()) + "</name>
            <email>" + encodeURI($('#txtEmail').val()) + "</email>
            <uri>" + encodeURI($('#txtWebsite').val()) + "</uri>
          </author>
          <content type='html'>" + parse($('#txtComment').val()) + "</content>
        </entry>",
      contentType: "application/atom+xml;type=entry",
      dataType: "xml",
      complete: function(req) {
        if (req.status == 201) {
          reset();
          $.ajax({
            url: "/blog/<some entry>.atom" + req.responseText,
            success: function(html) {
              $(html).hide().appendTo("#annotations").addClass("annotationSelf").fadeIn("slow");
            }
          });
        } else {
          alert('Failed to post comment: ' + req.statusText);
        }
      }
    });
    

    *This feature will be available in future version.

    Posted by JarrettV on March 21 at 3:46 PM

© Copyright 2013 Powered by AtomSite 1.4.0.0