Det här är steg 2 i en serie om hur man skapar en Custom section
i Umbraco. Läs första delen
här. I steg 1 skapade vi en ny nod i User-sektionen och mappar
användare till en eller flera MemberGroups.
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 (se steg
1).
Problemformulering
- Skapa en ny CustomMember-section
-
Lägga till en nod som tillåter oss att
- Lägga till nya medlem (mappad till samma grupper som vår
användare)
- Lista befintliga medlemmar
- Editera befintlig medlem
- Ta bort medlem
Lägga till en Custom section
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.
Först lägger vi till en ny sektion
INSERT INTO umbracoApp (sortOrder, appAlias, appName,
appIcon)
VALUES (9,'customMember','CustomMember','.traymember')
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.
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 <area
alias="sections">. Lägg till en ny rad där
<key
alias="customMember">Custom
members</key>
Klicka sedan på din användare igen i Umbraco admin så ser du att
den tar översättningen från din nya nyckel.

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.

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.
INSERT INTO umbracoAppTree (treeSilent, treeInitialize,
treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed,
treeIconOpen, treeHandlerAssembly, treeHandlerType)
VALUES ('false', 'true', 0, 'customMember', 'Member', 'Member',
'folder.gif', 'folder_o.gif',
'umbBoRatt.Umbraco.Sections.CustomMember', 'LoadMembers')
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
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.
Vi lägger till följande metod
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) && controller.HasGroup(userId, groupId))
{
return true;
}
}
return false;
}
Och på rad 142 kör vi en if-sats för att kolla om medlemmen
tillhör gruppen
if (memberInGroup(m.Id)) {
När vi byggt den koden borde vi få upp en listning av alla
medlemmar som tillhör endast vår egen grupp.
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.
Skapa nya medlemmar
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.
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:
<nodeType
alias="initmember">
<header>Member
</ header>
<usercontrol>/create/member.ascx
</usercontrol>
<tasks>
< delete
assembly="umbraco"
type="memberTasks"
/></tasks
>
</nodeType>
Vi säger nu att när en create med alias
initmember (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:
rootNode.NodeType = "init" +
TreeAlias.ToLower();
Hade vi velat göra vårt eget event behöver vi lägga till en ny
<nodeType> 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:
umbraco.interfaces.ITaskReturnUrl
Editera medlemmar
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.
treeElement.SetAttribute("action",
"javascript:openMember('" +
HttpContext.Current.Server.UrlEncode(u.UserName)
+ "');");
Vi säger att vi kallar på javascriptet openMember(id). I
RenderJS-metoden definerar vi javascriptet som:
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;
}
");
}
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.
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.
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å.
Javascriptet för att "ta bort" grupper:
//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();
});
Ta bort medlemmar
Eftersom vi valde att använda samma <nodeType> 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
umbraco.interfaces.ITaskReturnUrl.
Slutsats
Det här är mer eller mindre det jag tänkte gå igenom i den här
delen.
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.