05 december 2011

Using the Sitecore EditFrame with a DataSource

This post is a supplement to Brian’s excellent post on sc:EditFrame with some more use cases, showing the EditFrame used with another item than the current item, and showing rendering done from code behind.

http://briancaos.wordpress.com/2011/11/28/using-sitecore-editframe-in-pageedit/

image

Using the Sitecore EditFrame with a DataSource

DataSource: Item Full Path (if not set Context is used)
Buttons: Notice it must link to a folder containing buttons and not a button.

<asp:Repeater runat="server" ID="FooterLinks" DataSource="<%# FooterLinkSections %>">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
        <sc:EditFrame 
        ID="FooterEditFrame" 
        Buttons="/sitecore/content/Applications/WebEdit/Edit Frame Buttons/FooterNavigationSection" 
        runat="server" 
        Title="Edit the link list"
        DataSource="<%# ((FooterNavigationSectionItem)Container.DataItem).InnerItem.Paths.FullPath %>">
            <p>
                <%# ((FooterNavigationSectionItem)Container.DataItem).FooterNavigationSection_Title.Raw %></p>
            <asp:Repeater runat="server" ID="FooterLinks" DataSource="<%# ((FooterNavigationSectionItem)Container.DataItem).FooterNavigationSection_Links.ListItems %>">
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <a href="<%# Sitecore.Links.LinkManager.GetItemUrl(Container.DataItem as Item) %>">
                        <%# NavigableItem.GetNavigationTitleRaw(Container.DataItem as Item) %></a></li>
                </ItemTemplate>
                <FooterTemplate>
                    </ul></FooterTemplate>
            </asp:Repeater>
        </sc:EditFrame>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul></FooterTemplate>
</asp:Repeater>



 


Using the EditFrame with code behind/inline code


Using the object browser on Sitecore.Web.UI.WebControls.EditFrame you will find the RenderFirstPart RendeLastPart, for using these you must use the HtmlTextWriter.

image


var navList = footerItem.FooterNavigation_Selector.Item.GetChildren<FooterNavigationSectionItem>();
StringWriter output = new StringWriter();
using (HtmlTextWriter writer = new HtmlTextWriter(output))
{
    foreach (var selectorItem in navList)
    {
        var links = selectorItem.FooterNavigationSection_Links.ListItems.Aggregate(
            string.Empty,
            (current, item) =>
            current +
            string.Format(
                "<li><a href=\"{0}\">{1}</a></li>",
                Sitecore.Links.LinkManager.GetItemUrl(item),
                NavigableItem.GetNavigationTitleRaw(item)));
 
        var editFrame = new EditFrame
               {
                   ID = "editLinks" + selectorItem.ID.ToShortID(),
                   Title = "Edit the link list",
                   Buttons = "/sitecore/content/Applications/WebEdit/Edit Frame Buttons/FooterNavigationSection",
                   DataSource = selectorItem.InnerItem.Paths.FullPath
               };
        editFrame.RenderFirstPart(writer);
 
        writer.Write(
            string.Format(
                "<li><p>{0}</p><ul>{1}</ul></li>",
                selectorItem.FooterNavigationSection_Title.Raw,
                links));
 
        editFrame.RenderLastPart(writer);
    }
}
renderFooterLinks.Text = string.Format("<ul>{0}</ul>", output);

17 november 2011

Sitecore Desktop - setting default background image and color for new sitecore users

Sitecore support sent me this easy little guide, that is now google searchable.

Can we set default background image and color for new sitecore users ?
(without doing it manually on each user creation)

You can set the default background image for new Sitecore users. Please perform the following steps:

  1. copy the background image in the *.jpg format to the <web root>\Website\sitecore\shell\Themes\Backgrounds\ folder  in the file system, or you can use the existing one. 
  2. open the “/sitecore/system/Settings/Security/Profiles/User” item in the “core” database  in the Content Editor and change the path in the “Wallpaper“ field to target the desired image.

After these steps, all new users will get the image you have set above, as  the default wallpaper. 

If you want to set the default background color,  I suggest you perform the following steps:

  1. log in to Sitecore, select the “core” database  and find the “/sitecore/templates/System/Security/User” item(template).
  2. Add the “WallpaperBackground” field, without “Type” in it, save it.
  3. Find the “/sitecore/system/Settings/Security/Profiles/User” item, enter in the “WallpaperBackground” field an appropriate value in the following format “#123456”. Save it.

