torsdag 20 mars 2008

Umbraco CMS

Detta inlägg kommer handla om Umbraco CMS
Umbraco är ett content management system och på svenska ett webbpubliceringssystem där man har ett webbadministrationssystem av typen WYSIWYG (What You See Is What You Get).
Umbraco är ett Open Source projekt som släpptes 2004'a. Grundaren till Umbraco är dansken Niels Hartvig. I april 2007 hade omkring 25000 webbsidor med en grund Umbraco's CMS och detta gör Umbraco till toppen för de 15 mest populära .NET Open source applikationer och troligen den mest använda CMS för ASP.NET. Umbraco källkod är skrivet i C#.
Umbraco's officiella webbsida

Umbraco skryter själv med en hel del men framför allt givetvis att det är gratis och just enkelheten över själva applikationen och installationen av den. Samt att Umbraco erbjuder funktionalitet där man skulle behöva betala större pengar för samma funktionalitet.
Det ska vara väldigt enkelt att själv bygga ut systemet med egna .NET kontroller och använda xslt för att rendera ut information.
Detta låter ju väldigt lovande med egna kontroller men om man vill göra mer än så då?
"Even though you always have access to the umbraco source code, you’ll never need it to extend umbraco. A clever combination of interfaces and automatic discovery through reflection allows you to customize umbraco to satisfy even the most advanced requirements."

Alltså kan vi utesluta att vi inte behöver källkoden för att själv kunna bygga ut eller vidare på Umbraco standard installation men är det verkligen så lätt gjort som sagt. Källkoden hittar man för övrigt på codeplex

För redaktörer så är Umbraco ett lovande alternativ som levererar det mesta. Några av dessa punkter som Umbraco har valt att ta upp på deras webbsida är dessa.
  • Beautiful, user friendly interface
  • Integrated, customizable WYSIWYG editor
  • Unlimited content versioning with full rollback
  • Scheduled publishing
  • Advanced permission model
För designers hittar vi dessa punkter..
  • No limits to design
  • Super simple template engine
  • Full support for web standards
  • Full support for accessibility standards
  • Full support for semantic web
  • Full support for Ajax frameworks like Script.aculo.us or ASP.NET Ajax
    Integrated CSS support
  • Integrated web editors for templates, javascript files and css
Men det mest intressanta kanske är för oss utvecklare att se vilka möjligheter vi har.
  • Full .NET Support
  • Full documented API
  • Full source code freely available
  • Clear separation of businesslogic and presentation (MVC)
  • Easy integration of existing .NET User and custom controls
  • Support for any .NET Language including c# and VB.NET
  • Extremly extensible object model
Jag är nyfiken på hur bra APIt är dokumenterat och vilken hjälp man har att sätta sig in i Umbracos kod för att kunna vidare utveckla egna funktioner utöver de User controls som man kan integrera. Men efter en titt i dokumentationen så bekymrar det mig är att dokumentationen för hur Umbraco fungerar och för hur jag som utvecklare skall kunna utveckla vidare är bristande. APIt är någorlunda detaljerat dock men inte lärande. Men sektionen för 'Books' på Umbraco's webbsida så är det inte många artiklar vars känns riktigt genomgående och fulländade, en del är t.o.m. ej avslutade.

För att få extra hjälp på vägen jag finner även att Umbraco har sitt eget Google community. Även en wiki book som kan komma till hjälpen.

En intressant sak som Umbraco framför är att deras CMS är omptimerat för SEO, Search Engine Optimization eller Sökmotor optimering. Alltså göra sidorna optimerade och "vänliga" för sökmotorer.

Till den vanliga installationen kan man även sedan utöka Umbraco med form av packages vilket går att finna på package sidan. Dessa skall vara någorlunda lätta att installera.

Men nu för att ta reda på det mesta sagda ovan så skall vi börja med att installera Umbraco.
För en full guide av installation för Umbraco 2.1.1 hittar du här.

Det finns några minimum krav för systemet där Umbraco v3.0 skall köras på och för mjukvaran står dessa för:
Microsoft IIS 5+, MSXML, .NET Framework, ASP.NET 2.0 AJAX Extension 1.0, SQL Server 2005 Express
, SQL Server Management Studios Express.
Dessutom en del hårdvara krävs:
  • 1 GHz or faster processor
  • 512 MB or more memory
  • 2 GB or more available disk space
  • SVGA (1024 x 768) or higher monitor resolution
  • Internet Explorer 6 or higher
