Som jag bloggat om tidigare så kommer Umbraco att släpp stödet för XSLT i version 5, det blir istället fullt fokus på Razor!

 

På sistone har jag bland annat roat mig med att kolla in Doug Robars presentation från CodeGarden 2011 där han pratar om tips och tricks för Umbraco. Jag har också kollat igenom Razor-avsnitten på Umbraco TV – mest för att se om man kunde upptäcka något nytt. Jag antecknande lite smått och gott som jag tänkte bjuda på i detta (och kanske fler) inlägg.

 

Snabbvägen till Documents Types

När du arbetar med ett razor macro och vill komma åt en eller flera child-elements som är av en viss Document Type så kan man använda följande syntax:

@foreach(var node in Model.DocTypeNames) { }

Det sades i någon presentation att man skulle lägga till ett “s” i slutet på namnet på den DocType man ville komma åt men det verkar som att det funkar även utan detta s, i alla fall i version 4.7.1. Låt oss säga att du har en “NewsItemFolder” under första noden i systemet och sedan i denna listar dokument av typen “NewItem”. Då skulle följade lista alla nyheter:

@foreach(var node in Model.NewsItem.First().Children) {

@node.Name<br/>

}


Kapa och lägg till…

Det händer ofta att man bara vill visa delar en sträng, kanske för en sammanfattning eller teaserlista. Det finns inbyggt i @Library.Truncate(). För att kunna använda detta måste du köra V4.7.1, alternativt uppgradera din macromotor genom att kopiera in “umbraco.MacroEngines.dll” från V4.7.1 till din V4.7.0-installation. Så här använder du metoden:

@Library.Truncate("Här skriver vi en massa text som sedan ska kapas", 10, true);


Det som skrivs ut blir “Här skriver vi en massa t…”. Första parametern är indatan, sedan längden och om man vill att metoden lägger till “…” på slutet.

 

Om det är sant så gör det osv

Att if-statments mitt i razorkoden ser ganska klumpigt ut så därför finns @Library.If() som används så här:

 

@Library.If(true=true, "Skrivs vid sant", "Skrivs vid falskt, denna är är inte obligatorisk.");

 

Jag vill göra en breadcrumb

Då ska du använda dig av metoden “Ancestors” som finns på alla DynamicNodes. Så här skriver du för att lista alla “parents” hela vägen upp till root-noden.

@foreach(var node in Model.Ancestors()) {

@node.Name<br/>

}

 

Detta returnerar alltså alla parents i en fin lista så att man tex. kan göra en breadcrumb.

 

Gruppera mera

En feature som jag verkligen gillar är InGroupsOf(intAntalPerGrupp). Denna kan anropas på alla typer av samlingar och kommer då att returnera objekt av typen “umbraco.MacroEngines.Grouping” som håller alla objekt i samlingen grupperade i grupper enligt parametern. Tex:

@foreach (var groups in Model.Children.InGroupsOf(2))
{
foreach (var item in groups)
{
<a href="@item.Url">@item.Name</a><br />
}
// Bryter efter två rader med en hr, hade också kunnat
// vara text en ny kolumn eller liknande.
<hr />
}

  

Skulle skriva ut två childs, sedan en hr-tag, två childs, en tag osv osv.

 

Fuska lite

Peter Gregory har skapat ett litet projekt på our.umbraco.org där han sammanställer en liten fusklapp över Umbraco och Razor, Razor DynamicNode Cheat Sheet är klockrent, ladda hem idag!

 

Umbraco _cheatsheet

 

Nu orkar jag inte skriva mer! Tjejen ligger på soffan och vill att vi ska se på “Family guy”. Det finns mer Razor-tips att bjuda på så håll till godo, prenumerera gärna på min RSS men hjälp av tex Outlook eller Google Reader.

Idag togs ett nytt steg i arbetet med nya den versionen av Umbraco, Umbraco V5. Man släppte en första så kallad RC (Release Candidate) vilket innebär att man är väldigt nära det slutgiltiga resultatet. Samtidigt skrev man också att man hoppas på att den nya versionen kommer att bli klar för släpp i slutet av januari 2012!

 

 Umbraco -v5

 

I denna Umbraco V5 RC1 har man bland annat implementerat members-delen, man har jobbat med DictionaryItems för att få till språkstödet, gjort förbättringar på DocumentTypes och även arbetat med DynamicModel för att göra det ännu enklare att skriva grymma macros. Jag tänker labba lagom mycket med detta under julen, eftersom jag drar hem till Motala och käkar mammas julmat så får jag nog återkomma i mellandagarna med en eventuell kommentar ;)

 