After these steps, all new users, will have the background color you set above.

Best Regards,
Dmitry

10 september 2011

Multiple Group By vs. Multiple Order By syntax in LINQ

Knowing Group by in Sql, having it in linq is a very power full feature. An interesting aspect of linq is that the OrderBy and GroupBy are using very different syntax when operating with multiple elements.

.GroupBy(c => new { c.ClientInitials, c.OwnerInitials, c.Department } )
.OrderBy(c => c.ClientInitials).ThenBy(c => c.OwnerInitials).ThenBy(c => c.Department)

If you are tricked into the assumption that you can do: .OrderBy(c => new { c.ClientInitials, c.OwnerInitials, c.Department } )
You will receive an Exception: “At least one object must implement IComparable."

Here is a an example on how one set of objects can be remodelled with linq to get reporting statistics.
The Resource class has a list of bookings and we start by flattening to one dimension of data for simplicity.

var resourceSet = from c in this.GetResources()
                              from o in c.Bookings
                              select
                                  new
                                      {
                                          c.Department,
                                          c.Initials,
                                          c.Name,
                                          o.ClientInitials,
                                          o.OwnerInitials,
                                          o.EventDate,
                                          o.Description
                                      };

This could also be achieved with a .SelectMany

var resourceSet = this.GetResources().SelectMany( c => c.Bookings, (c, o) => new { c.Department, c.Initials, c.Name, o.ClientInitials, o.OwnerInitials, o.EventDate, o.Description });

Then we group by the three main parameters and summarizes the statistics base on the booking periods.

            IEnumerable<ReportViewModel> groupedByClientsOwnerDepartment = from c in resourceSet
                                                  group c by new { c.ClientInitials, c.OwnerInitials, c.Department }
                                                      into g
                                                      select new ViewModels.ReportViewModel()
                                                          {
                                                              ClientInitials = g.Key.ClientInitials,
                                                              OwnerInitials = g.Key.OwnerInitials,
                                                              Department = g.Key.Department,
                                                              CountBookingsLatestFullMonth = g.ToList().Where(f => f.EventDate.Month == DateTime.Today.AddMonths(-1).Month).Count(),
                                                              CountBookingsSinceLastFullMonth = g.ToList().Where(f => f.EventDate <= new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)).Count() };

We then return to the view and order the output by the main 3 group by elements.

            return View(groupedByClientsOwnerDepartment.OrderBy(c => c.ClientInitials).ThenBy(c => c.OwnerInitials).ThenBy(c => c.Department));

19 juli 2011

Visual Studio randomly changes keyboard layout to US

 

I have been fighting with visual studio sometimes changing the keyboard layout from my Danish keyboard layout to US keyboard. All my internet search results on the topic suggested shortcuts being pressed, but I have disabled the language bar shortcuts and removed the US keyboard from my profile as the first thing I did when I logged on. I have also disabled all ease of access shortcuts.

Visual Studio is running in the Administrator context. This seems to be the root of the issue and I have now taken on the bigger guns for fixing this. I have gone into the registry and removed the US keyboard layout (409) from all the internal users also.

The registry (regedit.exe) contains keyboard layout information for all the native users of a windows installation and they still have the US keyboard registered. Windows SID S-1-5-18 / S-1-5-19 / S-1-5-20 and .DEFAULT, default being “All Users”.

Removing all references to the 00000409 keyboard under the following registry nodes and leaving only the one keyboard layout you wish to use fixes the bug. You can not change keyboard layout if you only have one. After the mentioned change and a reboot I have not had the problem again, Nice and simple.

HKEY_USERS\.DEFAULT\Keyboard Layout\Preload
HKEY_USERS\S-1-5-18\Keyboard Layout\Preload
HKEY_USERS\S-1-5-19\Keyboard Layout\Preload
HKEY_USERS\S-1-5-20\Keyboard Layout\Preload

image

Ps. Do not make changes in your registry unless you understand the possible consequences, and remember that backup is your friend.

18 marts 2011

Simple Web.config Transformation without Visual Studio 2010

 

The MSDN documentation on Web.Config Transformation does not really help regarding generating the transformed config files in Visual Studio 2010, without going though full publications and involving the other solution projects.

