Arkiv för kategori ‘CMS’

Extensions för EPiServer

Jag har arbetat med EPiServer ett bra tag nu, och har sedan .NET 3.5 släpptes med möjligheten att ”bygga ut” objekt med egna funktioner använt ett gäng sådana för att underlätta mitt dagliga arbete. Jag har haft mina Extensions liggande ett tag på Github men tänkte även skriva en liten post om det här.

Ett exempel på en användning skulle t.ex kunna vara att du vill slumpa ut tio av en sidas barn, du vill också se till att bara hämta de som är publicerade. Genom att ha några smarta extensions så skulle du kunna göra såhär.

PageDataCollection pages = CurrentPage.GetChildren(new FilterPublished(), new FilterRandom(10));

Utan Extensions skulle detta kräva ett antal rader kod ytterligare och det är det lilla extra som gör att man trivs med ett API.
Eftersom filterparametern är en params parameter kan man kombinera ihop hur många filter man vill, egengjorda eller de som ingår i EPiServer. FilterRandom är bara ett enkelt filter för att slumpa ut ett antal sidor som jag gjort.
Min klass innehåller ett antal funktioner för att underlätta arbetet med EPiServer så det är bara att ta ner min klass och se om det är något ni gillar.

Inte nöjd med mina eller vill du ha ännu mer extensions så kan du kolla på EPiCode där man försöker sammanställa bra extensions från epi-utvecklare.

Lär dig leva utan ancestorView

Under våren har jag jobbat med att trimma en webbapplikation som levererar nätupplagan av en av Sveriges större tidningar. CMS-verktyget som används är Escenic i version 4.x och det kommer med en rad egna JSP-tagar. En av dom ska man dock akta sig för – <section:ancestorView>. Den är faktiskt inte så svår att leva utan heller. I den här artikeln visar jag hur.

Responstid före och efter jag bytt ut <section:ancerstorView>

Responstid före och efter jag bytt ut ancerstorview-taggen

Vad är ancestorView?

ancestorView används för att skapa en hierarkisk vy av sektioner utgående från den sektion du anger. Inget speciellt avancerat eller konstigt. Det borde inte heller vara jobbigt för systemet att skapa vyn, tyvärr sker något under ytan som ställer till det. Berätta gärna vad i kommentarerna. ;)

Hur det kan se ut (före)

Ett vanligt sätt att använda sig av ancestorView är för att exempelvis bygga en sökväg till en navigering:

<section:ancestorView id="sectionView" section="${article.homeSection}" includeRoot="true"/>
<menu:use id="navigation" treeName="myMenuName">
	<c:set var="count" value="1"/>
	<view:iterate id="item" name="sectionView">
		<menu:item id="current" sectionId="${item.id}"/>
		<c:choose>
			<c:when test="${count eq 1}">
				<c:set var="sectionPath" value="${current.text}"/>
			</c:when>
			<c:otherwise>
				<c:set var="sectionPath" value="${sectionPath}/${current.text}"/>
			</c:otherwise>
		</c:choose>
		<c:set var="count" value="${count+1}"/>
	</view:iterate>
</menu:use>

Skapa en lättviktig ersättning till ancestorView

En enkel väg till ett liv utan ancestorView-taggar är att skapa en mycket enkel custom tag. Nedanstående implementation har inte stöd för precis allt du kan göra med Escenics variant, men den gör jobbet för de flesta användningsfallen. Jag döpte den till ancestors.tag och la den i /WEB-INF/lib/tags/section.

<%@tag body-content="empty"%>
<%@tag import="neo.xredsys.api.Section, java.util.ArrayList"%>
<%@attribute name="id" required="true" rtexprvalue="false"%>
<%@attribute name="section" type="neo.xredsys.api.Section" required="true"%>
<%@attribute name="includeRoot" type="java.lang.String" required="false"%>
<%@variable name-from-attribute="id" alias="sectionPath" scope="AT_END"%>
<%
	final ArrayList sections = new ArrayList();
	if (section != null) {
		do {
			sections.add(0, section);
			section = section.getParent();
		} while (section != null && ("true".equals(includeRoot) || section.getParent() != null));
	}
	jspContext.setAttribute("sectionPath", sections);
%>

Det enda som egentligen sker här är att jag bygger upp en lista med föräldrasektioner i omvänd ordning genom att anropa Escenics API. Detta går av någon anledning massor med gånger snabbare.

Hur det kan se ut utan ancestorView
<%@ taglib prefix="sec" tagdir="/WEB-INF/tags/section" %>
<sec:ancestors id="sectionView" section="${article.homeSection}"/>
<menu:use id="navigation" treeName="myMenuName">
	<c:forEach var="item" items="${sectionView}" varStatus="itemStat">
		<menu:item id="current" sectionId="${item.id}"/>
		<c:choose>
			<c:when test="${itemStat.first}">
				<c:set var="sectionPath" value="${current.text}"/>
			</c:when>
			<c:otherwise>
				<c:set var="sectionPath" value="${sectionPath}/${current.text}"/>
			</c:otherwise>
		</c:choose>
	</c:forEach>
</menu:use>

Eftersom jag inte längre arbetar med en vy av sektioner, kan jag iterera över listan med föräldrasektioner med en vanlig c:foreach med fördelar som varStatus, mm.

Slutsats

Om du använder Escenic i någon 4.x-version och om du får några träffar när du söker på ancestorView i din kodbas, finns all anledning att se över ett byte!