Du som är nyfiken kan redan nu ladda ned RCn från CodePlex, och läsa mer i HQs blogginlägg på Umbraco.org.

 

Samtidigt funderar jag. Kan alla MVC? Kommer version 5 alltid att bli det självklara valet? Vad tror du?

 

God Jul!!

Vår senaste kund Samtrans gav oss förtroendet att implementera Umbraco CMS i den design som levererats av Vektorgrafik Stockholm.

 

Samtrans Screen

 

Företaget sysslar med persontransporter för personer med speciella behov och hemsidan är en uppfräschning av deras tidigare hemsida. Läs gärna med om projketet bland våra referenser.

Xslt Books

Böcker som gjort sitt...

 

För några dagar sedan skrev Niels Hartvig, grundaren av Umbraco, ett blogginlägg där han berättade att man nu kommer att släppa stödet för så kallade XSLT-makron i Umbraco.

 

XSLT är en teknik som används för att formatera och och omformatera XML-dokument. Eftersom hela Umbraco-sajten, i dagsläget, sparas som ett XML dokument i webbserverns cache så har XSLT varit en extremt snabb teknik för att lista och filtrera innehåll.

 

I Umbraco 5, som bygger på ASP.NET MVC och är en komplett ombyggnad av grunden till Umbraco, kommer man att släppa stödet för XSLT och istället satsa enbart på Razor-makron. 

Jag tycker att det är bra! Som nybörjare på Umbraco minns jag att det största "hindret" för mig var just XSLT. XSLT är extremt snabbt men på samma sätt som det är snabbt är det krångligt och kräver relativt djup förstålse om XML, XPath osv. När Umbraco 5 nu istället baseras på Razor kommer den som arbetat med ASP.NET MVC att känna igen sig eftersom att Razor är den teknik som används för att programmera vyer i gränsnittet för MVC-sajter.

 

Så det är bara att lägga mina gamla XSLT-böcker på hyllan....

Umbraco User Group

 

Jag vill tipsa om den svenska användargruppen för Umbraco (Umbraco User Group Sweden). Den startades för några månader sedan och kommer att hålla möten och seminarium med Umbraco som tema.

 

För att gå med, besök hemsidan uugs.se och glöm inte att joina facebook-gruppen

 

Vi ses och hörs! :D

Jag tänkte gå igenom grunderna i hur man bygger ut Umbracos Backoffice/backend. Eftersom det redan finns ett bra gäng bloggposter om hur man lägger till sin egen "section" så tänkte jag fokusera på lite andra delar just nu.

 

Skapa egen section / application i Umbraco

Det krävs lite småfix i databasen för att skapa sin egen section, det är inte särskilt avancerat och du kan läsa utförligt hur man gör i dessa poster:

 

http://www.robertgray.net.au/2011/5/10/creating-a-custom-content-tree-in-umbraco.aspx

 

http://www.sewen.se/blogg/2010/2/26/skapa-en-custom-section-i-umbraco-(steg-1).aspx

 

Göra egna Webforms till Umbraco backoffice

När du ska skapa dina egna .aspx-filer för redigeringsytan så är det en bra idé att använda Umbracos egna kontroller för backoffice. De finns i umbraco.uicontrols.controls. För att använda dessa på sida måste du lägga till följande rad i början av ditt aspx-dokument.

 

<%@ Register TagPrefix="umb" Namespace="umbraco.uicontrols" Assembly="controls" %>

När detta är fixat så kan du enkelt använda Umbracos orginal-kontroller och få din custom section att hålla samma konsekventa utseende som resten av backoffice.

 

Jag tänkte gå igenom några av de mesta grundläggande kontrollerna

 

TabView

Tabview

Om du vill använda tabbar skall du ha en TabView kontroll på sidan. Varje sida behöver bara EN TabView. Du skapar sedan valfritt antal tabs i din code behinde.

 

I din aspx-fil:

<umb:TabView ID="MyTabView" runat="server" Width="552px" Height="392px"/>


För att lägga till tabbar används förljande kod i code behinde:

protected override void OnInit(EventArgs e)
{
   base.OnInit(e);
   
    // Lägg till ny tab på MyTabView
    var myTab = MyTabView.NewTabPage("Details");
    myTab.Controls.Add(myPane);
    // Ett tab till
     var myTab2 = MyTabView.NewTabPage("New tab");
     myTab2.Control.Add(anotherPane);
}



Pane / PropertyPane

Pane -property

Det blå strecket markerar "umb:Pane" och de röda boxarna är PropertyPanels. Detta samarbete mellan Pane och PropertyPane ser man ofta i Umbracos backoffice. Koden ser ut ungefär så här:

<umb:Pane ID="myPane" runat="server" Text="Settings">
  <umb:PropertyPanel ID="PropertyPanel1" runat="server" Text="Database datatype">
	<!-- DropDown goes here -->
  </umb:PropertyPanel>
  <umb:PropertyPanel id="PropertyPanel2" runat="server" Text="Add prevalue">
	<!-- Textbox goes here -->
  </umb:PropertyPanel>
</umb:Pane>

 

MenuImageButton och MenuIcon

Det finns två olika typer av knappar som kan adderas till en TabView. Visuellt syns ingen skillnad, det är knapparnas funktion som skiljer sig.

  • MenuImageButton - Används om du vill att knappen ska fira av ett click-event och en postback.
  • MenuIcon - Används om knappen istället ska anropa en javascript-funktion.

 

MenuImageButton:

btnImage = dataTab.Menu.NewImageButton();
btnImage.ID = id;
btnImage.Click += new ImageClickEventHandler(SaveButton_Click);
btnImage.AlternateText = "Save";
btnImage.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

 

MenuIcon:

btnImageIcon = dataTab.Menu.NewIcon();
btnImageIcon.ID = "btnImageIcon";
btnImageIcon.OnClickCommand = "alert('Run javascript')";
btnImageIcon.ImageURL = GlobalSettings.Path + "/images/editor/save.gif";
btnImageIcon.AltText = "Show alert";

 

CodeArea

I Umbracos backoffice används ibland en inbyggd kodeditor. Den kan även du använda i dina egna projekt genom att infoga en CodeArea.

 

Umbraco codearea

 

Så här kan koden se ut:

 

<umb:CodeArea ID="editor" ClientSaveMethod="doSubmit" CodeBase="Python" AutoResize="true" OffSetX="47" OffSetY="55" runat="server" />

 

ClientSaveMethod är inte obligatorisk och används för att hantera om användaren trycker "Ctrl+S" i editorn. Egenskapen CodeBase krävs inte heller. När du arbetar med denna CodeArea i code behinde använd egenskapen "Text" för att sätta/hämta innehållet.

Jag läste precis några av mina favoritbloggar om Umbraco och såg att några tipsade om hur man enkelt tömmer papperskorgen.

 

http://www.blogfodder.co.uk/2011/5/26/mass-delete-over-1k-nodes-from-recycle-bin-in-47

 

http://anthonydotnet.blogspot.com/2011/07/umbraco-empty-recycle-bin-hangs.html

 

Jag rekommenderar paketet "F.A.L.M Housekeeping" som dels kan radera papperskorgen men även loggar, rollbacks och mycket annat. http://our.umbraco.org/projects/backoffice-extensions/falm-housekeeping

 

Housekeeping

Det är egentligen helt självklart och hör till grunderna inom .NET men jag måste verkligen dela med mig av den här historien för att göra det övertydligt. Det handlar om att sätta ihop (concat) strängar. Det finns ett väldigt enkelt sätt att göra detta som ser ut ungefär så här:

 

strVariable += "mer saker i strängen"


Detta sätt att sätta ihop strängar har jag använt en hel del genom åren. Jag har ofta läst om att StringBuilder-klassen är snabbare och bättre eftersom att den endast håller ett objekt i minnet, den skall alltså användas när det handlar om större objekt tex om concaten sker i en loop. En kod liknande den nedan fanns i ett projekt jag fick ta över.

foreach(var yada in yadaYada)
{
  strVariable += "mer saker i strängen"
}


Funktionen som ibland hanterade tiotusentals rader var extremt seg. Kan det vara Entity Framework (som också var inblandat) som spökar? Svaret var klart och tydligt nej. Det beror på att vi inte använder StringBuilder. Loopen ovan med 15 000 rader tog cirka 25 sekunder för vår testmaskin att processa. Gissa tiden för samma loop fast med StringBuilder?

foreach(var yada in yadaYada)
{
  stringBuilder.Append("mer saker i strängen");
}

Den tog 0,21 sekunder. Det är helt sjukt vilken enorm skillnad. Enligt vad jag förstår så kommer kompilatorn att döda den gamla och skapa en ny sträng i minnet varje gång loopen körs i första exemplet, i andra, med StringBuildern används samma objekt. Värt att veta alltså:

 

StringBuilder.Append 00:00.0210012 sekunder
Html+html 00:26.9005386 sekunder

 

När man utvecklar egna sections till Umbracos backoffice så är det lämpligt att återanvända standardkontrollerna i Umbraco. Dessa finns i umbraco.uicontrols och används genom att lägga till följande rad i början av din aspx-fil.

 

<%@ Register TagPrefix="umb" Namespace="umbraco.uicontrols" Assembly="controls" %>