For generating the most low-impact Transform operation outsite Visual Studio you have to add the following to your C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets and call msbuild with the task as \target, this could be put as a post build event, this way you can always check that your configuration transformations are merged as expected instead of having to guess, otherwise a fantastic new feature in the framework.

call "msbuild" "D:\Solutions\Intranet.Web.csproj" /t:Transform /p:Configuration=Release


You can also add it to the *.csproj file but it would be removed by VS upon editing, the other file is included by VS into the csproj.

   1: <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
   2: <Target Name="Transform">
   3:   <MakeDir Directories="obj\$(Configuration)" Condition="!Exists('obj\$(Configuration)')" />
   4:   <TransformXml Source="Web.Config" Transform="Web.$(Configuration).config" Destination="obj\$(Configuration)\Web.config" StackTrace="true" />
   5: </Target>

Source: http://forums.asp.net/p/1532038/3789356.aspx

12 november 2010

Sitecore in a Continuous Integration setup

removing manual operations related to Sitecore releases.

For the last year we have been focusing on integrating our Sitecore solutions in a Continuous Integration environment. We now have two larger Sitecore solutions and many smaller ones in the environment, where we can build, test and deploy environments, including Sitecore Items. We have gone through some iterations of the environment and find that we are ready to share some of our experiences.


Continuous Integration

The main purpose of continuous integration is to have an environment where code is build and tested at every commit, secondarily the build can be pushed to TEST or QA environments. The ultimate goal, for us, is to be able to test, validate and push Sitecore Sites from development to production, without any manual steps.

image

Continuous Integration and Sitecore

A Sitecore solution is composed of three parts, 1) the code 2) the database build by the developers (templates, layouts etc) and 3) the user content that is stored under sitecore/content and sitecore/media. The code is easy to integrate in a automated build, tests and deployment since this is the main goal of most CI setups, but where it gets more challenging is when the Sitecore Items get involved. Without the Sitecore Items in the CI setup there remains several manual parts for a release cycle.

image


Automating Sitecore builds
and release cycle

CruiseControl.NET has been chosen as build server platform and custom NAnt tasks are used in the build scripts for search and replace, robocopy and Sitecore Item control.


Item Versioning and (Auto)Serialization

Sitecore Items is a big part of a solution and the first requirement is that the Items can be put under Source control and versioned correctly, the native implementation from Sitecore is based on a manual "œdump" of what the developers choses to save to disk.

In a multi-developer environment this lead to developers dumping the whole sitecore database at each checkin, and reverting the full database takes over 10 minutes sometimes 30 so this was not done before each development session.

When renaming and deleting Items, this setup lead to Items being re-added to the tree after they had been deleted by another developer, because the other developers had not removed them before they themselves made a item dump and checked in.

What was needed was a synchronization model for keeping the file system up to date with Sitecore without user involvement, thereby the only files the developer checks in are the ones he has made changes to. This has been done by developing an auto serialization that attaches to the Item events and e.g. deletes the file if the Item is deleted, or serializes content items if there releted template is changed. We do not yet import file changes fully automated to Sitecore, for the fear of loosing work in case of merges and conflicts, but it would be a natural way to go.

This module means that we now have a stable model for versioning our sitecore item development, this was a base requirement for moving forward.  We have full traceability on the system development since every developer runs his own Sitecore code and database and both code and items are versioned.


Build Flow

We have done several iterations of the build scripts. Our latest iteration pushes the files before changing the configurations, and performs testing directly on the target system.

image


Repository Branching Strategy

Our latest project phmetropol.dk sometimes involved up to 8 developers, and 60+ change requests in some releases. For controlling this we created code branches in our repository for UAT and PROD. UAT had the latest code that was for final customer validation (UAT = User Acceptance Testing) and PROD contained the latest released code. This setup gave us the possibility to keep active development in the main trunk (incl. Sitecore Items) and releasing well tested code+Items in the UAT branch with a potential fix or two, and finally being able to hot fix (incl. Items).

Without version control on the Sitecore Items, we believe, such releases would have had major risks for errors.

that needed testing and We have also tried where the test was done locally before the files where moved, where items where separated from the build files but we had the need to introduce repository branching for adding a UAT and PROD build, and the configuration management when involving staged setups made the model complicated.


Configuration Management

The Sitecore solutions we have build in our environment have all involved staged setups, we have found two strategies for controlling the configuration under automated build.

Staged build and environment creation