Normalt så är dessa redan installerat på servern förhoppningsvis där du möjligen har på ditt webhotell så då behäver man inte oroa sig mer utöver detta. Men för mig som skall installera på min dator så blir det några extra steg.

Umbraco (v3.0.3) .msi installer fungerar bara för Windows Vista och Windows Server 2003 som jag helt missade vid nedladdnings sidan hos Umraco, så jag blev lite ställd till felmeddelandena jag stötte på. Så då kan det se ut såhär..

Istället laddar man hem en zip fil som man packar upp på lämpligt ställe ex 'c:\interpub\wwwroot'
För en full documentation hur man installerar Umbraco v3.0 och uppåt finns här att att läsa.
En viktig sak är att man i alla fall skapar en Databas för Umbraco och redigerar web.config filen för databas uppkopplingen även om man kör på webhotellet, detta är nödvändigt.

Efter en del tjafs med min IIS så fick jag fram tillslut configurations wizarden. Oftast innebär det lite extra jobb när man redan har installerat IIS tidigare och ändrat om en massa inställningar så det är värt att tänka på. Sedan är det bara att öppna sökvägen till default.aspx där installationen skedde och eftersom jag installerade lokalt på c:\interpub\wwwroot så kunde jag enkelt gå in på http://localhost/

Allt gick nästan perfekt i installationen så som man vill att det ska vara vid installation. Dock så hade jag hade glömt att ändra permission för web.config filen så den även kunde ändras men detta var inget problem att ändra om själv sedan då detaljerna i felmeddelandet var väldigt bra.

Här får man nu möjlighet till att installera Open Source Starter Kits vilket man finner i Umbraco's packages. Vid detta skrivande tillfälle så finns det 3st: Creative Web Site Package, Blog, WebsiteWizard.
När vi väl startar upp umbracos kontroll panel vilket man hittar default i Umbraco katalogen. Där ser vi att det inte finns mycket att göra just nu. Men det finns ingen oro att man inte kommer ha att göra då man faktiskt måste lära sig hur Umbraco fungerar i praktiken om man vill utöka med funktionalitet vilket är nästan ett måste. Det är svårt att veta vart man skall börja men ett tips är att installera de packet som finns att tillgå redan från start.

Jag tar och installerar Umbraco Website Wizard Version: 1.0 från packages. För övrigt så skulle jag välja att utgå från början med ett starter kit. Antingen Website wizarden eller Creative Web Site Package och sedan ta bort sidorna man inte vill ha som följer med eller eventuellt redigera dem. Installationen var väldigt enkelt att utföra. Det var bara klicka sig fram direkt genom en webb ruta och på någon sekund så är det klart. En default look för Umbraco ser nu ut såhär:

En sak som jag irriterar mig mycket på är default fonten som dem har valt att ha men detta går ju givetvis att ändra på vilket man upptäcker ganska snabbt att man har möjlighet till efter man tittat igenom alla admin sektioner som finns att tillgå.

Användar gränssnittet för Umbracos CMS är verkligen rikt på administrations möjligheter. Det mesta nödvändiga och lite till kan man göra. Det finns möjlighet att separat skriva in meta datat för varje sida vilket gör det vänligt för SEO. Men vi ser även att URL taggarna är även snyggt skrivna och sökmotors vänliga. Varje huvudsida har även en template kopplad till sig. Det finns ett litet mindre verktyg för formatering av text man skriver på webbsidan. Under settings sektionen så hittar man även alternativ för att ändra html koden på sidorna, css filer, skript etc. Härifrån är det inge möjligt nu att skapa sin egen layout och sedan bara infoga Umbraco's items som är nödvändiga som hanterar informationen i templaterna...

Umbraco - Main Template HTML<!doctype html public "-//w3c//dtd xhtml 1.0 strict//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd">
<html>
<head>
<title><?UMBRACO_GETITEM field="siteName" recursive="true"/> - <?UMBRACO_GETITEM field="pageName"/></title>
<link rel="stylesheet" href="/css/wizard.css" type="text/css">
<link rel="stylesheet" href="/css/umbracoAutoForm.css" type="text/css">
<LINK rel="stylesheet" type"text/css" href="/css/wizardPrint.css" media="print">
<META NAME="Keywords" CONTENT="<?UMBRACO_GETITEM field="keywords"/>" />
<META NAME="Description" CONTENT="<?UMBRACO_GETITEM field="description"/>" />

