<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rssdatehelper="urn:rssdatehelper"><channel><title>Sewen bloggar om Umbraco</title><link>http://www.sewen.se</link><pubDate></pubDate><generator>umbraco</generator><description>
&lt;p&gt;&lt;a href="/blog.aspx"
title="Blog about Umbraco in english"&gt;To english version of
blog»&lt;/a&gt;&lt;/p&gt;
</description><language>en</language><item><title>Umbraco 4.7 - Razor med Intellisense</title><link>http://www.sewen.se/blogg/2011/3/7/umbraco-47---razor-med-intellisense.aspx</link><pubDate>Mon, 07 Mar 2011 23:15:48 GMT</pubDate><guid>http://www.sewen.se/blogg/2011/3/7/umbraco-47---razor-med-intellisense.aspx</guid><content:encoded><![CDATA[ 
<p>Nya <strong>Umbraco 4.7</strong> kommer med en ny view engine,
Razor. <a
href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"
 target="_blank" title="Scott Guthrie - Razor">Scott Guthrie skrev
tidigare om Razor</a> och att det kommer bli en stor del av .net
och mvc framöver. Nu fungerar det även med Umbraco!</p>

<p>Razor med Umbraco är snabbt och enkelt att komma igång med. Kör
bara igång en ny installation av Umbraco 4.7, gå till
developer-sektionen och högerklicka på "Scription Files". Följande
dialog dyker upp:</p>

<p><img src="/media/2375/skapa ett razor macro.png" width="430" height="390" alt="Skapa ett Razor Macro"/></p>

<p>Välj "Cshtml by Razor Macro Engine" och eventuellt en mall att
börja med. Nu skapas ett nytt Razor Macro.</p>

<p>Problemet för mig var att när jag öppnade upp det i Visual
Studio 2010 fick jag ingen intellisense. Intellisense för Razor
finns i ASP.NET MVC 3 som man kan installera med Web Platform
Installer. Det var den enkla biten. Det krångliga är att när jag
försökte skriva något, så fungerade det så långt som @Model, men
jag fick inte upp någon intellisense på vilka properties som min
@Model har. Problemet är att @Model är definerat som Dynamic.</p>

<h2>Hur får jag intellisense till min @model?</h2>

<p>Det enkla svaret är att göra om Dynamic till riktiga objekt. Vi
börjar med att använda Umbraco.MacroEngine högst upp i vårt
Macro</p>

<p class="brush:csharp">@using umbraco.MacroEngines;</p>

<p>När vi gjort det så är det det dags att definera vad vår @Model
är. I det här fallet står vår @Model för en viss sida CurrentPage
och det vi vill få ut är ancestors till sidan. Så istället för var
i vår foreach-loop sätter vi in att vi får ut DynamicNode (Umbraco
Razors motsvarighet till Node). Resultatet blir att vi får
intellisense för Level-variabeln:</p>

<p><img src="/media/2385/razor intellisense_495x100.jpg" width="495" height="100" alt="Razor Intellisense"/></p>

<p>Det går såklart att gå steget längre och definiera @Model med en
variabel också, men det här får börja.</p>

<p>Mer om Umbraco Razor senare</p>
]]></content:encoded></item><item><title>Umbraco 4.6 Juno släppt i Microsoft Web Platform Installer WPI</title><link>http://www.sewen.se/blogg/2011/1/13/umbraco-46-juno-slaeppt-i-microsoft-web-platform-installer-wpi.aspx</link><pubDate>Thu, 13 Jan 2011 16:38:40 GMT</pubDate><guid>http://www.sewen.se/blogg/2011/1/13/umbraco-46-juno-slaeppt-i-microsoft-web-platform-installer-wpi.aspx</guid><content:encoded><![CDATA[ 
<p>Året 2011 börjar med att Umbraco släpps i version 4.6 (aktuell
version i skrivandets stund är 4.6.1) aka Umbraco Juno.</p>

<p>De sista buggarna från <a href="/blogg/2010/12/27/umbraco-slaepper-juno,-nya-version-46-beta.aspx"
title="Umbraco släpper Juno, nya version 4.6 Beta">beta-releasen</a>
har blivit åtgärdade och den nya versionen är släppt och går att
ladda ner via Windows Web Platform Installer vilket gör
det&nbsp;helt sanslöst enkelt att komma igång.</p>

<p><img src="/media/2009/sewen-wpi-umbraco_498x345.jpg" width="498" height="345" alt="sewen-wpi-umbraco"/></p>

<p>&nbsp;</p>
]]></content:encoded></item><item><title>Umbraco släpper Juno, nya version 4.6 Beta</title><link>http://www.sewen.se/blogg/2010/12/27/umbraco-slaepper-juno,-nya-version-46-beta.aspx</link><pubDate>Mon, 27 Dec 2010 11:06:38 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/12/27/umbraco-slaepper-juno,-nya-version-46-beta.aspx</guid><content:encoded><![CDATA[ 
<p>I helgen släpptes <a
href="http://umbraco.codeplex.com/releases/view/58026"
target="_blank" title="Umbraco Juno på Codeplex">Umbraco Juno, nya
version 4.6 Beta</a>.</p>

<p>Releasen är fokuserad på ett förbättrat användargränssnitt med
fokus på första-gången-användare av Umbraco. Installationsprocessen
har fått en rejäl ansiktslyftning och några nya funktioner.</p>

<p><img src="/media/1981/umbraco_46_installation_500x369.jpg" width="500" height="369" alt="umbraco_46_installation"/></p>

<p><em>Umbraco Juno - Installationprocessen</em></p>

<h2>Inbyggd databas - SQL CE 4.0</h2>

<p>Nytt i Umbraco Juno är att man kan välja en inbyggd databas. Den
stora fördelen med SQL CE 4.0 är att den fungerar i en medium-trust
miljö. Det gör att valfriheten av webhotell kommer vara i stort
sett obegränsad. Även version 4.5 hade stöd för medium-trust, men
eftersom man behövde en extern databas blev det ändå något av en
tröskel.</p>

<h2>Starter kits och skins</h2>