genvej.nu is created with two websites in the Visual Studio project, one site for CMS and a site for the Front site, config files for both environments are checked in and most of the rest is copied from the Visual Studio build process from bin/ressources/layouts etc. to front. The only things the build script had to change was the environment elements in each web.config.


Staged and environment creation

phmetropol.dk was our next project we wanted to create the staged files based on the cms files only, for keeping the development environment more streamlined. This means that we, from the NAnt build file, first created a staged copy of the source, changed the config to match a staged setup (using include files for overriding where possible) and last customized based on the target environment.

This worked well in our development stage but when we saw the need to introduce the UAT environment and build this setup has become a bit complicated to maintain.


Sitecore Items

Controlling Sitecore Items in the build process required that we had them under version control and branched. Once this is in place the next step is to push them around on our different environments.

For reverting and packaging a Sitecore context is required, we have therefore implemented a web service in the Sitecore admin level, that gives us access to reverting, serializing and packaging features. Combined with a NAnt task we can control items deserialization or packing from the build script.

We have initially implemented a full revert or partial, that we can control through a web service on the Sitecore environment to give us Sitecore context. In a default cycle the only path we revert are template and layouts, but we can also revert all of Sitecore in both core and master, the problem is that this takes up to 30 minutes, so our default behavior is only the main elements.

After some iterations, we are currently looking at a model where we push the items to the target using robocopy and use the change log to revert only the affected items on Sitecore, we have done a proof of concept and this feature is in active development. This will mean we can revert sitecore items on each build because it will be done very fast. In the process we har also evaluating ideas for partial reverts on the developer machines but in that area we have yet to find the best model.

Once reverted and tested we can package e.g. template and layouts, and save a package that is then used for deployment to production, or backup.  When deploying we never take items related to Content or Media, every other Item is excepted to come from our controlled builds and packages. We have had some surprises with Web forms for marketers and Sitecore/system in this context but we will keep that for another post.


Testing

Basic code test is implemented with NUnit and could be run after the build is done on the build server. We have chosen to deploy the site first so we can run functional tests involving page clicks and search results for tests. For allowing tests on the Site we have used WatiN.

For making functional tests on controlled data and not client content we have introduced two parallel sites in development, one used in the building of NUnit tests that validate main functionality and the other used by the client to build their content. In the development phase we let the clients build up data on the qa environment and we actually fetched data with our tool web service that we pushed to our test server so we could see more real content in the test environment and still have a semi stable environment for client qa.

Other levels of testing and quality control have been implemented using FxCop, StyleCop and TotalValidator and NArrange in the development cycle.


Conclusions

We have used a reasonable amount of time building this setup. We are now able to construct larger Sitecore solutions, with tests, branching and a release cycle with full source control and minimal manual processes.

In our next project we hope to take the last step and implement continuous deployment, so production is updated straight from our build server. We also expect to implement Web Config Transformation now available with Visual Studio 2010.

We see a Continuous Integration environment as a natural part of a large Sitecore solution and an important move towards a release process.

We would like to know about your expirences on Continuous Integration, so please leave a comment or blog post.

Jan Hebnes, Head of .Net development at 1508 A/S

Originally posted to: http://www.15all.net/2010/11/12/sitecore-in-a-continuous-integration-setup/

22 september 2010

New Gaming PC / September 2010