</head>
<body>
<?ASPNET_FORM>
<div id="container">
<div id="main">
<a href="/" title="Back to front page" id="header" style="background: url(<?UMBRACO_GETITEM field="headerImage" recursive="true"/>)">
</a>
<div id="naviHolder" style="background: url(<?UMBRACO_GETITEM field="topBg" recursive="true"/>)">
<?UMBRACO_MACRO macroAlias="WizardTopNavigation" ></?UMBRACO_MACRO>
</div>
<div id="content">
<?UMBRACO_TEMPLATE_LOAD_CHILD/>
</div>
<div id="bottom"><?UMBRACO_GETITEM field="footer" recursive="true"/></div>
<div id="bottomShadow"><br/></div>
</div>
</div>
<a title="Visit the umbraco.org site" href="http://umbraco.org" style="font-size: 10px; text-decoration: none; color: #999">Powered by umbraco</a>
</?ASPNET_FORM>
</body>
</html>

Koden ovan är kopierad rakt av från Main templaten. Och som man kan se så är det inte direkt någon större skillnad från vanlig html. Det intressanta hittar vi i de speciella taggarna som börjar med '<?'. Dessa är Umbraco egna taggar som hämtar information till templaten med inbyggda eller egna Macros. Dessa macros är uppbyggda vanligen i xslt men även i .NET kontroller och phyton. Det går givetvis att skapa egna macros och xslt funktioner samt binda dem till kontroller. Dessa Macros går att hitta i Devlopment sektionen.

Det finns även sektioner för att hantera användare och grupper.

Jag tänkte tydligare göra hur Templaten fungerar.
Det finns en så kallad Master Template installerad som kallas Main. Den består vanligtvis av child nodes och skapar en viss struktur för alla sidor. Det går att ha flera Master templates ifall man vill att en sida skall se annorlunda ut i layouten men då måste man oftast med detta ange en annan CSS fil. En enkel master template kan se ut såhär.

Enkel Template - Main<html>
<head>
<title>
<?UMBRACO_GETITEM field="pageName"/>
</title>
</head>
<body>
<?UMBRACO_TEMPLATE_LOAD_CHILD/>
</body>
</html>

Låt oss utgå ifrån den ovan och att den kallas Main och att vi befinner oss i Settings sektionen.

"<?UMBRACO_GETITEM field="pageName"/>" Denna förekommer vanligen på alla sidor där vart den anger titel för sidan.

"<?UMBRACO_TEMPLATE_LOAD_CHILD/>" Talar om vart child noden skall placeras in.

Och sedan om vi skapar en ny template som heter Test och fyller i en enkel html kod
"<p>Hej hopp</p>". Vi anger även ett Name: Test, Alias: wwTest och anger även en master template som är i detta fall den ovan kallad Main. Där sparar vi.

Sedan kan vi skapa en ny Document Type eller välja ur en befintlig. Om vi väljer att skapa en ny så högerklickar vi på Document Type och väljer Create. Sedan fyller vi in nödvändig information. Namn: Test och Alias wwTest. Kryssa i Allowed Template Test och default Test om inget annat anges. Vi kan även välja att ange i en annan Document Type så som i Frontpage att ange Test som en child node för att sedan nedan kunna lägga till ett sådant typ av dokument.

Sedan går vi till Content sectionen och väljer att skapa ett nytt dokument genom att högerklicka på Frontpage mappen och väljer Create. Vi väljer från drop down listan Test som template och skriver in ett namn på Sidan i detta fall även där Test.

Vi sparar sidan och publiserar den. Den genererade källkoden bör bli följande.


<html>
<head>
<title>
Test
</title>
</head>
<body>
<p>Hej hopp</p>
</body>
</html>

Jag tänkte även testa att installera andra packet. Jag börjar med att ta hem MemberControls från packages. Detta packet ger mig 3 macros med..
  • Member Login: Basic Login/Logout functionality
  • Member Signup: SignUp Form with custom membertype and groups
  • Member Password Reminder: A simple password reminder via e-mail