<p>För att snabbt och enkelt komma igång med en ny webbplats
introducerar Umbraco Juno Starter kits och skins. Ett starter kit
är ett paket av färdiga mallar och sidor (<span><em>Simple</em>,
<em>Blog</em>, <em>Personal</em> och <em>Business</em></span>). För
att sedan göra dessa personliga kan man välja olika skins, dvs
utseende på sina mallar. Detta är något som kommer vara guld värt
för första-gångs-användare.</p>

<p><img src="/media/1986/umbraco_46_skins_500x319.jpg" width="500" height="319" alt="umbraco_46_skins"/></p>

<p><em>Umbraco Juno - Starter kits och Skins</em></p>

<h2>För utvecklare</h2>

<p>Även utvecklare har fått massor av ny funktionalitet för att
underlätta exempelvis skapandet av Custom Datatypes. Några av
funktionerna är:</p>

<p><span></span></p>

<ul>
<li
style="margin-left: 0px; margin-bottom: 0.3em; margin-top: 0.3em; vertical-align: middle;">
Default Data Editor Settings for Custom Data Types</li>

<li
style="margin-left: 0px; margin-bottom: 0.3em; margin-top: 0.3em; vertical-align: middle;">
Upgraded User Control Wrapper to support custom settings and xml
return types</li>

<li
style="margin-left: 0px; margin-bottom: 0.3em; margin-top: 0.3em; vertical-align: middle;">
Support for Microsoft SQL CE 4.0 (CTP 2)</li>

<li
style="margin-left: 0px; margin-bottom: 0.3em; margin-top: 0.3em; vertical-align: middle;">
Support for Microsoft Razor Syntax</li>

<li
style="margin-left: 0px; margin-bottom: 0.3em; margin-top: 0.3em; vertical-align: middle;">
Standardize on .NET 4.0</li>
</ul>

<p>Ladda ner senaste versionen av <a
href="http://umbraco.codeplex.com/releases/view/58026"
target="_blank" title="Umbraco Juno på Codeplex">Umbraco Juno från
Codeplex</a> och testa.<br />
<br />
</p>
]]></content:encoded></item><item><title>Ipad och Telenor SIM inställningar</title><link>http://www.sewen.se/blogg/2010/12/17/ipad-och-telenor-sim-instaellningar.aspx</link><pubDate>Fri, 17 Dec 2010 13:56:18 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/12/17/ipad-och-telenor-sim-instaellningar.aspx</guid><content:encoded><![CDATA[ ]]></content:encoded></item><item><title>Grattis MatHem - Sveriges bästa matbutik på nätet, hemleverans av varor, färdig matkasse, mm</title><link>http://www.sewen.se/blogg/2010/11/22/grattis-mathem---sveriges-baesta-matbutik-paa-naetet,-hemleverans-av-varor,-faerdig-matkasse,-mm.aspx</link><pubDate>Mon, 22 Nov 2010 17:42:56 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/11/22/grattis-mathem---sveriges-baesta-matbutik-paa-naetet,-hemleverans-av-varor,-faerdig-matkasse,-mm.aspx</guid><content:encoded><![CDATA[ 
<p>Internetworld utsåg i förra veckan Sveriges 100 bästa sajter. På
en sjätteplats och utmärkelsen "Sveriges bästa matbutik" kom en
sida som Sewen är inblandad i, <a href="http://www.mathem.se"
target="_blank">mathem.se - Mat för hemleverans</a> på nätet.</p>

<p><img src="/media/1946/mathem - mat för hemleverans.jpg" width="500" height="325" alt="MatHem - Mat för hemleverans"/></p>

<p>MatHem levererar för närvarande i Stockholm och Uppsala, men
kommer inom kort täcka in andra områden i Sverige också. Förutom
att beställa mat för hemleverans kan du även beställa en färdig <a
href="http://www.mathem.se/matkassar" target="_blank">matkasse</a>,
handla direkt från ett recept du hittar samt annat smått och
gott.</p>

<p>Sewen vill skicka ett STORT GRATTIS till alla som jobbar med
MatHem och säga att det bara är att fortsätta kämpa!</p>

<!--9615b1cf761742d4a4988a4844960726-->
]]></content:encoded></item><item><title>Umbraco 4 - Svensk manual för redaktörer</title><link>http://www.sewen.se/blogg/2010/11/5/umbraco-4---svensk-manual-foer-redaktoerer.aspx</link><pubDate>Fri, 05 Nov 2010 12:13:35 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/11/5/umbraco-4---svensk-manual-foer-redaktoerer.aspx</guid><content:encoded><![CDATA[ 
<p><a href="http://blog.mattbrailsford.com" target="_blank">Matt
Brailsford</a> har kommit med det utmärkta initiativet att skapa en
gemensam manual för redaktörer av Umbraco 4. Tack vare Umbraco
communityt har den spritt sig och finns nu tillgänglig på fem olika
språk. Däribland svenska.</p>

<p>Sewens senaste kunder har fått manualen i samband med
överlämnande av webplatser. Det har varit tummen upp varenda
gång.</p>

<p>Manualen är på 46 sidor och behandlar allt en redaktör behöver
veta. Det är dels grundläggande om Umbraco samt ett avslutande
kapitel med tips om något inte beter sig som det borde.</p>

<p>Bra jobbat ännu en gång Umbraco communityt.</p>

<p><a href="http://our.umbraco.org/FileDownload?id=1182"
target="_blank">Direktlänk till manualen på svenska»</a></p>

<p><a
href="http://our.umbraco.org/projects/website-utilities/editors-manual">
Länk till projektet»</a></p>
]]></content:encoded></item><item><title>Microsofts www.asp.net kör nu Umbraco CMS som publiceringssystem</title><link>http://www.sewen.se/blogg/2010/5/6/microsofts-wwwaspnet-koer-nu-umbraco-cms-som-publiceringssystem.aspx</link><pubDate>Thu, 06 May 2010 10:12:55 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/5/6/microsofts-wwwaspnet-koer-nu-umbraco-cms-som-publiceringssystem.aspx</guid><content:encoded><![CDATA[ 
<p>Scott Guthrie skrev i tidigare att Microsofts egna
utvecklarresurs <a href="http://www.asp.net/"
title="www.asp.net">www.asp.net</a> skulle börja köra Umbraco CMS
som publiceringssystem.</p>