Der er blevet investeret i ny gaming maskine, til mig og 2 andre som lige fik knyttet sig til.
Målet var at finde en maskine til omkring 10.000,- som kunne det hele.
Det skal selvfølgeligt deles med verden. 
Profil 1 (Jan) Profil 2 Profil 3 Billigste
Med billigste priser fra edbpriser.dk kr. 10.298,00 kr. 8.296,00 kr. 11.306,00 kr. 29.900,00
Med Windows 7 Home Premium kr. 11.495,00 kr. 8.296,00 kr. 11.306,00 kr. 31.097,00
clip_image003 Antec Performance One P183 kr. 986,00 kr. 986,00
clip_image004 Antec Three Hundred - EU kr. 394,00 kr. 394,00 kr. 394,00
image EPS-750W Ultra Silent kr. 368,00
image CoolerMaster Silent Pro Gold 1000W kr. 1.426,00 kr. 1.426,00 kr. 1.426,00 kr. 1.426,00
clip_image009 ASUS P6T Deluxe V2 kr. 1.651,00
Gigabyte GA-X58A-UD3R kr. 1.430,00 kr. 1.430,00 kr. 1.430,00 kr. 1.430,00
clip_image011 Core i7 I7-930 8 MB (Intel Boxed) kr. 1.892,00 kr. 1.892,00 kr. 1.892,00 kr. 1.892,00
Corsair XMS3 3 x 2 GB kr. 962,00 kr. 962,00 kr. 962,00 kr. 962,00
Kingston x 6 GB kr. 1.532,00
image XFX Radeon HD 5750, (1 GB) kr. 1.025,00
image XFX Radeon HD 5830 (1 GB) kr. 1.567,00 kr. 1.567,00 kr. 1.567,00 kr. 1.567,00
clip_image024 Intel X25-M Mainstream Solid State Drive - 34nm Product Line 80 GB kr. 1.410,00 kr. 1.410,00 kr. 1.410,00
image Samsung SpinPoint F3 Desktop Class HD103SJ, 1 TB kr. 434,00 kr. 434,00 kr. 434,00 kr. 434,00
image Samsung SH-S223L (Elfenben / Sølv / Sort) Detailsalg kr. 191,00 kr. 191,00 kr. 191,00 kr. 191,00
clip_image026 Samsung SyncMaster P2450H (Sort rose) kr. 1.600,00 kr. 1.600,00
clip_image027 Microsoft Windows 7 Home Premium (Dansk) (Komplet pakke) kr. 1.255,00 kr. 1.255,00
clip_image027 Microsoft Windows 7 Home Premium (Engelsk) (Komplet pakke) kr. 1.197,00 kr. 1.197,00

07 september 2010

Ny forside på http://jan.hebnes.dk

Så fik endeligt taget mig sammen til at opdatere http://jan.hebnes.dk
Det er gjort via servicen http://flavors.me som jeg spottede en tidligere kollega havde benyttet til hans egen side.

Bloggen

Blogspot.com som kører bloggen opdatateret deres hosting service pr. 1.maj således at man ikke længere får lov at køre via FTP upload til sit eget site, men man må stadigt sætte sit eget domain på, så nu kører bloggen videre under http://blog.jan.hebnes.dk.
En bonus ved at gå over til drift direkte på blogspot er at der ikke skal laves noget specielt for at understøtte billeder i blog posts, dette indlæg er skrevet direkte i Windows Live Writer og screenshots er blot klippet ind, så publicering kan foregå meget nemt.

Flavors.me

Styrken ved servicen er at det er super simpelt at opsætte integration til rigtig mange service udbydere, hvilket ville være meget tidskrævende at få på plads alene.
image image image

Indholdet er bevaret

For at beholde kontrollen over mit domain er flavors.me/janhebnes indlejret med en iframe på forsiden og mit indhold er fortsat på en egen server, den gamle forside kan tilgåes på http://jan.hebnes.dk/archives.html
Den side som er vigtigst for mig at bevare er svæveflyvningen som rigtig mange har glæde af at læse på når de starter pilot uddannelsen.
http://jan.hebnes.dk/projects/soaring/

Baggrundsbillede

En stor del af flavors.me går på at iscenesætte siden, med inspiration fra de andre brugere på flavors.me http://flavors.me/directory har jeg valgt at gøre det med et stort flot cockpit billede fra en termik tur i DuoDiscus en dag med blå termik, der bliver himmlen så fantastisk blå.

09 oktober 2009

1508 er med i el-bil udstillingen på dansk design center. Her dukkede den seneste nye sports el bil op og om lidt dukker Connie Hedegård op!
1508 er med i el-bil udstillingen på dansk design center. Her dukkede den seneste nye sports el bil op og om lidt dukker Connie Hedegård op!
Nu smutter Julie og jeg ud i kulturnatten.

02 september 2009

Beretning fra Riviera tour 2009

Så fik vi endeligt færdig redigeret vores beretning fra sommerferien, 20 dage i sol og varme. Det blev en fantastisk tur!

Beretning fra Riviera tour 2009

23 maj 2009

DM Dag 3 - så sidder jeg igen og studerer hvordan majs planterne gror. I dag er det ved Århus. Opgaven var på 371km men der var kun 850-900 til sky basen, så det hele var lidt tæt på en.
DM Dag 3 - så sidder jeg igen og studerer hvordan majs planterne gror. I dag er det ved Århus. Opgaven var på 371km men der var kun 850-900 til sky basen, så det hele var lidt tæt på en.