Information - Browsing Technical
-
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)
The default logging setup uses the default log listener.
Recommended Logging Setup (web.config)
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.
-
TODO List
FIXED
Unapprove link doesn't work in Manager for non-blog collections
DONEAdd Edit User support
DONEInstalled, Online, Upload filter on Themes
DONEUpdate Users page in Manager
ADDED Role Manager, need to add modify, inherit, scope supportBetter theme thumbnails
DONEAdd upload theme support
DONEDelete theme
Clone themeChange site when (new collection/workspace)
FIXEDFix href when new collection created
Delete workspace and delete collection in ManagerShow not implemented on non-finished links
DONE
Widget scoping, asset group, master page, areas improvements, additional descriptionsWidget configuration popups, individualized per widget
Widget area hints
Widget page hints
Widget include scope filteringAdd context specification upon including widgetsFIXED
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
DONEDelete userBetter user names when logging in with google OpenId
DONE
Update counts for items, authors, contributors in workspace, collection settings
Fixsupport for multi-folder, multi-subdomin, add new multi-domain in AtomSite ManagerUpdate more of the code to properly use ModelBinders
CDN Manager and setting
-
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.
In the next part, we will look at adding configuration settings for this plugin to the AtomSite Manager.
-
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>
-
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"><li><a href="#blogSettings">Blog Settings</a></li></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"> <link rel="openid.server" href="http://www.myopenid.com/server" /> <link rel="openid.delegate" href="http://jarrettv.myopenid.com/" /> </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"><li><a href="#blogSettings">Blog Settings</a></li></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>
-
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.
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.
When group combining is disabled, there will be one request to the server for each unique asset.
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.
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.
-
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.
And you'll get a nice choose a scope dialog.
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=
-
Themes
- Overview
- Themes Location
- Cascading Theme
- Changing Theme
- Default Theme Layout
- Content and Include Areas
- Page Widths and Column Templates
- Changing Includes
- Writing a Basic Theme
- 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.
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
-
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"/>
-
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.