<p>Nu har det blivit verklighet. En skön skalp för Umbraco när ett
så stort och inflytelserikt företag som Microsoft själva väljer det
som plattform.</p>

<p>Grattis Umbraco!</p>
]]></content:encoded></item><item><title>Medium Trust - Installera Umbraco på Binero</title><link>http://www.sewen.se/blogg/2010/4/7/medium-trust---installera-umbraco-paa-binero.aspx</link><pubDate>Wed, 07 Apr 2010 18:11:27 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/4/7/medium-trust---installera-umbraco-paa-binero.aspx</guid><content:encoded><![CDATA[ 
<p>Rent traditionellt har inte Umbraco gått att installera i Medium
Trust tidigare. Många webhotell använder Medium Trust för att
skydda åtkomst till andra sajter på samma server. Att inte kunna
installera Umbraco i Medium Trust har varit en stor nackdel. Nu är
det möjligt! Teamet bakom Umbraco, den här gången med <a
href="http://www.benjaminhowarth.com/">Benjamin Howarth</a> i
spetsen, har lagt ner stor möda och besvär för att reda ut vad det
var som begränsade Umbraco från att köra i Medium Trust. Från
version 4.1, som planeras att släppas någon gång i slutet av Q2,
kommer Medium Trust stödjas från grunden. Tillvidare finns en
lösning för att även köra 4.0.x.</p>

<p>Nedan tänkte jag gå igenom hur jag installerade Umbraco på
Binero, som kör Medium Trust på sina windowsbaserade webbhotell.
Efter det kommer jag föra ett kort resonemang varför Medium Trust
är viktigt.</p>

<h2>Umbraco på Binero</h2>

<h3>Bakgrund</h3>

<p>Vi fick i uppdrag att bygga en mindre bloggportal för en av
Sveriges stigande stjärnor inom komikerhimlen. Kunden hade redan
tidigare webbhotell Privat (69:-/månad) hos Binero. Eftersom jag
just läst om Umbraco i Medium Trust tyckte jag det här var ett
utmärkt tillfälle att testa om det skulle fungera.</p>

<h3>Installation</h3>

<p>Först och främst satte vi upp ett lokalt projekt och utvecklade
sajten precis som vanligt. När allt var klart och det såg snyggt ut
på vår lokala installation, tog vi tag i problemet att få allt att
lira på Binero.</p>

<p>Vi började med att teckna tilläggstjänsten MSSql-server (vi hade
likaväl kunnat köra med MySql, men jag föredrar MSSql när det finns
den möjligheten). Sedan publicerade vi vår databas till den nya
MSSql-servern. Vi använder Visual Studios inbyggda funktion
<em>Server Explorer - Right click on database - Publish to
provider</em> för att snabbt och enkelt få ut en scriptad databas
med allt innehåll.</p>

<p>Nu kunde vi köra vår lokala kopia mot databasen för att
verifiera att allt innehåll kommit med som det ska.</p>

<p>Nästa steg var att ladda ner <a
href="http://www.benjaminhowarth.com/media/964/umbraco403-mediumtrust.zip">
patchen för att kunna köra Umbraco i Medium Trust</a>.</p>

<p>För säkerhets skull tog vi nu en kopia av hela projektet (jag
erkänner och skäms; vi fuskade genom att inte använda
versionshantering). Sedan ersatte vi alla filer i vår lösning med
dem från patchen.</p>

<p>OBS! Eftersom patchen innehåller hela config-mappen, var noga
med att inte skriva över ändringar du gjort själv i
config-filerna.</p>

<p>Även web.config är nu överskriven. Det vi gjorde var att ändra
tillbaka</p>

<ol>
<li>umbracoDbDSN - till den connectionstring som ansluter till
MSSql hos Binero</li>

<li>umbracoConfigurationStatus - till den Umbraco-version vi
använder (value="4.0.3")</li>
</ol>

<p>Sedan var det dags att ladda upp vår lösning till Binero.</p>

<h3>Problem 1 - Integrated Pipe-line mode</h3>

<p>Vi trodde (läs: hoppades) nu att vi skulle ha en färdig lösning.
Men det första vi stötte på var ett problem med Integrated
Pipe-lines som är default i IIS 7. Tidigare har jag löst det genom
att sätta Classic mode i Application Pool, men eftersom vi tänkte
köra på Binero som det är utan att krångla gav vi oss på att vi
skulle hitta en lösning för det.</p>

<p>Dum som jag är ibland, öppnade jag web.config direkt från
notepad++ (som iofs är en utmärkt editor) och försökte editera
därifrån. Av någon anledning har jag då ingen färgkodning för
config-filer, trots att de egentligen är vanliga (?) xml-filer. Jag
gissar att det är en enkel inställning och att notepad++ kan lösa
det, men jag har inte känt något behov av det tidigare. I alla
fall, det jag missade, var att hela stycket som gör att Umbraco
fungerar i Integrated Pipe-line mode är bortkommenterat per
default. Jag slet mitt hår i en timme eller så innan jag förstod
vad felet var.</p>

<h3>Problem 2 - msxml:script</h3>

<p>Msxml:script är ett sätt att skriva .net-kod inline i en
xslt-fil. Det finns inget sätt (känt än så länge i alla fall) att
komma runt det. För min del ser jag det inte som något problem,
eftersom det är väldigt enkelt att skriva egna extensions till xslt
i kompilerade .net-filer. Men, det gör så att vissa befintliga
paket inte fungerar som de ska. Det utomordentliga paketet
XSLTSearch använder sig till stor del av msxml:script. Vår enkla
lösning var att ta bort det så länge. Vi hade inga krav på oss att
ha med en sökning på den här webbplatsen. En annan lösning hade
varit att flytta över alla msxml:script i en kompilerad dll och
helt enkelt skriva om XSLTSearch. Dock tror jag att det finns andra
i Umbraco communityt som redan har det på sin agenda.</p>