När man tar hem packetet först så funderar man hur fasiken ska jag installera detta då? Eftersom de inte står tydligt några installations instruktioner så kan detta va väldigt förvirrande men efter ett tag sökandes så finner jag att om man går in på Development sektionen och högerklickar på Macros och väljer sedan Import package. Därefter dyker en ny ruta upp vart man väljer packet. Det är viktig att packetet du tog hem har filändelsen .umb och inte zip som de kan laddas ned som och i sådana fall om de har .zip så döper du bara om dem. Nu när det är installerat så är det dags att foga in detta Macro till en template. För att testa detta så lägger jag bara in MemberLogin macrot i Main templaten med hjälp av 'Insert Umbraco Macro' knappen för Main templaten i Settings sektionen.
Dennna rad kod lades till " <?UMBRACO_MACRO macroAlias="MemberLogin" LogOutOnly="0" LoggedInText="Du är nu inloggad" SignOutLinkText="Logga Ut" > </?UMBRACO_MACRO>".

Jag tar mig en titt på sidan och ser att jag nu har en login kontroll där. Men utan användare kan man inte logga in så jag väljer även att skapa en ny Template kallad Singup. I Singup infogar jag MemberSingup Macron. Sedan skapar jag även ett nytt Document Type kallat Singup och konfigurerar det efter behov. Jag väljer Frontpage document typen under structur fliken att tillåta Singup som en child node. Nu kan jag ska ett nytt dokument under Content sektionen och kallar det Singup med typen Singup. Om vi tar en titt på resultatet så ser det ut nu såhär.

Det fungerar utmärkt att skapa en ny användare. Kontrollerna i sig är inte så anpassad just för svenska men något större problem är det inte i sig för det går att ändra genom att öppna kontrollerna i tex visual studio. Däremot kan vi inte ändra något i cs koden för dem men efter redigering i presentations lagret så ser det bättre ut.

Det fungerar nu att logga in med en användare.
Vi har även nu möjlighet med detta packet att sätta restriktioner från vilka dokument eller mappar användare eller grupp skall kunna ta del utav.

Man kan säga att XSLT (eXtensible Stylesheet Language Transformations) är en avikelse i Umbraco. Men det är själva xslt funktionerna som gör Umbraco dynamiskt för med xslt hämtas information från en XML fil som renderar upp innehållet och strukturen med mera. Macros i Umbraco kan vara uppbyggda av xslt. Man kan säga att det är en fördel om man redan kan XSLT som utvecklare ifall man tänkt bygga egna Macros, annars är det givetvis relativt lätt att lära sig för en nybörjare. XPath är en nödvändig del att använda i XSLT filen för att kunna kommunicera och hämta information från XML filen. Efter att man lärt sig förstå XSLT så är XPath en viktig del att även förstå sig på för att sedan kunna skriva egna kraftulla XSLT filer.Det finns en väldigt bra skriven artikel på Umbracos webbsida som förklarar hur Umbraco fungerar med XSLT.
En till källa för att se exempel med XSLT hittar du i wiki boken.

Jag hade tänkt att installera XSLT Search packetet från packages. För en full guide över hur vi nu kan implementera XSLT search finner du i wiki boken. Eftersom den guiden är för en äldre version så kommer den inte fungera med den nyare XSLT search 2.7. Men med XSLT Search 2.7 så kommer det följa med liknande template, document, type och content som är färdigt.
Vad jag gjorde var att jag installerade paketet och skapade en document type och ny template anpassat till en ny Sök sida. Med samma tanke som i wiki bok guiden fast nu fick vi mycket gratis på vägen. Sedan skapar jag en ny content sida kallat SearchPage. Det intressanta hittar vi i SearchPage templaten.

SearchPage Template
<div id="textContent">
<h1>Sök</h1>
<?UMBRACO_GETITEM field="bodyText"/>
<br />
<?UMBRACO_MACRO
macroAlias="XSLTsearch"
source="-1"
searchFields="@nodeName,metaKeywords,metaDescription,bodyText"
previewFields="bodyText,metaDescription"
previewType="beginning"
searchBoxLocation="bottom"
resultsPerPage="5"
previewChars="255"
showPageRange="1"
showOrdinals="0"
showScores="0"
showStats="1"
>
</?UMBRACO_MACRO>
</div>

