Monday, December 18, 2006
PhotoSynth Technology Preview
Friday, December 15, 2006
Visual Studio 2005 SP1
ASP.NET 2.0 AJAX Extensions RC1
another year passed
so, this post is really about 2 weeks old, but i thought i'd write it anyway.
I found myself thinking about the last couple of years that passed by, and it struck me like a blow to the head: this year has been fantastic!
The last year included:- working for metamatrix // interfolio
- working with sitecore cms (which you all by now know i love)
- went to tech ed in barcelona
- living in stockholm
- drinking beer
- playing music
- stopped smoking
- started going to the gym (if you knew me a year ago you'd be laughing right about now)
- bought an apartment
- bought a car
- started this blog
- found what i was hoping i'd find in a company that develop top-of-the-line solutions
Now, for those of you that don't know me personally, let's just compare this year to some previous:
1 year ago i was..
- living in stockholm
- working for morningstar
- drinking beer
- smoking cigarettes
- playing music
2 years ago i was..
- living in london
- working for morningstar
- drinking beer
- smoking cigarettes
- playing music
3 years ago i was..
- living in london
- working for morningstar
- drinking beer
- smoking cigarettes
- playing music
4 years ago i was..
- living in stockholm
- working for morningstar
- drinking beer
- smoking cigarettes
- playing music
see a repetative pattern evolving here? well, for the first time that pattern is gone, completely (ok, so not -really- completely, i still like my beers, stockholm and my music).
morningstar was great working for, don't get me wrong, and london was a fantastic city to live in. the friends i have there i'll keep for life, without doubt. the thing that separates those years from today is that today i'm loving it. 100% loving it.
and yeah, it's true: i'm going to the gym these days and yeah, it's true: i've stopped smoking (so far anyway)
time sure flies..
i'm -so- looking forward to another great year!
P.
Extending the RSS Module
public static void GetRssUrls() { Item root = Sitecore.Context.Item; System.Text.StringBuilder sb = new System.Text.StringBuilder(); if (root != null) { if (root.Fields["Rss_Feeds"]!=null) { Sitecore.Data.Fields.MultilistField mf = root.Fields["Rss_Feeds"]; if (mf != null) { if (mf.Count > 0) { foreach (Item itm in mf.GetItems()) { sb.AppendLine("<link rel=\"alternate\" type=\"application/rss+xml\" title=\"" + itm.Fields["Title"].Value.ToString() + "\" href=\"" + itm.Paths.GetFriendlyUrl() + "\" />"); } } } Sitecore.Context.Page.Page.Header.Controls.Add(new LiteralControl(sb.ToString())); } } }4) add the following code to your Page_Load event
that's it. now compatible browsers will 'light up' all shiny and stuff when you select a feed that will be available on a page - ain't that great for christmas? finally, wrapping up, Alex de Groot just posted his 1-year-blogging-anniversary post. Congratulations! today is friday - today is afterwork - today is gonna be one more day that i forget to go buy gifts.. but hey, at least it's friday.. take care, P.protected void Page_Load(object sender, EventArgs e) { RssAlternativeRenderer.GetRssUrls(); }
Wednesday, December 13, 2006
10 steps to adding search providers to a sitecore website using OpenSearch specifications
yep, 10 steps to adding search providers to a sitecore website using OpenSearch specifications. ok, so there's a lot of sub-steps and some code, but at least the highlighted parts are only 10 :) here we go!
1) create a new layout called OpenSearch
2) create a new template called OpenSearchSource 2.1) add the following fields to this template 2.1.1) OpenSearchDescription : text 2.1.2) ShortName : text 2.1.3) LongName : text 2.1.4) Description : text 2.1.5) Tags : text 2.1.6) Contact : text 2.1.7) URL_RSS : text 2.1.8) URL_Atom : text 2.1.9) URL_HTTP : text 2.1.10) Attribution : text 2.1.11) Language: text 2.1.12) AdultContent : checkbox 2.1.13) inputEncoding : text 2.1.14) outputEncoding : text 2.1.15) count : text 2.1.16) Icon_Large : text 2.1.17) Icon_Small : text 2.2) set the standard values of the fields accordingly (without the qoutes): 2.2.1) OpenSearchDescription : "http://a9.com/-/spec/opensearch/1.1/" 2.2.2) ShortName : "MyExample" (set your site name or something) 2.2.3) LongName : "Search using MyExample Search" (just a more detailed name) 2.2.4) Description : "Use our own search engine to search our site" 2.2.5) Tags : "example web" 2.2.6) Contact : "peter@interfolio.se" (your email would be better) 2.2.7) URL_RSS : "http://www.interfolio.se/search.aspx?q={searchTerms}&view=rss" (set this to the result querystring of your rss search page (if any) and add the {searchTerms} to the query param, or leave empty) 2.2.8) URL_Atom : "http://www.interfolio.se/search.aspx?q={searchTerms}&view=atom" (set this to the result querystring of your atom search page (if any) and add the {searchTerms} to the query param, or leave empty) 2.2.9) URL_HTTP : "http://www.interfolio.se/search.aspx?q={searchTerms"} (set this to the result querystring of your search page and add the {searchTerms} to the query param) 2.2.10) Attribution : "Copyright 2006, Peter Johansson, All Rights Reserved." 2.2.11) Language: "*" (can be set to a desired language, like sv-SE) 2.2.12) AdultContent : unchecked :) 2.2.13) inputEncoding : "UTF-8" 2.2.14) outputEncoding : "UTF-8" 2.2.15) count : 10 2.2.16) Icon_Large : "http://www.interfolio.se/images/find.png" (or leave blank to show no icon) 2.2.17) Icon_Small : "http://www.interfolio.se/images/find.png" (or leave blank to show no icon) 2.3) create a master for the newly created template
3) add a folder where you'll store your OpenSearch specification items (perhaps /sitecore/content/global/OpenSearch) 3.1) assing the master created in 2.4 to the newly created folder 3.2) assing the layout we created at step 1 to the standard values of our OpenSearchSource template
4) add a dummy specification item that we can change later, i'm naming mine OpenSearchExample, but you can name it what you want.
5) here you can approach it from many angles, but since this is my tutorial we're gonna look at it my way :), 5.1) create a template that your site-specific templates will inherit from (make sure it inherits Standard template), maybe even name it SitewideSettings like i'm doing. 5.2) add a Tree list field to that template, name it OpenSearch_Sources and specify it's source to be your newly created folder at step 3, and finally check the shared checkbox. 5.3) make your site-specific templates inherit from the SitewideSettings template created at step 4.1.
6) edit an item (or create a new one) and select the dummy item we created at step 4 in the OpenSearch_Sources tree list
7) commit a full publish
That's it for sitecore desktop stuff.. for now.. next up, let's change the OpenSearch layout file.
8) Create a new class called OpenSearchPage 8.1) Set the Inherits attribute of the layout to the newly created class, like Inherits="OpenSearch.OpenSearchPage" 8.2) make the new class inherit from the standard Page class 8.3) override the OnLoad event 8.4) create code to output our OpenSearch specification. Instead of doing this the really fancy way i'll just show a really simple way to output it. What should really be done is to make use of an xmltextwriter and an actual xml document to make sure the output is nice all follows standards, but to save time i've simply sent the format straight to the page and made sure the ContentType is text/xml. to make this better, go ahead and change all this, it should be made better so if you use any of this think about that :) anyway, here's really all of the code needed for (the not-so-correct-way-of) returning the output:
public class OpenSearchPage : Page { protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (Sitecore.Context.Item != null) { this.Context.Response.Clear(); this.Context.Response.ContentType = "text/xml"; System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); sb.AppendLine("<OpenSearchDescription xmlns=\"" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["OpenSearchDescription"].Value, "") + "\">"); sb.AppendLine("<ShortName>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Shortname"].Value, "") + "</ShortName>"); sb.AppendLine("<Description>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Description"].Value, "") + "</Description>"); sb.AppendLine("<Tags>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Tags"].Value, "") + "</Tags>"); sb.AppendLine("<Contact>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Contact"].Value, "") + "</Contact>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_RSS"].Value, "") != "") sb.AppendLine("<Url type=\"application/rss+xml\" template=\"" + Server.HtmlEncode(Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_RSS"].Value)) + "\"/>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_Atom"].Value, "") != "") sb.AppendLine("<Url type=\"application/atom+xml\" template=\"" + Server.HtmlEncode(Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_Atom"].Value)) + "\"/>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_HTTP"].Value, "") != "") sb.AppendLine("<Url type=\"text/html\" method=\"get\" template=\"" + Server.HtmlEncode(Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["URL_HTTP"].Value)) + "\"/>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["LongName"].Value, "") != "") sb.AppendLine("<LongName>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["LongName"].Value) + "</LongName>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Icon_Large"].Value, "") != "") sb.AppendLine("<Image height=\"64\" width=\"64\" type=\"image/png\">" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Icon_Large"].Value) + "</Image>"); if (Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Icon_Small"].Value, "") != "") sb.AppendLine("<Image height=\"16\" width=\"16\" type=\"image/png\">" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Icon_Small"].Value) + "</Image>"); sb.AppendLine("<Attribution>"); sb.AppendLine(Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["Attribution"].Value, "Copyright, All rights reserved.")); sb.AppendLine("</Attribution>"); sb.AppendLine("<AdultContent>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["AdultContent"].Value, "false") + "</AdultContent>"); sb.AppendLine("<Language>" + Server.HtmlEncode(Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["language"].Value, "*")) + "</Language>"); sb.AppendLine("<OutputEncoding>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["outputEncoding"].Value, "UTF-8") + "</OutputEncoding>"); sb.AppendLine("<InputEncoding>" + Sitecore.StringUtil.GetString(Sitecore.Context.Item.Fields["inputEncoding"].Value, "UTF-8") + "</InputEncoding>"); sb.AppendLine("</OpenSearchDescription>"); this.Context.Response.Write(sb.ToString()); this.Context.Response.End(); } } }
9) add functionality to add content to the header. all we really need now is a way to tell the browser that there's a search provider available on the site, and here's a little code snippet for that as well
public class OpenSearchRenderer { public static void GetOpenSearchUrls() { Item root = Sitecore.Context.Item; System.Text.StringBuilder sb = new System.Text.StringBuilder(); if (root != null) { if (root.Fields["OpenSearch_Sources"] != null) { Sitecore.Data.Fields.MultilistField mf = root.Fields["OpenSearch_Sources"]; if (mf != null) { if (mf.Count > 0) { foreach (Item itm in mf.GetItems()) { sb.AppendLine("<link title=\"" + itm.Fields["ShortName"].Value.ToString() + "\" rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"http://localhost" + itm.Paths.GetFriendlyUrl() + "\">"); } } } Sitecore.Context.Page.Page.Header.Controls.Add(new LiteralControl(sb.ToString())); } } } }
10) output the header information. to finalize the entire thing and actually get the output to the page, all you have to do is add a call to the GetOpenSearchUrls method on the pages, so for example just add a call to it in the Page_Load event;
protected void Page_Load(object sender, EventArgs e) { OpenSearch.OpenSearchRenderer.GetOpenSearchUrls(); }
now, to wrap it all up you should have a working example of how to add OpenSearch information that will enable your site to 'tell' the browser there's one or more search providers available on your site, it should light up the down arrow to the right of the magnifying glass in the top-right search area part of your IE7 toolbar and if you expand it it should show your newly added search provider. you could also extend the definition of the xml output to include mozilla specific resources (like xmlns:moz="http://www.mozilla.org/2006/browser/search/") and even further extend the functionality in a lot of customized ways since OpenSearch has many ways to extend the specifications and results.
further reading: OpenSearch: http://www.opensearch.org/ OpenSearch Specifications 1.1: http://www.opensearch.org/Specifications/OpenSearch/1.1 Search Provider Extensibility in Internet Explorer 7: http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/external/overview/ie7_opensearch_ext.asp Adding Search providers to IE 7 using OpenSearch 1.1: http://blogs.msdn.com/ie/archive/2005/09/14/466186.aspx
well, i guess that's that. Sorry for the bad formatting, one of these days i'll actually change the design, but right now this will have to do. take care, P.
Tuesday, December 12, 2006
December 2006 Sandcastle CTP
Wednesday, December 06, 2006
XNA Game Studio Express Launch
Tuesday, December 05, 2006
ASP.NET 2.0 CSS Friendly Control Adapters 1.0
"WPF/E" CTP
Monday, December 04, 2006
The Panel
Friday, November 24, 2006
first 5.3 site launched
Tuesday, November 21, 2006
Making the Media Library F.O.B.A.R
Tuesday, November 14, 2006
Sitecore Certified Developer
Sunday, November 12, 2006
A new day dawning
Thursday, November 09, 2006
TechEd - All about the Experience!
Sitecore 5.3
Wednesday, November 08, 2006
TechEd: middle of day 2
Sunday, November 05, 2006
TechEd
Friday, October 27, 2006
waiting / writing
Saturday, October 21, 2006
Microsoft ASP.NET AJAX v1.0 Beta
Wednesday, October 18, 2006
IE7 roll-out
Monday, October 16, 2006
Annoying KB918899 issue resolved
Sneaky, sneaky..
Wednesday, October 11, 2006
Sitecore 5.3 & Vista RC2
- Make sure Vista is configured to recognize IIS6 actions/scripts etc. This can be done by checking the appropriate boxes under the IIS part of the "Turn Windows features on or off".
- Install .NET Framework 1.1 (and updates).
- Turn the UAP off (not sure if this really is needed, but that's what I did).
- Run the installer as administrator (right click the installer, "Run as Administrator").
For me it still crashes in the beginning with that InstallDriver Module error, but after that the installer runs (read "is now running" since i'm installing right now) smoothly..
UPDATE 2:
Well, the happiness of the first update was not kept alive for long. After the installation finished (which it did and that was nice) I'm now stuck at the next obstacle - When trying to access localhost all I got at first was an error message saying it couldn't read the config file and a wierd "Could not load all ISAPI filters for site". So, like every other time something goes wrong, I added Network Service and the other system roles to the website and it's content, allowing full access for ease of use. Voila, time to see the next error, and this one is regarding changes made to the handling of the actual web.config file itself. This part was a little more tricky since it's not at all that well documented..
Below is what i've done so far (and as of right now I'm not at all sure about this solution, maybe there's a best-practice way to go about all this, but since I haven't seen one yet I'll keep on trying).
- Create a system.webServer node
- Move HttpModules and HttpHandlers from system.web to system.webServer
- Rename HttpModules to modules
- Rename HttpHandlers to handlers
So far all I get is that it's missing a http handler and nothing will load, but perhaps I'll have it fixed soon..
UPDATE 3:
Well, this is a situation with IIS7 having two options to run the site in: "Classic .NET Mode" or "Integrated .NET mode", the later of the two is what they recommend for IIS7 and future versions. Fine, they want us to move up, that's alright. But right now I don't care, I just want it to run. So, if you want to try and load it into the Integrated .NET mode (which I'm trying to), keep thinking and comment, otherwise you can run a command in the command promt to switch it to Classic .NET mode.
%systemroot%\system32\inetsrv\appcmd.exe set app "SITENAMEHERE/" /applicationPool:"Classic .NET AppPool"
FINAL UPDATE:
When all else fails, admit you've probably done something stupid and save yourself the worry by simply scrapping the old installation and do a new one. Lesson learned.
Hope this will help you install it on Vista if you run across these problems as well.
Take care, P.Wednesday, September 27, 2006
Atlas Example
Right, down to business then: Sitecore and "Atlas".
"Atlas" is pretty much microsofts approach to AJAX and the hype surrounding it, so it's quite obvious that it was not going to go away but instead turn into a new part of the framework (see Scott Guthrie's blog on the matter at http://weblogs.asp.net/scottgu/archive/2006/09/11/_2200_Atlas_2200_-1.0-Naming-and-Roadmap.aspx)
Downloads:
- "Atlas": http://go.microsoft.com/fwlink/?LinkId=52384
- "Atlas" Control Toolkit: http://atlas.asp.net/atlastoolkit
- Install "Atlas" (make sure the checkboxes are ticked to also install Visual Studio project template and to register the .asbx extension in IIS).
- Copy the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll) from its installation folder to your site's Bin folder.
- Open the Web.config file
- Add these elements as children to the <configuration> element <configSections> <sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup"> <section name="converters" type="Microsoft.Web.Configuration.ConvertersSection"/> </sectionGroup> </configSections> <microsoft.web> <converters> <add type="Microsoft.Web.Script.Serialization.Converters.DataSetConverter"/> <add type="Microsoft.Web.Script.Serialization.Converters.DataRowConverter"/> <add type="Microsoft.Web.Script.Serialization.Converters.DataTableConverter"/> </converters> </microsoft.web>
- Add/Integrate these elements as children to the <system.web> element <pages> <controls> <add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/> <add namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/> </controls> </pages> <!-- ASMX is mapped to a new handler so that proxy javascripts can also be served. --> <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" type="Microsoft.Web.Services.ScriptHandlerFactory" validate="false"/> </httpHandlers> <httpModules> <add name="ScriptModule" type="Microsoft.Web.Services.ScriptModule"/> </httpModules>
- Save the Web.config file.
- Add a reference to the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll).
- (Optional) You can now also add "Atlas" to the Toolbox in Visual Studio. Right click the Toolbox, chose "add tab", name it, then right click, "choose items..", and browse to the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll).
Phew! Ok, that's about it for the installation and messing with a already existing site, now on to the fun stuff.
If you've never tried it before you're going to have fun, "Atlas" is neat and easy to use (note tho that it's still not a full release, so if it for whatever reason does crash, well, sorry, not much to do then but to re-install it).
1: Adding a ScriptManager
Add this to the page you want to enable "Atlas" on.
<atlas:ScriptManager ID="MyScriptManager" runat="server" EnablePartialRendering="true"> <ErrorTemplate> <div style="width: 450px; height: 300px; padding: 10px; border: solid 1px black; background: gray; text-align: left;"> <h1>Site error detected</h1> <p>An unhandled exception with the following message has occured on the server:</p> <p><span id="Span1" runat="server"></span></p> <p>We're sorry for any trouble this has caused you and will fix the problem as soon as possible.</p> <p><input id="Button1" type="button" value="OK" runat="server"/></p> </div> </ErrorTemplate> </atlas:ScriptManager>
Play around with it, you'll find more things to use i'm sure.
2: Adding a UpdatePanel
An UpdatePanel is pretty much a content-wrapper that will allow you to reload parts of the page (AJAX styled content refreshing instead of reloading an entire page) so let's look at that one. First up, we need to wrap our area with the tags.
<atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <div id="Div1"> </div> </ContentTemplate> </atlas:UpdatePanel> Now, let's add a nice looking UpdateProgress as well to show that something's going on when it loads
<atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <div id="Div1"> <atlas:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> <div id="Div2"> <asp:Image ID="Image2" runat="server" ImageUrl="/images/loading2.gif" GenerateEmptyAlternateText="True" AlternateText="Loading.." /> </div> </ProgressTemplate> </atlas:UpdateProgress> </div> </ContentTemplate> </atlas:UpdatePanel> 3: Refreshing the content
It's nice to have the possibility to update content on the page, but unless we actually activate it there's no point, so let's add an automated update of the content using a TimerControl.
<atlas:TimerControl ID="tcExample" runat="server" Interval="10000" Enabled="true" OnTick="tcExample_Tick"> </atlas:TimerControl> Next we need to add the tick event to the UpdatePanel so that it knows when to update itself. This is done using a Trigger that we'll connect to the Tick event of the newly created TimerControl. Add the following code within the UpdatePanel section:
<Triggers> <atlas:ControlEventTrigger ControlID="tcExample" EventName="Tick" /> </Triggers> 4: Defining what to refresh/update
Well, now that we have automated updating partially set up, let's add something to actually refresh/update. For this example we'll use an image (simple, i know, but it's just for example purposes). Add the following image tag within the <ContentTemplate> section of the UpdatePanel
<asp:Image id="ExampleImage" runat="server"/> 5: The code so far
Now, if you've followed the steps above somewhat down each line your page should look something like this:
<atlas:ScriptManager ID="MyScriptManager" runat="server" EnablePartialRendering="true"> <ErrorTemplate> <div style="width: 450px; height: 300px; padding: 10px; border: solid 1px black; background: gray; text-align: left;"> <h1>Site error detected</h1> <p>An unhandled exception with the following message has occured on the server:</p> <p><span id="errorMessageLabel" runat="server"></span></p> <p>We're sorry for any trouble this has caused you and will fix the problem as soon as possible.</p> <p><input id="okButton" type="button" value="OK" runat="server"/></p> </div> </ErrorTemplate> </atlas:ScriptManager> <atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <atlas:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> <asp:Image ID="Image1" runat="server" ImageUrl="/images/loading2.gif" GenerateEmptyAlternateText="True" AlternateText="Loading.." /> </ProgressTemplate> </atlas:UpdateProgress> <asp:Image id="ExampleImage" runat="server"/> </ContentTemplate> <Triggers> <atlas:ControlEventTrigger ControlID="tcExample" EventName="Tick" /> </Triggers> </atlas:UpdatePanel> <atlas:TimerControl ID="tcExample" runat="server" Interval="10000" Enabled="true" OnTick="tcExample_Tick"> </atlas:TimerControl> 6: Adding the final code
Almost done now, just one thing left, and that's to add the actual code we use behind the scenes. For this example i've used a simple sitecore structure to attach images to an existing item Sitecore - Content -- Home --- AtlasExample ---- Image 1 ---- Image 2 ---- Image Whatever ---- ...
The template that holds the images simply holds a Image field named "image", nothing more. The reason for having them located under one item is just for easy access through sitecore.
In the code we're gonna be using a ItemCollection and IEnumerator to move through the items and get the content.
protected static System.Collections.IEnumerator images; protected static ItemCollection imageItems;
First up, load the content into the collection when the page is first loaded:
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { InitColl(); } } protected void InitColl() { if (Sitecore.Context.Item.HasChildren) { imageItems = new ItemCollection(); Item imageFolder = Sitecore.Context.Item.Children["AtlasExample"]; if (imageFolder!=null) { foreach (Item itm in imageFolder.Children) { imageItems.Add(itm); } images = imageItems.GetEnumerator(); SelectNextImage(); } else { this.ExampleImage.Visible = false; Sitecore.Context.ClientPage.ClientResponse.Refresh(this.ExampleImage); } } } protected void SelectNextImage() { if (imageItems!=null) { if (imageItems.Count>0) { if (images != null) { if (!images.MoveNext()) { images.Reset(); images.MoveNext(); } Item next = (Item)images.Current; Sitecore.Data.Fields.ImageField image = (Sitecore.Data.Fields.ImageField)next.Fields["image"]; this.ExampleImage.ImageUrl = "~/media library/Images/" + image.Src; this.ExampleImage.AlternateText = "AtlasExample"; } } } } Next, add the tick event that we stated in the TimerControl earlier.
protected void tcExample_Tick(object sender, EventArgs e) { SelectNextImage(); }
Now go ahead and build it and watch the results on your site.
8: Moving on
As you can see extending a site, even a sitecore powered one, with "Atlas" is really a piece of cake and is there for everyone's taking. Check out the Atlas control toolkit and the samples there for more details on how to extend with "Atlas" using custom extenders.
Further reading:
- Roadmap to ASP.NET "Atlas" Documentation and Resources: http://atlas.asp.net/docs/Default.aspx
- "Atlas" Control Toolkit: http://atlas.asp.net/default.aspx?tabid=47&subtabid=477
- Scott Guthrie's blog: http://weblogs.asp.net/scottgu/default.aspx
Take care, and have fun!
P.
Tuesday, September 19, 2006
Atlas loves Sitecore
Friday, September 15, 2006
Bugs?
- Create a template
- Add a Link field
- Save
- Create an Item based on the newly created template
- Try to add a external link using the link field
Notice that the dialog that opens up is in fact the dialog for Internal Link?
Hopefully this'll get fixed, or is already fixed perhaps?
UPDATE:
Keeping an eye open proves to be priceless at times, and this time i'm soooo proven wrong (the dropdown to the right, on the side of "insert link" includes the option to add a external link). Well, you live and learn. There's no bug what-so-ever, i'm the bug :)
P.
Wednesday, September 13, 2006
Sitecore 5.3
For those of you with access to sdn5 and curiosity to satisfy, run on over there and download it..UPDATE: Well, the installer works better than before, but i still hope they will add the option to specify the prefix when installing on SQL, 'cause if they don't it'll be a pain to install on a server with existing solutions.. That's it for now, P.
Friday, August 25, 2006
Items and their security
Tuesday, August 22, 2006
Tthe importance of looking ahead
First release has seen daylight and now (i think) i can finally breathe again.
It's been interesting, that i can't argue, but it's also proven to be quite challenging at times. Had to figure out a lot of new ways to do things you know you somehow should be able to do. Next in line will probably be updates and enhancements and what-not but that's all in the coming so i reckon for this very moment i'm quite happy with the release i've made and the chance to breathe again.
Ever thought about the way blogs and articles help you think outside the box? Well, i have.
There are people that do a lot more for others that they think. People that don't just develop solutions, they also develop other people. They are, in lack of better words, people developers.
Think about it: Who hasn't glanced at pieces of code in articles from the various sitecore blogs? or adapted the code from sdn5 to suit their needs? I know i have.
All these authors, thinkers and futurists make a difference if you ask me - They're part of a new breed of developers, of teachers.
You know what? let's dub them knights of sitecore. Along with the awesome code in sitecore their ways of adaptation and use of it make damn sure that people, like me & you, keep looking ahead, looking for more & striving to improve.
Sitecore, and their knights, are one step ahead, and from what i'm seeing people are running as fast as they can to catch up.
This time my hat's off to you all, and hopefully you know who you are.
That my friends, is the importance of looking ahead.
P.Wednesday, August 16, 2006
Murphy's 1st Law: If anything can go wrong, it will
Server Error in '/' Application. Multiple controls with the same ID '_menu' were found. FindControl requires that controls have unique IDs. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Web.HttpException: Multiple controls with the same ID '_menu' were found. FindControl requires that controls have unique IDs.Not the ideal scenario to start my day with, but hopefully i'll have it fixed soon (otherwise it's going to be a loooooong day).. P. UPDATE: well, i don't really know if it was from lack of sleep or stress or something else, but after moving a few more IDs around it's back to normal again.. 2 days & counting..
Friday, August 11, 2006
Hook, line & sinker
Wednesday, August 02, 2006
Vacation: Week #2
Wednesday, July 12, 2006
First impressions..
Monday, July 10, 2006
5.3 Beta
Friday, July 07, 2006
5.3 - Follow Up
protected Listview BudgetList; // more nice stuff that you're using.. protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!Sitecore.Context.ClientPage.IsEvent) { // some code here to load it all if you have any.. } }All you'll actually really have to do here, for now (i'm sure it'll be fixed and even improved by the rate they're developing) is to add one line to the OnLoad() event:
protected Listview BudgetList; // more nice stuff that you're using.. protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!Sitecore.Context.ClientPage.IsEvent) { BudgetList.ContextMenu = "show:BudgetContextMenu"; // some code here to load it all if you have any.. } }(sorry for the crappy layout of the text, don't really have the time to edit it properly).
Thursday, July 06, 2006
5.3
Sitecore’s portal framework is replaced with the ASP .NET 2.0 embedded portal framework.Perhaps for many a minor thing that'll pass without much notice, but right now that same change/update/migration, if it won't support the previous portal, only says one thing to me: cancel any upcoming vacations..
Wednesday, July 05, 2006
Internet Explorer Developer Toolbar
Get children sorted from a specific Item
So, whenever you need to get a list of items sorted a specific way just use the method in the appropriate way, maybe like the example below?private Sitecore.Collections.ItemCollection GetChildrenSorted(Item parent, String sortby, bool sortascending, int offset, int range, string filter) { Sitecore.Web.UI.HtmlControls.DataContext dc = new DataContext(); dc.DataViewName = "Master"; return dc.DataView.GetChildren(parent, sortby, sortascending, offset, range, filter); }
Maybe this is a really bad way to approach this problem, but it works for me so i'll use it for now (or until this functionality is implemented in Sitecore).private void FillSomeListOrSomething() { // Parent Item that you want to get the children from.. Item parent = Sitecore.Configuration.Factory.GetDatabase("master").Items["/sitecore/content/home"]; if (parent.HasChildren) { foreach (Item itm in GetChildrenSorted(parent, "__created", false, 0, 0, "")) { // whatever you want to do with the sorted list of items you got back.. } } }