<p>Egentligen stötte vi på ett problem till. Det var när vi laddade
upp allt så klagade den på att den inte kunde köra några
xslt-macron. Det felet har jag redan påpekat tidigare. Vår
xsltExtensions.config blev överskriven av patchen, vilket gjorde
att xslt-macrona inte kände igen vårt library som vi försökte
implementera. Det löstes enkelt genom att kopiera in vår gamla
config-fil.</p>

<h2>Fördelarna med Medium Trust</h2>

<p>Den stora anledningen till varför man vill att Umbraco (eller
vilken annan webbapplikation som helst) ska köra på Medium Trust är
att troligtvis 90% av världens alla webbsidor befinner sig i Medium
Trust. Konkurrerande open source CMS som Joomla, Wordpress och
Drupal har inga problem med Medium Trust. Alltså, missar man en
otroligt stor del av marknaden om det inte går att installera
applikationen.</p>

<p>Anledningen till att webbhotellen väljer att köra Medium Trust
på sina servrar är helt enkelt för att skydda kod. Din kod från de
andra som du delar server med. De andra från din kod.</p>

<p>En tredje fördel med Medium Trust är även att det tvingar dig
som utvecklare att skriva snyggare kod. En kod som är anpassad för
en säker miljö, där du inte har möjlighet att sänka en server om
något skulle gå fel.</p>

<p>Det är alltså</p>

<ol>
<li>Billigare</li>

<li>Säkrare</li>

<li>Bättre kod</li>
</ol>

<h2>Sammanfattning</h2>

<p>Umbraco har nu gått in i ytterligare en utvecklingsfas där man
nu helt plötsligt kan installera Umbraco i snart vilken miljö som
helst. Eftersom Umbraco även har/kommer ha fullt stöd för
Mono-plattformen är det helt klart ett CMS att räkna med i
framtiden. Linux och Medium Trust är inga hinder längre.</p>

<p>Det är dags att ta upp kampen på riktigt med de populära
php-CMS:en.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
]]></content:encoded></item><item><title>Skapa en Custom section i Umbraco (steg 2)</title><link>http://www.sewen.se/blogg/2010/3/30/skapa-en-custom-section-i-umbraco-(steg-2).aspx</link><pubDate>Tue, 30 Mar 2010 11:06:17 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/3/30/skapa-en-custom-section-i-umbraco-(steg-2).aspx</guid><content:encoded><![CDATA[ 
<p>Det här är steg 2 i en serie om hur man skapar en Custom section
i Umbraco. <a href="/blogg/2010/2/26/skapa-en-custom-section-i-umbraco-(steg-1).aspx"
title="Skapa en custom section i Umbraco (Steg 1)">Läs första delen
här</a>. I steg 1 skapade vi en ny nod i User-sektionen och mappar
användare till en eller flera MemberGroups.</p>

<p>I den här delen kommer vi skapa en Custom section som heter
CustomMember. Den kommer påminna om den Member-sektion som redan
finns i Umbraco, men endast lista medlemmar från de grupper som du
är mappad till (<a href="/blogg/2010/2/26/skapa-en-custom-section-i-umbraco-(steg-1).aspx"
title="Skapa en custom section i Umbraco (Steg 1)">se&nbsp;steg
1</a>).</p>

<h2>Problemformulering</h2>

<ol>
<li>Skapa en ny CustomMember-section</li>

<li>
<div>Lägga till en nod som tillåter oss att</div>

<ol>
<li>Lägga till nya medlem (mappad till samma grupper som vår
användare)</li>

<li>Lista befintliga medlemmar</li>

<li>Editera befintlig medlem</li>

<li>Ta bort medlem</li>
</ol>
</li>
</ol>

<h2>Lägga till en Custom section</h2>

<p>Eftersom jag redan i steg 1 förklarat hur vilka tabeller i
Umbraco databasen som påverkar sektioner kommer jag sätta igång
direkt.</p>

<p>Först lägger vi till en ny sektion</p>

<p>INSERT INTO umbracoApp (sortOrder, appAlias, appName,
appIcon)<br />
 VALUES (9,'customMember','CustomMember','.traymember')</p>

<p>Vi döper sektionen till customMember, säger att den ska ha
css-klassen traymember och lägga sig på plats 9 (sist) i
sektionsmenyn. För appIcon kan man antingen ange en bild-fil direkt
eller en css-klass. Anger man en bild kommer Umbraco leta efter
bilden i mappen "~/umbraco/images/tray/". Anger man en css-klass
behöver man uppdatera någon av de css:er som Umbraco admin
användare i sin backend. De återfinns i mappen "~/umbraco/css/".
Eftersom våra användare aldrig kommer ha tillgång till båda
Member-sektionerna samtidigt ger vi den samma css-klass som
Member-sektionen.</p>