Som vi kan läsa av ovan så har jag satt in en Richtext editor i Document Typen 'Search Page' vart man kan fylla i lite jadder. Sedan har jag infogat XSLTsearch Macrot med diverse inställningar. Mer än så behövdes det inte för att funktionen skall fungera. Men eftersom jag vill ha en svensk text på min sök funktion så går jag in i XSLT filen XSLTsearch.xslt som man hittar i developer sektionen. Därifrån ändrar jag den engelska texten till svenska som man hittar någonstans i den djupa djungeln. Och resultetet blev detta..

Denna sök funktion kan man naturligtvis modifiera exakt hur man vill men det är en väldigt genomtänkt funktion redan så jag anser inte att några större modifikationer behövs. Och givetvis går Macrot att lägga in i Main templaten så man har den medföljandes över alla sidor men då skall man även tänka på att det behövs utrymme för resultatet som visas. Man kan nog även lägga till en del CSS på detta om man vill men det blev relativt snyggt genom att jag la in Macrot och det övriga i Search Page templaten inom en div tagg med grund ID 'textContent'.

Hit tills har jag installera, implementerat och modifierat 3 packages: Website wizarden, MemberControls och XSLT Search. Alla dessa 3 är sjävlklart Open Source packet. Men jag känner nu att jag skulle vela implementera något eget från grunden. Jag väljer därför att skapa ett eget XSLT Macro.

Det jag hade tänkt att göra (vilket var redan där svårt att komma på något improvisatoriskt) var att man kunde ladda upp filer till en viss sida men detta fungerade inte riktigt så bra som jag hade tänkt att det skulle göra. Jag använde mig av Uploader egenskapen i Document Type för ett nytt dokument kallat Uploader. Denna visar sig vara bättre då man bara skall bifoga en fil i dokumentet då det var endast begränsat till en fil. Men det är ju möjligt givetvis att lägga till flera sådana egenskaper men i längden så är det ingen bra idé. Jag skapade i alla fall ett nytt Document Type kallat Uploader samt en Template till den. Jag gjorde en ny XSLT fil bunden till ett macro med den följande koden nedan.

SearchPage Template<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [
<!ENTITY nbsp "&#x00A0;">
]>
<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:picture="urn:picture"
exclude-result-prefixes="msxml umbraco.library picture msxsl">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<msxsl:script language="CSharp" implements-prefix="picture">
<![CDATA[
public string getName(string str)
{
str = str.Substring(str.LastIndexOf("/") + 1);
str = str.Remove(str.LastIndexOf("."));
return str;
}

public string getFileType(string str)
{
str = str.Substring(str.LastIndexOf(".") + 1);
if(str == "jpg" || str == "gif" || str == "bmp")
{
str = "pic.jpg";
}
else if(str == "zip" || str == "rar" || str == "tgz")
{
str = "comp.jpg";
}
else if(str == "pdf")
{
str = "acro.jpg";
}
else
{
str = "doc.jpg";
}

return str;
}
]]>
</msxsl:script>
<xsl:template match="/">
<h2>
<xsl:value-of select="$currentPage/@nodeName"/>
</h2>
<table>
<xsl:for-each select="$currentPage/data [@alias='Uploader']">
<tr>
<td>
<img>
<xsl:attribute name="src">
/images/<xsl:value-of select="picture:getFileType(current()/text())"/>
</xsl:attribute>
<xsl:attribute name="height">15px</xsl:attribute>
<xsl:attribute name="width">20px</xsl:attribute>
</img>
</td>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="text()"/>
</xsl:attribute>
<xsl:value-of select="picture:getName(current()/text())"/>
</a>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

Som man kan se så var det tänkt att jag skulle hämta ut all data med Alias Uploader. Vilket kanske var felaktigt tänkt då vi är intresserade av alla text noder som i alla fall bara blir begränsat till en med Uploader egenskapen. Där renderar jag ut informationen i en tabell med början av att jag renderar ut en bild icon för typ av fil och sedan namnet på filen utan filändelse i en tabell. Med text informationen från det hämtade datat så skickar jag in det i 2st value-of som anropar ett skript skrivet i C#. Lyckligtvis så kan XSLTn hantera skript språk så som C# och Javascript vilket kan få oss att undvika att skapa en User eller Custom control för de jobbet.
Jag skapade sedan en Content fil kallad Uploader även den och under egenskaper laddade jag upp en bild fil. Resultatet blev i alla fall detta vid presentation.

Det fungerade ju i alla fall att rendera ut informationen ur XML filen med hjälp av XSLT.

