Summary: The KartonesNet CS2007 Addon Pack 1.3.3 includes refactored TwitterAutoPostingAddon and UserTwitterAccountPostingAddon modules, and a new experimental url-shortening service.
In my last release of this Community Server 2007 pack I added a lightweight list of all posts, but it wasn't the only optimization I had in mind to do small speed increases on blog page loads. Two new controls I've just finished are a readonly tag list, and a "visual tag" list, which I'll explain in detail.
WeblogPostTagList
This control is just a simplified, readonly version of the default one that CS2007 ships. I have stripped down all javascript the inline tag editor uses and all related functionality, creating a smaller and faster one that just renders the list of tags/categories of a post (or a post list, just like the normal tag list did).
Features:
The syntax is almost the same as with the CS one:, with the addition of the new property:
<KartonesNet:WeblogPostTagList runat="server" TagListPrefixLiteral="Tags: " Tag="Div" CssClass="em" />
For example this blog now uses it.
WeblogPostVisualTagList
This control uses the previous one as the base, but what it does is, instead of rendering text tags, renders images based on lowercasing and replacing spaces by underscores of the tag name (for example "XBox 360" would become "xbox_360.xxx".
Features:
Example of how to use it:
<KartonesNet:WeblogPostVisualTagList runat="server" Tag="Div" CssClass="em"
TagImagesURL="https://kartones.net/" ImagesExtension="png"
TagListPrefixLiteral="<b>Tags</b>: "
TagAliases="360,xbox360=XBox 360;wii=Nintendo Wii" />
And a real example of how it looks:
This all happened because compressing ASP.NET and CS Javascripts is no easy task, and in order to do it you have to use ASP.NET AJAX (which I didn't wanted to use either). But my battle of speeding up this blog as much as possible is still ongoing (I want to do one additional task :)
I've just released the 1.3.1 version of my Community Server 2007 addon pack.
Small incremental release because I only added a small new component, AllWeblogPostsList, which doesn't uses paging and has a few internal optimizations to retrieve all blog posts from a given blog (the one in which you place it).
I made it because I wanted to have a full one-page post archive without additional uneeded stuff for one of our blogs.
Using it is fairly easy (read the included txt), just like the normal blog post archive from CS2007 (and allowing any formatting you want):
<KartonesNet:AllWeblogPostsList id="EntryItems" Runat="server">
<HeaderTemplate><ul></HeaderTemplate>
<ItemTemplate>
<CSBlog:WeblogPostData ID="WeblogPostData" runat="server" Property="Subject" LinkTo="Post" Tag="li" />
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</KartonesNet:AllWeblogPostsList>
I'm taking small vacations in a few days so more small things that I have in mind related to Kartones.Net and Community Server 2007 will have to wait. Until then, may the force of C# be with you!
Update: Fixed a small error in the example, inside the <ul> should be only <li> elements, doh! (>_<)
This weekend, in my spare time, I've finally achieved one thing I wanted since some time: Fully automating the Site Stats of Kartones.Net.
Previously, I had to manually update the page with the current data each month, plus exporting some Google Analytics reports in PDF. As computers are supposed to exist to make our lives easier (although for developers is more of the opposite actualy :), I decided to use the Google Analytics Data Export API (which as usual uses GData for retrieval of the information) and ASP.NET Chart Controls to create an automated and live stats page.
As I had in mind publishing the class under my KartonesNet CS2007 Addon Pack, I've made some things in the code specifically to make it more customizable by anyone. But let's get into how I've made it and how it works...
Without entering into details of how GData works, as usual working with it when being authenticated we will make http request to specific urls and retrieve XML contents (in which we will have a list of <entry> elements). The requests have this format:
https://www.google.com/analytics/feeds/data?ids=ga:_ProfileID_&dimensions=_Dimensions_&metrics=_Metrics_&sort=_OrderBy_&start-date=_StartDate_&end-date=_EndDate_&prettyprint=true&max-results=_MaxResults_
As we can see, the first parameter is a Profile ID, obtained after authentication. My API supports only ClientLogin
(user & password, as usual *), but there are other methods. After authentication, we will receive an authorization token, which we will need to always specify in the headers of our Http Requests:
request.Headers.Add("Authorization: GoogleLogin auth=" + sessionToken);
The profile ID represents the "site" we want to get data about. If you don't know the profile ID of your site, or only have one, don't bother with it, if you call the API Login() method without ProfileID, it will get the first available one.
Login with the API can't be easier:
GoogleAnalyticsAPI googleAnalytics = new GoogleAnalyticsAPI();
bool loginSuccess = googleAnalytics.Login(user, password);
if (loginSuccess)
{
...
After authentication, we can make GData requests to gather data, by specifying dimensions and metrics. As the documentation is pretty self-explaining I won't enter into details, just mentioning that it is important to check the valid combinations of them because you can have errors with given combinations.
I have recreated for Kartones.Net some basic reports, like visits/pageviews, visitor OS, browser and language config, or a ‘Top 20 content pages'. There is a lot of room for imagination here, specially if you perform operations with the returned data.
The API calls are very simple:
public string GADataCall(string[] Dimensions, string[] Metrics, string OrderBy);
I have not made enumerations for dimensions/metrics just in case Google extends it (and because they are a lot and I only needed a few for my reports), and the OrderBy parameter can be set to null/string.Empty if you don't want ordering.
Note: To specify a descending order, prepend a minus to the field, e.g.: -ga:pageviews
A few important things about the API calls to gather data:
One thing I wanted is to allow customization of the results while keeping them small and light. My scenario was the web, but even in there I needed more than only "table formatting" with <tr> and <td>, so I created this small interface:
namespace KartonesNet.APIs
{
/// <summary>
/// Interface for implementing a Google Analytics data formatter
/// </summary>
public interface IGoogleAnalyticsDataFormatter
{
/// <summary>
/// Tag to inject before each element
/// </summary>
/// <returns>Tag</returns>
string PreElementTag();
/// <summary>
/// Tag to inject before each field of an element
/// </summary>
/// <returns>Tag</returns>
string PreFieldTag();
/// <summary>
/// Tag to inject after each field of an element
/// </summary>
/// <returns>Tag</returns>
string PostFieldTag();
/// <summary>
/// Tag to inject after each element
/// </summary>
/// <returns>Tag</returns>
string PostElementTag();
}
}
Very simple and customizable (you can simply return string.Empty on those values you don't want to use). I provide three DataFormatters with the API:
This is an example call that uses all stuff (not much anyway):
googleAnalytics.DataFormatter = new GoogleAnalyticsTableDataFormatter();
googleAnalytics.MaxResults = 12;
osGAData = googleAnalytics.GADataCall(
new string[] { "ga:operatingSystem" },
new string[] { "ga:pageviews" },
"-ga:pageviews");
And not much else to add... Plugging the gathered data into the ASP.NET Charting Control as usual took more time for visual setup than for logic itself but was really easy, and as it has caching too, the resulting stats page loads pretty fast on subsequent calls (and not slow on the first one).
Here is a screenshot of how all this looks once finished:
All that remains is grabbing the component and making your own reports!
I hope the API proves useful, feel free to drop a comment with suggestions, problems or just thoughts about it :)
I've just updated my Community Server 2007 addon pack to add support for Slideshare presentations. The name of the component has changed to from GDocsSlideshowAddon to SlideshowsAddon so remember to update your CommunityServer.config file reflecting the change.