<p>För att sektionen ska dyka upp i Umbraco admin behöver vi säga
att vår användare ska ges tillgång till sektionen. Gå till
Users-sektionen och leta upp din användare. Under Sections ska en
ny sektion [customMember] dykt upp. Anledningen att den ser konstig
ut är att den letar efter en nyckel i Umbracos språkfiler. Vi
öppnar filen "/umbraco/config/lang/en.xml" (eller det språk du har
inställt att Umbraco admin använder. Där finns en &lt;area
alias="sections"&gt;. Lägg till en ny rad där</p>

<p><span><span>&lt;</span><span>key</span>
<span>alias</span><span>=</span>"<span>customMember</span>"<span>&gt;</span>Custom
members<span>&lt;/</span><span>key</span><span>&gt;</span></span></p>

<p>Klicka sedan på din användare igen i Umbraco admin så ser du att
den tar översättningen från din nya nyckel.</p>

<p><img src="/media/1496/033010_0904_SkapaenCust1.png"/></p>

<p>Vi klickar för att vår användare ska se vår
CustomMembers-sektion och sparar. När vi sedan uppdaterar sidan
(ctrl-F5) ska vår nya sektion dyka upp.</p>

<p><img src="/media/1501/033010_0904_SkapaenCust2.png"/></p>

<p>Nästa steg blir att lägg till ett träd till vår nya sektion så
att något händer när man klickar på den.</p>

<p>INSERT INTO umbracoAppTree (treeSilent, treeInitialize,
treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed,
treeIconOpen, treeHandlerAssembly, treeHandlerType)<br />
<br />
 VALUES ('false', 'true', 0, 'customMember', 'Member', 'Member',
'folder.gif', 'folder_o.gif',
'umbBoRatt.Umbraco.Sections.CustomMember', 'LoadMembers')</p>

<p>Vi har sagt att vår första nod ska heta Member, ha den vanliga
folder-ikonen och laddas från klassen LoadMembers i namespace
umbBoRatt.Umbraco.Sections.CustomMember</p>

<p>Eftersom vi redan bestämt att det gränssnittet ska likna den
Member-sektion som redan finns gör vi så att vi använder den som
mall. Vi öppnar filen
"/umbraco/presentation/umbraco/Trees/loadMembers.cs" från Umbracos
källkod. Vi börjar med att kopiera hela källkoden till vår nya
klass och bygger vår lösning. När vi sedan öppnar vår
CustomMember-sektion laddas hela användarträdet. Vi behöver ändra i
koden för att endast lista medlemmar från grupper som vi är mappade
till.</p>

<p>Vi lägger till följande metod</p>

<pre class="brush:csharp">
        private bool memberInGroup(int memberId)
        {
            umbBoRatt.Core.Controllers.UserMemberGroupController controller = new umbBoRatt.Core.Controllers.UserMemberGroupController(new umbBoRatt.Core.Models.UserMemberGroupRepository(GlobalSettings.DbDSN));

            Member m = new Member(memberId);

            int userId = umbraco.BasePages.UmbracoEnsuredPage.CurrentUser.Id;

            foreach (object value in m.Groups.Keys)
            {
                int groupId;
                if (int.TryParse(value.ToString(), out groupId) &amp;&amp; controller.HasGroup(userId, groupId))
                {
                    return true;
                }
            }
            
            return false;
        }
</pre>

<p>Och på rad 142 kör vi en if-sats för att kolla om medlemmen
tillhör gruppen</p>

<p><span><span>if</span> (memberInGroup(m.Id)) {</span></p>

<p>När vi byggt den koden borde vi få upp en listning av alla
medlemmar som tillhör endast vår egen grupp.</p>

<p><em>OBS! För att inte behöva jobba med sökningar av medlemmar,
det är inget krav för oss ännu, kommenterar vi bort den noden från
trädet.</em></p>

<h2>Skapa nya medlemmar</h2>

<p>Nästa punkt blir att skapa nya medlemmar. Umbracos inbyggda
funktion för att skapa nya medlemmar duger gott åt oss. Den enda
ändringen vi behöver göra är att när vi skapat medlemmen ska vi
lägga till en grupp till den. För att göra det använder vi Umbracos
Event Model. Mer om det senare.</p>

<p>Umbraco använder UserControls för de olika event som sker vid
högerklick på en nod. Mappningarna sker i filen
"~/Umbraco/config/create/UI.xml". Vi hittar:</p>

<p><span><span>&lt;</span><span>nodeType</span>
<span>alias</span><span>=</span>"<span>initmember</span>"<span>&gt;<br />
</span></span>
<span><span>&lt;</span><span>header</span><span>&gt;</span>Member<span>
&lt;/</span> <span>header</span><span>&gt;<br />
</span></span>
<span><span>&lt;</span><span>usercontrol</span><span>&gt;</span>/create/member.ascx
<span>&lt;/</span><span>usercontrol</span><span>&gt;<br />
</span></span>
<span><span>&lt;</span><span>tasks</span><span>&gt;</span></span><span>
<span>&lt;</span> <span>delete</span>
<span>assembly</span><span>=</span>"<span>umbraco</span>"
<span>type</span><span>=</span>"<span>memberTasks</span>"
<span>/&gt;</span></span><span><span>&lt;/</span><span>tasks</span>
<span>&gt;<br />
</span></span>
<span><span>&lt;/</span><span>nodeType</span><span>&gt;</span></span></p>

<p>Vi säger nu att när en <em>create</em> med alias
<em>initmember</em> (definerat i CreateRootNode-metoden i
LoadMembers-klass) uppstår, öppnar vi kontrollen
"/umbraco/create/member.ascx". Vi måste nu bara se till att vårt
alias verkligen stämmer överens med det skrivna ovan. Vi ändrar
koden till:</p>

<p><span>rootNode.NodeType = <span>"init"</span> +
TreeAlias.ToLower();</span></p>

<p>Hade vi velat göra vårt eget event behöver vi lägga till en ny
&lt;nodeType&gt; med vårt eget unika alias och kalla på en egen
custom UserControl. Dessutom om vi vill skapa våra egna tasks,
måste vi göra en ny klass som implementerar:
<span>umbraco.interfaces.<span>ITaskReturnUrl</span></span></p>

<h2>Editera medlemmar</h2>

<p>I vår LoadMember-klass har vi definerat vad som ska hända när vi
klickar på en Medlem. Umbraco kommer automatiskt att trigga det
javascript som står i action-attributet.</p>

<p><span>treeElement.SetAttribute(<span>"action"</span>,
<span>"javascript:openMember('"</span> +</span></p>

<p>
<span><span>HttpContext</span>.Current.Server.UrlEncode(u.UserName)
+ <span>"');"</span>);</span></p>

<p>Vi säger att vi kallar på javascriptet openMember(id). I
RenderJS-metoden definerar vi javascriptet som:</p>

<pre class="brush:csharp">
        public override void RenderJS(ref StringBuilder Javascript)
        {
            Javascript.Append(
                @"
                    function openMember(id) {
                        parent.right.document.location.href = 'plugins/CustomMember/editMember.aspx?id=' + id;
                    }

                    function openContentItem(id) {
                        parent.right.document.location.href = 'ContentItem/edit.aspx?id=' + id;
                    }
                    ");
        }
</pre>

<p>Vi säger alltså till Umbraco att när man klickar på en Medlem,
öppna i din högra Frame editMember.aspx som ligger i
"\umbraco\plugins\CustomMember". Vi behöver alltså skapa sökväg och
sida.</p>

<p>Jag valde länge här mellan att använda samma kontroll för att
editera medlemmar som Umbraco redan använder, eller att skapa en
egen kontroll. Jag kom fram till att jag inte vill att mina
användare ska kunna byta grupper på medlemmarna. Alltså vill jag ha
en sida som ser ut exakt som den vanliga editera-medlemmar sidan i
Umbraco, men utan grupper.</p>

<p>Jag kopierade hela sidan som Umbraco använder. Sen la jag till
ett Javascript längst upp som gömmer grupperna. Det kan diskuteras
om det här är rätt sätt att göra det på, och jag skulle vara den
första att erkänna att det kanske inte är det bästa. Men det är
tillräckligt bra för min lösning och det är garanterat den
snabbaste, godtagbara lösningen. Märker vi framöver att den inte är
acceptabel kan vi ändra det då.</p>

<p>Javascriptet för att "ta bort" grupper:</p>

<pre class="brush:csharp">
//Javascript function to remove groups (Users shouldn't be able to save groups)
        $(document).ready(function() {
            var node = $('#ctl00_body_Membergroups')[0];
            $(node.parentNode.parentNode.parentNode.parentNode).remove();
        });
</pre>

<h2>Ta bort medlemmar</h2>

<p>Eftersom vi valde att använda samma &lt;nodeType&gt; som
Umbracos Medlem-sektion redan använder, fick vi funktionen att ta
bort medlemmar gratis. Vill man kan man skapa sina egna events i en
egen klass. Jag nämnde det förut, men nämnder det igen att kravet
då är att man ärver från
<span>umbraco.interfaces.<span>ITaskReturnUrl.</span></span></p>

<h2>Slutsats</h2>

<p>Det här är mer eller mindre det jag tänkte gå igenom i den här
delen.</p>

<p>Vi har lärt oss hur man skapar upp en ny sektion. Hur man lägger
till en huvudnod och subnoder till sektionen. Vi har även tummat på
hur man skapar events för noderna. I kommande del kommer jag gå
igenom hur man skapar sina egna event med egna tasks.</p>
]]></content:encoded></item><item><title>Skapa en custom section i Umbraco (Steg 1)</title><link>http://www.sewen.se/blogg/2010/2/26/skapa-en-custom-section-i-umbraco-(steg-1).aspx</link><pubDate>Fri, 26 Feb 2010 15:26:33 GMT</pubDate><guid>http://www.sewen.se/blogg/2010/2/26/skapa-en-custom-section-i-umbraco-(steg-1).aspx</guid><content:encoded><![CDATA[ 
<h2>Bakgrund:</h2>

<p>Vi har en sajt för föreningar. Föreningarna ser bara sin egen
förenings innehåll i Content-sektionen. Nu har det kommit en
förfrågan från flera föreningar att de vill kunna lägga till sina
medlemmar och ha en inloggad del. Vi vill inte ge administratörerna
för de olika föreningarna direkt tillgång till Umbracos
member-sektion eftersom de då skulle se alla föreningars medlemmar.
Alltså faller valet på att skapa en ny <em>custom section</em> där
de kan administrera den egna föreningens medlemmar. Vi tyckte det
här var ett ypperligt tillfälle att dela med oss hur vi skapar en
<em>custom section</em>.</p>

<h2>Problemformulering:</h2>

<ol>
<li>I Users-sektionen lägger vi till en User -&gt; MemberGroup -
mappning.</li>

<li>Skapa en ny CustomMember-sektion som liknar den Member-sektion
som redan finns i Umbraco (CRUD).</li>
</ol>

<h2>Om Umbraco databasen:</h2>

<p>Sektioner i Umbraco hanteras av två databastabeller.</p>

<h3>umbracoApp</h3>

<p>Består av Krasst ansvarar umbracoApp för visningen av menyn för
sektionerna i Umbraco admin. Tabellen består av fem kolumner som
beskrivs nedan. De flesta har med just visningen att göra, men
<em>appAlias</em>-kolumnen är värd att lägga på minnet för den
kommer spela roll i vår nästa tabell och i config.</p>

<h3>umbracoAppTree</h3>

<p>När en sektion laddas så är det den här tabellen som ansvarar
för vad som kommer dyka upp i Content-menyn.</p>

<p>För att läsa mer om tabellerna gå till <a
href="http://www.geckonewmedia.com/blog/2009/8/3/how-to-create-a-custom-section-in-umbraco-4">
http://www.geckonewmedia.com/blog/2009/8/3/how-to-create-a-custom-section-in-umbraco-4</a></p>

<p>Eftersom vår första uppgift var att lägga till en User -&gt;
MemberGroup - mappning i Users-sektionen som redan finns så är det
umbracoAppTree som vi ska lägga till en ny rad i.</p>

<pre class="brush:csharp">
INSERT INTO umbracoAppTree

(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType)

VALUES ('false', 'true', 3, 'users', 'userGroupMapping', 'User Group mapping', 'folder.gif', 'folder_o.gif', 'umbBoRatt.Umbraco.Sections.Users', 'LoadUserGroupMappings')
</pre>

<p>Vi väljer att inte krångla till det med design här, eftersom det
bara kommer vara sajtens administratörer som ser det. Vi ser till
att våra andra ikoner ser snyggare ut framöver.</p>

<p><em>TIPS! Umbraco förutsätter att tree-ikonerna ligger i mappen
"~/umbraco/images/umbraco/"</em></p>

<p>Det vi nu har sagt till Umbraco är att när den laddar
Users-sektionen ska den lägga till en ny folder med namnet "User
Group mapping". För att veta folderns innehåll ska den ladda
classen <em>LoadUserGroupMapping</em> med namespace
<em>umbBoratt.Umbraco.Sections.Users</em>. Alltså får vi se till
att skapa den klassen.</p>

<p><em>OBS! Om Umbraco inte hittar ditt namespace eller klassen
kommer det inte synas något i admin. Kontrollera referenser,
namespace och klassnamn en gång till. När du gjort ändringar i
databasen, se till att röra web.config för att starta om
applikationen.</em></p>

<h2>BaseTree</h2>

<p>Nu kommer det härligaste med Umbraco. Eftersom Umbraco är Open
Source behöver man aldrig gissa sig fram till hur man ska göra. Det
finns alltid ett exempel att ta av. I det här fallet ska vårt nya
träd lista användare. Vi har redan ett likadant träd som listar
användare. Vi ser i databasen att klassen ska heta loadUsers. Vi
gör en sökning i Umbracos källkod och finner klassen i mappen
"/umbraco/presentations/umbraco/trees/". Vi använder källkoden från
den filen med några smärre förändringar.</p>

<p><img src="/media/1132/022610_1423_Skapaencust1.png"/></p>

<pre class="brush:csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using umbraco.cms.presentation.Trees;
using umbraco.BusinessLogic.Actions;
using umbraco.interfaces;
using umbraco.BusinessLogic;
using umbraco.BasePages;

namespace umbBoRatt.Umbraco.Sections.Users
{
    public class LoadUserGroupMappings : BaseTree
    {
        public LoadUserGroupMappings(string application) : base(application) { }

        protected override void CreateRootNode(ref XmlTreeNode rootNode)
        {
            rootNode.Icon = FolderIcon;
            rootNode.OpenIcon = FolderIconOpen;
            rootNode.NodeType = "init" + TreeAlias;
            rootNode.NodeID = "init";
            rootNode.Action = "";
        }

        protected override void CreateRootNodeActions(ref List actions)
        {
            actions.Clear();
            actions.Add(ActionRefresh.Instance);
        }

        protected override void CreateAllowedActions(ref List actions)
        {
            actions.Clear();
        }

        public override void Render(ref XmlTree tree)
        {
            User[] users = User.getAll();

            User currUser = UmbracoEnsuredPage.CurrentUser;

            bool currUserIsAdmin = currUser.IsAdmin();
            foreach (User u in users)
            {
                XmlTreeNode xNode = XmlTreeNode.Create(this);

                // special check for ROOT user
                if (u.Id == 0)
                {
                    //if its the administrator, don't create a menu
                    xNode.Menu = null;
                    //if the current user is not the administrator, then don't add this node.
                    if (currUser.Id != 0)
                        continue;
                }
                // Special check for admins in general (only show admins to admins)
                else if (!currUserIsAdmin &amp;&amp; u.IsAdmin())
                {
                    continue;
                }

                if (u.Disabled)
                    xNode.IconClass = "umbraco-tree-icon-grey";

                xNode.NodeID = u.Id.ToString();
                xNode.Text = u.Name;
                xNode.Action = "javascript:openUserMemberGroupMappings(" + u.Id + ");";
                xNode.Icon = "user.gif";
                xNode.OpenIcon = "user.gif";

                tree.Add(xNode);
            }
        }

        public override void RenderJS(ref StringBuilder Javascript)
        {
            Javascript.Append(
               @"
                    function openUserMemberGroupMappings(id) {
                        parent.right.document.location.href = 'plugins/CustomMember/Users/editUserMemberGroupMappings.aspx?id=' + id;
                    }
                ");
        }
    }
}
</pre>

<h3>Förklaringar till BaseTree</h3>

<p>Vår klass ärver från BaseTree. Vi har valt att override ett
antal metoder. Jag kommer förklara deras funktion en och en.</p>

<p><em>CreateRootNode</em>: I vårt träd har vi en rootNode. Vi kan
göra ändringar i den noden i CreateRootNode metoden. Vi väljer
ikon, sätter ett id och en eventuell action (kommer kalla på ett
eget javascript om det är satt). rootNode.NodeType är viktig om man
ska koppla Create-event till sin nod. Vi kommer gå igenom det
närmre när vi skapar vår CustomMember-sektion.</p>

<p><em>CreateRootNodeActions</em>: Definierar vad som ska hända när
man högerklickar på en nod i trädet. I vårt fall tillåter vi endast
att man kan uppdatera trädet.</p>

<p><em>CreateAllowedActions</em>: Definerar vilka actions som
kommer vara tillåtna för vår sub-noder. I vårt fall vill vi bara
att man ska kunna klicka på varje användare och därifrån definiera
User -&gt; MemberGroup - mappningen, därför tömmer vi sub-noderna
på actions.</p>

<p><em>Render</em>: När man väljer att expandera trädet kommer
Render metoden att kallas på. Det är här man skapar sub-noder till
trädstrukturen. I vårt fall hämtar vi alla Users. Efter några
kontroller om det är admin-användare eller inte som är inloggad tar
vi var och en av våra Users och skapar noder av dessa.</p>

<p><span><span>foreach</span> (<span>User</span> u <span>in</span>
users)</span></p>

<p><span>{</span></p>

<p><span><span>XmlTreeNode</span> xNode =
<span>XmlTreeNode</span>.Create(<span>this</span>);</span></p>

<p>För varje nod väljer vi dessutom ikoner, text och en action (ett
javascript som kallas på vid klick på noden). Slutligen lägger vi
till noden till vår rootNode .</p>

<p><span>tree.Add(xNode);</span></p>

<p><em>RenderJS</em>: Kommer lägga till ett javascript till sidan,
som vi sedan kan kalla på via våra actions från noderna.</p>

<p>Den stora förändringen vi gjort ligger i vad som ska hända när
man klickar på en användare.</p>

<p><span>xNode.Action =
<span>"javascript:openUserMemberGroupMappings("</span> + u.Id +
<span>");"</span>;</span></p>

<p>Ovan har vi har definerat att när man klickar på en medlem så
kommer ett javascript openMemberGroupMappings att anropas. I vår
RenderJS metod definerar vi det javascriptet. Det är så enkelt att
det öppnar en aspx-fil i Umbraco admins stora iFrame. Nu är det
dags att skapa den aspx-filen.</p>

<h2>UI</h2>

<p>Eftersom vi vill att vårt gränssnitt ska påminna så mycket som
möjligt om Umbracos eget gränssnitt börjar vi med att ta lite
hjälp. I loadUsers-klassen ser vi att den kallar på en fil som
heter editUser.aspx. Vi öppnar den och får vår grunddesign. Vi
importerar umbraco.ui och får tillgång till kontroller som har ett
native Umbraco utseende.</p>

<p><span><span>&lt;%</span><span>@</span> <span>Register</span>
<span>TagPrefix</span><span>="cc1"</span>
<span>Namespace</span><span>="umbraco.uicontrols"</span>
<span>Assembly</span><span>="controls"</span>
<span>%&gt;</span></span></p>

<p>Se hela front-end koden här:</p>

<pre class="brush:csharp">
&lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="editUserMemberGroupMappings.aspx.cs" MasterPageFile="/umbraco/masterpages/umbracoPage.Master" Inherits="umbBoRatt.Web.umbraco.plugins.CustomMember.Users.editUserMemberGroupMappings" %&gt;

&lt;%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %&gt;
&lt;asp:Content ContentPlaceHolderID="body" runat="server"&gt;
&nbsp;&lt;cc1:UmbracoPanel runat="server" ID="UserMemberGroupMappings" Text="User Member group mappings" hasMenu="true"&gt;
&nbsp;&lt;cc1:Pane ID="Pane1" runat="server"&gt;
&nbsp;&lt;cc1:PropertyPanel runat="server" ID="PropertyPanel2" Text="Member"&gt;
&nbsp;&lt;asp:Literal ID="lblMemberName" runat="server"&gt;&lt;/asp:Literal&gt;
&nbsp;&lt;/cc1:PropertyPanel&gt;
&nbsp;&lt;cc1:PropertyPanel runat="server" ID="PropertyPanel1" Text="Member groups"&gt;
&nbsp;&lt;asp:CheckBoxList ID="memberGroups" runat="server" OnDataBound="memberGroups_DataBind"&gt;
&nbsp;&lt;/asp:CheckBoxList&gt;
&nbsp;&lt;/cc1:PropertyPanel&gt;
&nbsp;&lt;/cc1:Pane&gt;
&nbsp;
&lt;/cc1:UmbracoPanel&gt;
&lt;/asp:Content&gt;
</pre>

<p>I page_load i vår back-end lägger vi till en spara-knapp till
menyraden i vår UmbracoPanel. Sedan binder vi vår CheckBoxList med
alla MemberGroups.</p>

<p>I spara-metoden itererar vi listan och sparar alla ikryssade
MemberGroups. Vi ser även till att aktivera Umbraco admins inbyggda
pratbubbla (speechBubble). Vi får tillgång till den genom att vi
ärver från UmbracoEnsuredPage istället för den vanliga Page.</p>

<pre class="brush:csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco.BasePages;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.propertytype;
using umbraco.cms.businesslogic.web;
using umbraco.presentation.channels.businesslogic;
using umbraco.uicontrols;
using umbraco.providers;
using umbraco;
using umbraco.cms.businesslogic.member;

namespace umbBoRatt.Web.umbraco.plugins.CustomMember.Users
{
    public partial class editUserMemberGroupMappings : UmbracoEnsuredPage
    {
        public User pageUser { get { return new User(int.Parse(Request["id"])); } }
        private umbBoRatt.Core.Controllers.UserMemberGroupController Controller;
         

        protected void Page_Load(object sender, EventArgs e)
        {
            Controller = new umbBoRatt.Core.Controllers.UserMemberGroupController(new umbBoRatt.Core.Models.UserMemberGroupRepository(GlobalSettings.DbDSN));

            //Add save to menu
            MenuImageButton save = UserMemberGroupMappings.Menu.NewImageButton();
            save.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";
            save.Click += new ImageClickEventHandler(saveUser_Click);

            if (!Page.IsPostBack)
            {
                lblMemberName.Text = pageUser.Name;

                //Bind all member groups
                memberGroups.DataSource = MemberGroup.GetAll;
                memberGroups.DataTextField = "Text";
                memberGroups.DataValueField = "Id";
                memberGroups.DataBind();
            }
        }

        /// 
        /// Handles the databind event of the list control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        protected void memberGroups_DataBind(object sender, EventArgs e)
        {
            int userId = pageUser.Id;
            foreach (ListItem li in memberGroups.Items)
            {
                li.Selected = Controller.HasGroup(userId, int.Parse(li.Value));
            }
        }

        /// 
        /// Handles the Click event of the saveUser control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void saveUser_Click(object sender, ImageClickEventArgs e)
        {
            //1) Remove all groups for user
            //2) Foreach li.selected add group to user
            //3) Show speechbubble

            int userId = pageUser.Id;
            Controller.RemoveAllGroups(userId);

            foreach (ListItem li in memberGroups.Items)
            {
                if (li.Selected)
                {
                    Controller.AddMemberGroup(userId, int.Parse(li.Value));
                }
            }

            speechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editUserSaved", base.getUser()), "");     
        }
    }
}
</pre>

<p>Resultatet blir:</p>

<p><img src="/media/1137/022610_1423_Skapaencust2.png" width="433" height="136"/></p>

<h2>Sammanfattning:</h2>

<p>Vi har gått igenom de tabeller som Umbraco använder för
sektioner och trädstrukturen för sektionerna. Vi har även skaffat
oss en övergripande förståelse för hur Umbraco admin använder
klassen BaseTree för trädstrukturen i sektionerna. Med hjälp av
blogginlägget <a
href="http://www.geckonewmedia.com/blog/2009/8/3/how-to-create-a-custom-section-in-umbraco-4">
http://www.geckonewmedia.com/blog/2009/8/3/how-to-create-a-custom-section-in-umbraco-4</a>
kommer det inte vara något problem för dig som läsare att redan nu
ge dig på att skapa en <em>Custom Sections</em> i Umbraco. Mer om
det kommer i Steg 2 av serien att skapa en <em>Custom Section</em>
i Umbraco.</p>
]]></content:encoded></item></channel></rss>