Nu när jag har testat att skapa ett Macro i XSLT är det nog även läge för att se möjligheterna i en .NET control istället.
Jag valde att skapa en User Control med en funktion som liknade ovan med XSLT. Min tanke var att jag skapar en kontroll var man kan ladda upp filer till en mapp. Det var inget mer speciellt än att jag skapade en ny webbsida och sedan en ny Web User Control. I den skrev jag som vanligt min funktionalitet mot asxc filen från code behind filen. Filernas källkoder ser ut enligt följande.

Control.asxc
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Control.ascx.cs" Inherits="UmbracoControl.Control" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<asp:Label ID="lbl_uploader" runat="server" Text="" />
<div id="uploaderContent">
<fieldset>
<legend>Ladda upp fil</legend>
<asp:FileUpload ID="FileUpload1" runat="server" /><br />
<asp:Button ID="btn_upload" runat="server" Text="Ladda upp" OnClick="button_Upload" /><br />
</fieldset>
<fieldset>
<legend>Filhanteraren</legend>
<asp:GridView ID="GridView1" runat="server" GridLines="None" CellPadding="2" AutoGenerateColumns="False" DataKeyNames="FullName" Width="100%">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkBox" runat="server" />
<asp:Label ID="lbl_value" runat="server" Visible="false" Text='<%# Eval("FullName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField DataTextField="Name" CommandName="Select" HeaderText="Namn" SortExpression="Name" />
<asp:BoundField DataField="CreationTime" HeaderText="Skapad" />
<asp:BoundField DataField="LastWriteTime" HeaderText="Senast &#196;ndrad" />
</Columns>
</asp:GridView>
<asp:Button ID="btn_delete" runat="server" Text="Ta bort" OnClick="btn_delete_Click" />
</fieldset>
</div>


Control.asxc.cs
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
//Använd Umbraco för tillgång till data
using umbraco.presentation.nodeFactory;
using System.IO;

//Ett namespace jag valt att kalla UmbracoControl
namespace UmbracoControl
{
public partial class Control : System.Web.UI.UserControl
{
private Node currentNode;
private int maxFileSize;
private string uploadDir;
private string mimeType;

protected void Page_Load(object sender, EventArgs e)
{
//Ladda in informationen för denna XML sida
currentNode = Node.GetCurrent();
//Max storlek på filen som laddas upp (4Mb)
maxFileSize = 1024 * 4000;
//Sökväg till filmappen
uploadDir = Server.MapPath("./files");
if (!IsPostBack)
{
//Visa aktuella filer
ShowDirectoryContents();
}
}

private void ShowDirectoryContents()
{
//Hämta DirectoryInfo från mappen
DirectoryInfo dir = new DirectoryInfo(uploadDir);
//Hämta filer
FileInfo[] files = dir.GetFiles();
//Visa innehållet i mappaen
GridView1.DataSource = files;
//Om inga filer i mappen kunde hittas
if(files.Length <= 0) { ArrayList arr = new ArrayList(); arr.Add("Inga filer kunde hittas"); GridView1.DataSource = arr; } GridView1.DataBind(); //Ta bort 'SelectedIndex' ifall det finns någom GridView1.SelectedIndex = -1; } // När en fil uppladdas... protected void button_Upload(object sender, EventArgs e) { if (FileUpload1.PostedFile.ContentLength != 0) { try { //Validering på filen if (FileUpload1.PostedFile.ContentLength > maxFileSize)
lbl_uploader.Text = "Filen du försökte ladda upp var för stor, max storleken är: " + maxFileSize + "bytes";
else
{
//Filnamn
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
//Skapa sökväg(säker)
string destPath = Path.Combine(uploadDir, filename);
//Spara filen
FileUpload1.PostedFile.SaveAs(destPath);
lbl_uploader.Text = "Filen laddades upp!";
//Visa aktuella filer
ShowDirectoryContents();
}
}
catch (Exception ex)
{
lbl_uploader.Text = ex.Message.ToString();
}
}
}