Add ReferenceNär jag gjorde detta i ett nytt projekt för att tag sedan märkte jag att Visual Studio vägrade att ge mig Intellisense på kontrollerna vilket var sjukt irriterande. Efter lite googlade så hittade jag denna tråd som presenterade den enkla lösningen:

 

Lägg till en referens till ClientDependency.Core.dll i ditt projekt och saken är biff.

 

 

 

 

 

Vår utvecklare Markus Johansson har gjort en kort introduktion till Umbraco CMS du som skall redigera sajten ser hur enkelt det är att arbeta med detta underbara publiceringsverktyg och du som ska utveckla får upptäcka enkelheten och skalbarheten.

 

För dig som ska uppdatera hemsidan

 

 

För dig som är utvecklare

 

I vår utvecklingsmiljö använder vi SQL Server 2008 och för ett tag sedan utvecklade vi en Umbraco-lösning med denna databas som grund. När detta skulle implementeras till kundens produktionsmiljö visade det sig att de körde SQL Server 2005. Det innebär att man inte kan kopiera mdf-filen eller skapa en backup och återställa den på servern som man annars hade kunnat göra.

 

Lösningen som vi kom fram till blev att scripta hela databasen så här:

 

1. Öppna SQL Server Managament Studio.
2. Högerklicka på den databas du vill exportera och välj "Generate Scripts"

 

Copy -database -11

 

3. I steget options glöm INTE att klicka i följande:
 - Script Bindings = True
 - Script for sever version = SQL Server 2005
 - Script logins = True
 - Script Data = True

 

Copy -database -2

 

4. Klart

När utvecklingen av en Umbraco-sajt är klar och hemsidan skall göras publik finns det en del saker att tänka på. Det är många moment och småsaker som kan vara lätt ass missa. Därför tänkte jag dela med mig av min nuvarande checklista.

 

  • ConnectionString - Glöm inte att ändra kopplingen till den databas som skall användas i produktionsmiljön.
  • Stäng av UmbracoDebug genom att sätta "umbracoDebugMode" to false i web.config.
  • Slipp "Uppgraderingsmeddelanden" i backend genom att sätta umbracoDisableVersionCheck till false eller umbracoVersionCheckPeriod till 0 även detta i web.config.
  • Sätt "CustomErrors" till RemoteOnly för att inte exponera eventuella fel till användare/hackers.
  • Sätt debug till false i kompileringssektionen.
  • Dubbelkolla att mapprättigheterna är korrekta i produktionsmiljön - Länk till artikel på umbraco.org.
  • Aktivera "Health Monitoring" i web.config. Då får du tex. mail om ett fel uppstår på servern. Lär mer om health monitoring.
  • Städa i din Umbraco-installation. Tabort gammla logposter, mediafiler och annat som tar onödig plats. Använd pluginen FALM Housekeeping av Adriano Fabri.
  • Ge din kund en kram.

Jag jobbade med ett RSS-macro som skulle lista blogg inläggen från bland annat  denna blogg. Mallen kräver att man kan sortera posterna efter datum i fallande ordning. Eftersom xsl-sort har ett element som heter data-type så forskade jag i om man kunde sätta danna till date - vilket inte gick. De enda värden som är gilltiga är text, number och qname.

 

Därför blev min lösning att konvertera datumet till siffror och sedan sortera efter nummer.

 

<xsl:apply-templates select="$currentPage/descendant::SimpleBlogPost [@isDoc]">
     <xsl:sort select="umbraco.library:FormatDateTime(postDate ,'yyyyMMddhhmmss')" data-type="number" order="descending" />
</xsl:apply-templates>

 

 

Webappers _logo

 

Jag tycker verkligen om tips-bloggen "WebAppers" som tipsar om coola gratis scripts, tips och tekniker för att göra din sajt snyggare och mer användarvänlig. Ett måste bland bokmärkena.

 

Länk: http://www.webappers.com

Nu är vår nya hemsida lanserad. Eftersom vi är stora förespråkare av Umbraco CMS så valde vi att bygga även vår egna sida med detta system som grund. Såhär ser det ut just nu när jag skriver detta blogginlägg.

 

Umbracocms -470-screenshot

 

För just vår hemsida har det inte krävts några enorma utbyggnader av Umbracos grund men vi har använt följande moduler:

 

 

Vi har också använt oss av den nya funktionaliteten med Razor-macron som är riktigt användbar och effektiv att arbeta med!

En intressant och användbar del av Umbraco är "Base", där används REST för att på ett enkelt sätt göra det möjligt att kommunicera med Umbraco, dels från Umbracosajten, men även från externa sytstem.

 

Mer info om Rest (Representational State Transfer) finns bland annat här: http://sv.wikipedia.org/wiki/Representational_State_Transfer

 