//Knapp för att ta bort mappar och filer
protected void btn_delete_Click(object sender, EventArgs e)
{
// Kontrollen är initierad och bunden här - Hämtar en collection av raden
GridViewRowCollection rows = GridView1.Rows;

foreach (GridViewRow row in rows)
{
//ref, hämta värde.
CheckBox cb = row.FindControl("chkBox") as CheckBox;
if (cb.Checked)
{
//Hämta värdet ifrån en gömd label
Label lbl = row.FindControl("lbl_value") as Label;
//Testa att ta bort Filen
try
{
File.Delete(lbl.Text);
lbl_uploader.Text += "Filen togs bort!";
ShowDirectoryContents();
}
catch (Exception ex)
{
lbl_uploader.Text += "Filen kunde ej tas bort!" + ex.Message ;
}
}
}

}
}
}

Inte så mycket mer speciellt över detta än att jag har angett ett eget namespace och en intressant detalj hittar vi i code behind filen. "using umbraco.presentation.nodeFactory;" Detta måste vi ange för att kunna hämt ainformation om den nuvarande sidan. Samma information som vi har att tillgå till som i XSLT funktionen för sidan. För att få detta fungera skiljer det sig inte från XSLT med implementationen i det i templatenm, Document typen och Content pagen. I developer sektionen så är ett Macro skapat precis som i XSLT funktionen vi gjorde men denna gång behöver vi inte skapa någon fil utöver det i administrations panel som vi gjorde i XSLT funktionen genom att skapa en ny XSLT fil. Vi reffererar från Macro funktionen till en .NET Kontroll. Enligt följande.

Med följande får vi detta resultat.

En väldigt simpel uppladdnings funktion liknande den som i XSLT fast den var egentligen tänkt då genom administrations panelen ladda upp filer. Fast i det fallet med XSLT gick det ju tyvärr bara ladda upp 1 fil. Det finns möjlighet till att bygga om cs filen till en dll och placera dll filen i Bin katalogen ifall man vill men det är inget jag valt att göra. Vad som händer då är att man gör om sin User Control eller Server till en Custom Control. Detta kan vara bra för att det ska bli enklare att distribuerar sin control samt inkapsla, innesluta den. En guide till hur man gör detta finns att tillgå på Codeproject.
Vi hittar även ett PDF dokument hos Umbraco som beskriver hur man skapar och använder sin egen .Net Control, dock så är detta dokument lite bristande. Där går de även igenom hur man kan använda parametrar till sin .NET Control vilket kan va väldigt intressant.

Användningsområdena för XSLT och respektive .Net Control skiljer sig. För en enklare funktion känns det väldigt onödigt att börja skapa en Control då XSLT väl kan fungera lika bra. .NET kontrollen känns mer tillämpad när det gäller mer avancerade funktioner samt om man ska vidare distribuera dem. Att vidare distribuera dem är inget större problem heller då man skapar en xml fil som anger vart filerna skall placeras i den befintliga installationen samt egenskaper och inställningar. Den xml filen skall packas ihop med diverse övriga filer. Paketet döps sedan om med filändelsen 'ubm' för att Umbraco skall kunna läsa den.

Nu har jag tittat på hur man kan bygga ut Umbraco med sin egen funktionalitet.
Jag tycker det blir dags här att sammanfatta lite av vad jag har gått igenom.

Umbraco skryter själv med en hel del men framför allt givetvis att det är gratis och just enkelheten över själva applikationen och installationen av den. Samt att Umbraco erbjuder funktionalitet där man skulle behöva betala större pengar för samma funktionalitet.
Det ska vara väldigt enkelt att själv bygga ut systemet med egna .NET kontroller och använda xslt för att rendera ut information.
Detta låter ju väldigt lovande med egna kontroller men om man vill göra än så då?

Jag undrade i början hur mycket mer man kunde bygga ut Umbraco utöver .Net kontroller och xslt funktionalitet men här blir vi väl begränsade till att endast kunna göra det för att ligga inom ramarna för CMS. Annars skulle vi behöva använda oss av källkoden för att därifrån kunna bygga ut bredare. Dock så ser jag inte just nu något behöver att göra det då möjligheterna med att lägga in sina egna kontroller täcker det mesta. Det kanske känns omständligt i vissa fall med att man blir tvungen till att göra såhär.

Till de punkter vars Umbraco vill framföra dem som ett alternativ kan jag hålla med på att de punkter jag skrev i början stämmer väldigt bra. En mindre nackdel som jag upptäckte med administrations panelen var att WYSIWYG editorn med dess panel ovan inte var helt komplitabel med Firefox. Det fanns även andra funktioner där vars Firefox inte svarade på. Därför valde jag efter ett tag att arbeta med Internet Explorer 7 i administrations panelen. Det är lite synd med tanke på att man kanske inte just har möjlighet att använda IE7.

En sak som jag känner att Umbraco bör satsa på är bättre dokumentation för hur en utvecklare skall kunna sätta sig in i applikationen. Detta är lite en form av en djungel att kunna sätta sig in i den. Det fanns ett par bra artiklar eller boks som Umbraco vill kalla dem men många av dem var av sämre innehåll och en del inte fulländade. APIt behövde jag dock inte titta desto mer i. Jag har även tittat en del i källkoden för Umbraco och vad jag känner så är det som att gå in i en kod djungel utan man har direkt någon aning om vilken ände man skall börja ifrån. Jag kunde ej hitta något material som beskrev hur Umbraco är uppbyggt i käll kod och vart man som ny utvecklare kan börja sätta sig in i. Det är bristande helt enkelt på en komplett dokumentation för en nybörjare att sätta sig in i systemet.

Det tar även tid att lära sig Umbraco. Man vill gärna mer än vad man kan från första början så det blir en hel del testande och mer eller mindre läsning även för att förstå. Jag råder dig som vill använda Umbraco och göra egna funktioner att verkligen sätta dig ned och läsa igenom all information som kan kännas betydelse full. Jag har länkat ovan till det mesta betydelse fulla artiklarna och i wiki books kan man hitta ett par fina exempel men däremot får man se upp för att de kan ha utgått sitt bäst före datum så att säga.

Med tanke på allt man får gratis med Umbraco så känns detta system verkligen värt alternativ att tänka på innan man kanske betalar för något annat. Jag kan mycket väl tänka mig att i fortsättningen använda mig av Umbracos CMS. Användargräns snittet i Umbraco är relativt bra tycker jag. Det är väldigt lätt att göra sina egna templates för hur sidorna skall se ut och lägga in egen CSS även fast jag inte gick in på att ändra någon CSS men det är väldigt grundligt.
Jag pratade om att XSLT känns som en avvikelse i Umbraco men detta känner inte jag som något på ondo utan något som är bra. Så att Umbracos system bygger på XML tekniker är känns ganska attraktivt.

Något bristande vad jag har läst om i Umbraco är ett packet som fyller upp funktioner för bild hantering och ett galleri. Det finns ett paket men tydligen så täcker det inte hela behovet. Och synd är det för vad jag kunde hitta så fanns det ingen källkod att tillgå vart jag letade.
Jag tror det behövs dock lite till arbete med Umbraco för att helt kunna tillfredsställa de behov som finns idag men det känns ändå som de har nått nästan ända fram med bas funktionaliteten. Det känns som det är brister på dessa ad on packages, de är svåra att hitta och de är få att tillgå.

Detta Open Source CMS är bland de intressantaste delarna i min fördjupning men nu skall jag avsluta här för att kunna gå vidare i mina 2 andra Open Source webb applikationer jag även skall hinna testa. Hoppas det var intressant läsning och att det hjälper någon där ute.

2 kommentarer:

Anonym sa...

Det var ett inlägg som heter duga :) Intressant läsning. Jag har själv aldrig testat Umbraco men väl andra ASP.NET CMS och de lider oftast också av dålig dokumentation.

Kul att du hittat ett system som du kanske kommer använda dig av i framtiden. Jag kan tänka mig att lägger man lite tid på att lära sig så är det oerhört kraftfullt.

Anonym sa...

Jag utvecklar dagligen asp.net applikationer med EPiServer och har testat Umbraco en del. Jag tycker att det är ett mycket gott alternativ till EPiServer just för open-sourcedelen.
Det påminner väldigt mycket i sina byggstenar om EPiServer med ett stort undantag och det är fultaggarna som ska anges för att få in data. Jag har mycket svårt att förstå varför man har byggt umbraco med dessa genvägar. Det hade kunnat lösa det mycket snyggare.
Jag hoppas nu att man i 4:an har löst detta genom att använda standardiserat sätt att konstruera CMS-sidor.
Å andra sidan är det precis så fult som de flesta CMS är uppbyggda; Joomla,mfl.
Ett annat verktyg väl värt att ta en titt på är DotNetNuke men det lutar mer åt ett portalverktyg än rent CMS. Umbraco är i det avseendet bättre men DotNetNuke snyggare i sin arkitektur.