Det är sjukt enkelt att få REST att fungera i Umbraco.

  • Skapa en klass med statiska methoder som skall exponeras.
  • Lägg assemblyt i Umbracos bin-katalog
  • Konfigurera Umbraco-Base i filen "restExtensions.config"
  • Ös på

 

Exempel och mer info finns här: http://umbraco.org/documentation/books/introduction-to-base/simple-base-samples

Jag har vid ett antal tillfällen förbryllats över hur XSLT rendering från Umbraco, trots att sen nod-lista är korrekt sorterad i backend, inte visar noderna i den ordning som den "borde".

Jag har hela tiden använt mig av denna kod för att sortera mina noder i en XSLT-loop:

<xsl:sort select="@sortOrder" order="ascending" />

Detta fram tills att jag läst en bloggpost som sa att man borde skicka med datatypen.

<xsl:sort select="@sortOrder" order="ascending" data-type="number" />

Utan egenskapen för "data-type" så hanteras numren som strängar (läs: sorteras enligt dessa principer) men när man sätter datatypen till "number" så kommer sorteringen att bli korrekt.

Har precis hjälpt en kund som fick problem när deras webbhotell valde att uppgradera sina gamla windows 2003-servrar med ASP.NET 2.0 till Win 2008 och ASP.NET 3.5.

Det var flera fel som uppstod...

 

Inget ASP.NET Ajax Installerat

Det första felmeddelandet som visades var följande:

Assembly Load Trace: The following information can be helpful to determine why the assembly 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' could not be loaded.

Detta fel uppstår när Umbraco försöker att komma åt ASP.NET Ajax. Webbhotellet hade glömt, eller stuntat i att återinstallera detta på servern vilket gjorde att dessa assemblies behövde adderas till bin-katalogen. Att kopiera in följande filer löste problemet:

 

System.Web.Extensions.Design.dll

System.Web.Extensions.dll

 

Uppdatera Web.Config för att passa .NET Framework 3.5

Den nya servern körde .NET framwork 3.5 istället för 2.0 vilket gjorde att kunden ville köra Umbraco-instanserna i denna version. Detta kräver relativt stora ändringar i web.config. Läs mer om denna uppgraderingen här:
http://umbraco.org/26156

 

Lösenord fungerade inte i Umbraco Backend

På en av sajterna dök ett sista problem upp. Användarnas lösenord i backend fungerade inte korrekt efter uppgraderingen. De flesta umbracoinstanserna som kördes var 4.0.2.1 - den version där hashade lösenord infördes som standard. Den instans som krånglade körde version 4.0.0 så lösningen var enkel:

Lösenorden i databasen var inte hashade, men i den nya web.config-filen förutsattes att lösenorden var hashade. Följande ändring gjordes:

 

<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
             <providers>
                 <clear />
 
                <add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Another Type" passwordFormat="Hashed" />
                 <add name="AspNetSqlMemberShipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="LocalSqlServer" />
                 <add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
               </providers>
         </membership>

 

Blev till:

 

<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
             <providers>
                 <clear />
                 <add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Another Type" />
                 <add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" />
             </providers>
         </membership>

 

Dvs - passwordFormat="Hashed" raderades så att umbraco inte skulle försöka hasha lösenord när de ska matchas vid inloggning.

Har precis jobbat mycket med en Umbraco-lösning där jag också använder delar av AjaxControlToolkit (ACT). Detta kit skeppades för första gången av Microsoft omkring fyra-fem år sedan i sin första version, version 1.0.

Det är denna version som finns inkluderad i Umbraco 4.0.5 som jag använder i denna lösning.

Helt plötsligt, mitt under arbetet med mina UserControls och XSLT-macron upptäckte jag att backendsystemet slutat fungera. Trädvyerna expanderades inte på någon av "tabbarna", inte under content, inte media, ja ingenstans.

Jag rullade tillbaka en backup som var några månader gammal och upptäckte efter lite letande att jag refererat till en nyare version av ATC i ett av mina projekt - dessa projekt har post-build events som skriver över BIN-filerna i Umbraco-lösningen.

Dvs - Den nyare versionen (4.0) av ACT hamnade i bin-mappen på min skarpa lösning. Detta ställer alltså till problem med Umbracos backend. Jag rullade tillbaka ACT till version 1.0 vilket löste problemet.

Både XSLT macron och UserControls kan ha parametrar. Dessa kan skrivas i direkt i ko

 

<umbraco:macro alias="RenderProperties" paramvalue="Parameter direkt i kod" runat="server"/>
 

Eller så kan värdet hämtas ifrån andra delar av systemet. Tex ifrån den aktuella noden:

 

<umbraco:macro alias="RenderProperties" paramvalue ="[$pageTitle]" runat="server"/>

 

Det finns fyra andra källor för parameter-värden i Umbraco:

  • Page value: [#propertyAlias]
  • Page properties value: [$propertyAlias]
  • Cookie value: [%cookieValueKey]
  • Request collection  (tex QueryString): [@requestValueKey]

 

Flera värden, ibland kan man vilja ha flera värden och ta den första som faktiskt inte är noll då funkar detta:

 

<umbraco:macro paramvalue ="[#propertyAlias],[#propertyAlias2],my static string" />

 

Något som stört mig ett tag är att Firefox tenderar att vara sjukt långsamt när man debuggar Visual Studio-projekt via den inbygga webservern i VS.

En snabb googling gav mig denna tråd på grymma Stack Overflow: http://stackoverflow.com/questions/24959/debugging-asp-net-with-firefox-and-visual-studio-net-very-slow-compared-to-ie

 

Slutsatsen är helt enkelt att man måste inaktivera ipv6 i Firefox, enklaste sättet att göra det är följande:

 

  • Skriv about:config i Firefox adressbar, klicka ja på säkerhetsmeddelandet.
  • Skriv disableIPv6 i filterboxen högst upp och tryck enter. Inställningen "network.dns.disableIPv6" visas.
  • Dubbelklicka på "false" så att värdet ändras till true.

 

När dessa enkla steg är fixade går det tokfort att debugga med Firefox, vilket är supernice eftersom man då kan använda sig av bland annat Firebug.

Jobbar på en lösning som ska dela användare mellan en vanlig ASP.NET WebApplication och en Umbraco-Instans. Till detta skall även användarinfo kunna uppdateras med Batchar som hämtar XML-data och uppdaterar bla adressuppgifter och betalstatus.

 

Jag tittade närmare på två lämpliga lösningar och jag tänkte gå igenom dem här:

1. Användare i Umbraco

Spara användarna i Umbraco och jobba med dem via Umbracos API. Det visade sig att det var krångligt att få igång APIt utanför Umbraco-instansen och att allt arbete med användare och dess egenskaper i Umbraco är databasintensivt.

Ett möjligt alternativ vore att skriva direkt till Umbraco-databasen via webbappen, men alternativet känns inte aktuellt då Umbracos datastruktur är komlex och bör behandlas via dess API.

 

2. Användare i ASP.NET-applikationen

Skapa en skräddarsydd databas där användare sparas och sedan låta båda lösningarna hämta sina användare/roller från denna plats. Det innebär att jag måste skriva en ny MembershipProvider och RoleProvider till Umbraco, även att användarhanteringen i Umbracos backend inte fungerar fullt ut.

Lösningen

Trots arbetet med nya providers och det faktum att backend inte fungerar till 100% så valde jag lösning 2. Att ha full kontroll över användarens data och slippa avancerade databasstrukturer vid batchjobben var mer värdefullt än de få funktioner som inte fungerar i backend pga Custom Providers.

 

Upptäckte ett intressant problem med att använda divar i XSLT. Följande kod används ofta för att "cleara" divar när man kör dem flytande.

 

<div class="clear"></div>

 

I försökte använda den i ett macro, den låg "wrappad" i en annan div - såhär:

 

<div>
 
   <div class="clear"></div>
 
</div>

 

När denna proccessades av XSLT transormatorn i Umbraco så blev det renderades inte den sista stängningen av div-taggen. Jag löste det genom att köra följande kod:

 

  <div>

      <div class="clear">&nsbp;</div>

  </div>

 

Ibland vill man tex att Umbraco ska visa de 10 senaste posterna i en nod eller kanske de 10 senaste av en speciell document type.

Så här kan man använda XSLT för att begränsa antalet poster som lämnas från en for-each-loop.

<xsl:for-each select="$currentPage/node">

<xsl:sort select="@sortOrder" order="descending"/>

    <!-- xsl-if kollar att positionen är under 11 dvs, högst 10. Om så inte är fallet skrivs inget ut. -->

   <xsl:if test="position() < 11">

       <xsl:value-of select="@nodeName"/><br/>
   </xsl:if>
</xsl:for-each>



Såhär fungerar det:

<xsl:sort> Används för att sortera resultatet. Select-parametern anger efter vilket värde det skall sorteras och order-parametern anger om det skall vara fallande eller stigande ordning (ascending, descending).

 

XSLT-funktionen Position() returnerar nummet på den post som just nu bearbetars i loopen. Med hjälp av <xsl:if> anger vi att endast de fem första posterna ska visas, dvs poster som har ett värde under 10.

Tecknen &lt; och &gt; betyder samma sak som < och >, dessa tecken är skyddade i XSLT och måste därför ersättas med &gt; och &lt&, dvs greater than och lower than.

Jag har byggt ett system till en kund som arbetar med ljud och ljus. Kunden uppdaterar själv sidan med Umbraco 4.0.2. Sidan är uppbyggd med moduler med text, bild, bildspel, video osv. Dessa sorteras sedan och visas i den ordning som listan är sorterad.

 

En frustrerade sak som jag upptäckte var att Umbraco automatiskt lägger till en ny nod längst ned i nodlistan. Ofta vill man ju att nya inlägg/noder ska hamna högst upp. Att sortera i omvänd ordning blir ologiskt - noderna bör ju visas på samma sätt i nodlistan som på själva sidan. Problemet med att Umbraco lägger nya noder längst ned gör att man efter varje nytt inlägg måste sorta för att få de nya inlägget/noden högst upp.

 

För att komma runt detta och få mina nya noder att hamna högst upp skapade jag en metod som prenumererar på händelsen "umbraco.BusinessLogic.Actions.ActionNew()" som aktiveras när en ny nod har skapats. Läs mer om händelser i på umbraco.org.

Följande kod gör att en ny nod automatiskt hamnar högst upp i nodlistan istället för tvärtom:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using umbraco;
using umbraco.interfaces;
 
using umbraco.BusinessLogic.Actions;
using umbraco.BusinessLogic.console;
using umbraco.cms.businesslogic.web;
 
namespace em.umb.sortnewnode
{
   
    public class DefaultValueHandler : umbraco.BusinessLogic.Actions.IActionHandler
    {
        string umbraco.BusinessLogic.Actions.IActionHandler.HandlerName()
        {
            return "em.umb.sortnewnode";
        }
 
        umbraco.interfaces.IAction[] umbraco.BusinessLogic.Actions.IActionHandler.ReturnActions()
        {
            return new umbraco.interfaces.IAction[] { new umbraco.BusinessLogic.Actions.ActionNew() };
        }
 
       
        Boolean umbraco.BusinessLogic.Actions.IActionHandler.Execute(umbraco.cms.businesslogic.web.Document documentObject, umbraco.interfaces.IAction action)
        {
           
 
            // Getting the fist node.
 
            Document.GetChildrenForTree(documentObject.Id);
 
 
 
           // Creating a generic list of Documents
            List<Document> docs = new List<Document>();
 
 
 
            foreach(IconI d in documentObject.Parent.Children) {
                docs.Add(new Document(d.UniqueId));
            }
 

            // Sorting the list by sortOrder using Linq.
 
            var res = (from d in docs
                       orderby d.sortOrder ascending
                       select d);
 
 
 
           // Picking the first node
 
            Document firstDoc = res.First();
 
 
 
           // Setting sortOrder on the new node, by taking the first nod minus 5.
 
            documentObject.sortOrder = firstDoc.sortOrder - 5;
 
 
 
            return true;
 
        }
    }
 
}

 

Självklart är jag medveten om att man kanske vill kunna ställa in detta på katalognivå eller kanske confa det i web-config - har dock inte behövt denna funktionalitet. Lovar att återkomma med eventuella uppdateringar.

När innehåll från en html-editor skall visas i listor eller i andra flöden kan det vara smidigt att "stippta" eller radera/filtrera bort HTML-taggar.

 

Alltså detta:

<h1>Hello World</h1>
<p>I´m here</p>

Blir till:

Hello World
I´m here

Hur gör man då? Faktum är att lösningen är väldigt enkel. Jag skapade en egen c-sharp funktion som kör ett regex och sedan beräknar längden på inlägget för att veta om det skall kortas ned eller inte:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxml="urn:schemas-microsoft-com:xslt"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:umbraco.library="urn:umbraco.library"
 xmlns:em="urn:em"
 exclude-result-prefixes="msxml umbraco.library">


<xsl:output method="xml" omit-xml-declaration="yes" />

<xsl:param name="currentPage"/>

<!-- ******* SCRIPTS STARTS HERE *********** -->

<msxsl:script language="CSharp" implements-prefix="em">
<![CDATA[

// Removes all HTML-taggs from parameter-string

public string generatePreview(string strHTML) {
 
 // Setting default string-length
 int intDefaultLength = 200;

// Removing HTML-tags using regex
 strHTML= Regex.Replace(strHTML, "<[^>]*>", String.Empty);

 
 if(strHTML.Length > intDefaultLength) {
  return strHTML.Substring(0,intDefaultLength) + "...";
 }
 else {
  return strHTML;
 }
}

]]>
</msxsl:script>

 <!-- ******* SCRIPTS ENDSHERE *********** -->

 

<xsl:template match="/">

<!-- The fun starts here -->

  <p><xsl:value-of select="em:generatePreview($currentPage/data [@alias = 'HTMLContent'])" disable-output-escaping="yes"/></p>

 

</xsl:template>

</xsl:stylesheet>


Självklart kan man,  om man vill skapa och kompilera sin egen extension till XSLT, då kan man ha med denna funktionalitet i sin extention. Detta är att föredra om man ska använda funktionen på många olika XSLT-mallar.

När man lägger till en ny stillmall (CSS) i Umbraco viasas den inte automatiskt när du redigerar innehåll i WYSIWYG-editorn TinyMCE.

För att stillmallen ska "slå igenom" och synas i editorn måste man kryssa för stillmallen i developer-delen.

 

  • Gå till Developer
  • Öppna upp "Data Types" och klicka på "Richtext editor".
  • Kryssa i de stilmallar du vill ska synas i editorn under "Related stylesheets".
  • Spara och nu är det bara att köra.
  • TIPS: Skapa en speciallstillmall om du tex vill ha en annan bakgrund i editorn än på själva sidan. Denna stilmall använder endast i editorn, inte i själva HTML-koden.

 

 

Datatypes _richtext _css

Umbracos inbyggda texteditor "Richtext editor" som baseras på TinyMCE 3 har en dropdown som heter "Choose style".

 

Choose _style _dropdown

Standardinställningen i TinyMCE är att alla klasser i de stillmallar som är bundna till editorn ska visas i dropdownen. Eftersom det oftast finns massa klasser i dessa stilmallar som man inte vill ska synas i listan har Umbraco en annan lösning.

Så här fixar du en ny klass i listan "Choose style"

  • Klicka dig till "Settings" och expandera "Stylesheets". Välj en av de stillmallar som visas i Umbracos Richtext editor.
  • Högerklicka och välj "Create" för att skapa en ny under-klass.
  • Döp den nya stilen till önskat namn, i rutan "styles" kan du sedan skriva CSS-markup.
  • Denna markup syns inte automatiskt i editor, du måste också lägga till denna markup i din stillmall. I detta fell i mallen screen.

 

Datatypes _richtext _css

Ett tips för dig som utvecklar umbraco-lösningar är såklart att använda Visual Studio.

Umbraco har ju möjligheta att redigera XSLT, CSS, JavaScript och även HTML-mallar i sitt admingränsnitt.

Däremot missar man ju debugging och mycket annat som kommer tillsammans med Visual Studio.
Om du vill utveckla och debugga med Visual Studio 2008, gör såhär:

 

1. Skapa en ny Umbraco-installation

Ställ in databas-koppling, rättigheter osv. Filerna kan tex hamna i c:\inetpub\wwwroot\umbraco

 

2. Skapa ett nytt "Website Application Project"

Detta projekt ska skapas i en annan mapp än din umbraco installation.

Lägg till de mappar för de filer du vill kunna arbeta med. Jag har följande:

    * /css
    * /scripts
    * /xslt
    * /masterpages
    * /usercontrols

 

3. Lägg till ett "Post Build Event"
Detta körs efter att projektet har kompilerats. Syftet är att vi ska kopiera filerna från vår Web Application till vår Umbraco installation.

Klicka på "Soulution>Properties>Build Events" och lägg till följande kod under "Post Build Events" - alltså det som sker när projektet är kompilerat.

XCOPY "$(ProjectDir)bin\$(ProjectName)*.*" "C:\Inetpub\soundforce - umbraco4\bin\" /y /S
XCOPY "$(ProjectDir)usercontrols\*.ascx" "C:\Inetpub\soundforce - umbraco4\usercontrols\" /y /S
XCOPY "$(ProjectDir)xslt\*.xslt" "C:\Inetpub\umbraco4\xslt\" /y /S
XCOPY "$(ProjectDir)css\*.css" "C:\Inetpub\umbraco4\css\" /y /S
XCOPY "$(ProjectDir)scripts\*.js" "C:\Inetpub\umbraco4\scripts\" /y /S
XCOPY "$(ProjectDir)\*.pbd" "C:\Inetpub\umbraco4\" /y /S


Parametern /y gör att filer skrivs över, och /S att även underkataloger inkluderas.

 

4. För att debuga

    * Öppna siten i din webbläsrae
    * I Visual Studio väljer du Debug > Attach to Process och väljer w3wp.exe från listan. (På IIS on XP/2000 heter proccesen asp_net.exe).
    * Var noga med att *.pbd-filerna kopieras till umbraco-installationen.
    * Debugga för fulla muggar!