You are on page 1of 123

Episerver alapjai

Mielőtt egy projekt hivatalosan is elindulhatna, a csapatnak és az ügyfélnek meg kell állapodnia
abban, hogy mit kell felépíteni. Ha ebben megállapodtak, akkor lehet tervet készíteni. A tervnek
tartalmaznia kell a legfontosabb

teljesítendő feladatokat és az ütemtervet. Annak érdekében, hogy megállapodás szülessen arról,


hogy egy projekt mit fog tartalmazni, üzleti elemzők, UX-guruk, tervezők, terméktulajdonosok,
műszaki építészek, kerekesek, kereskedők egyvelege,

mozgatóknak és mozgatórugóknak együtt kell dolgozniuk a projekt teljes körű meghatározásához.

A weboldal újraplatformálása nem olcsó mulatság. Egy egyedi e-kereskedelmi honlapkészítés


általános költségvetése meghaladja az egymillió fontot/dollárt. Ekkora tőkebefektetés esetén a
vállalkozás

természetesen jelentős előnyökre számít. A siker fogalmát minden projekt esetében másképp kell
meghatározni. Egyes vállalatok célja az értékesítés növelése a következők révén

egy jobb e-kereskedelmi platformon keresztül. Másoknak az lehet a céljuk, hogy több ügyfelet
szerezzenek, vagy hogy felfrissítsék a megjelenésüket egy új márkajelzéssel. Az üzleti motivációtól
függetlenül, a projekt nem fog

nem tekinthető sikeresnek, ha nem segíti a vállalkozást e cél elérésében. Feltételezve, hogy Ön a
projekt technikai vezetője. Mindezeket a célokat és célkitűzéseket meg kell határozni, mielőtt
elkezdené a projektet.

a kódolást.

A legtöbb projekt esetében a drótvázakat, a terveket és az ütemtervet egyeztetni és aláírni kell,


mielőtt a fejlesztés megkezdődhetne. Csábító lehet, hogy megpróbáljuk elkezdeni a kódírást, mielőtt
még a hatókörrel

még nem született teljes körű megállapodás. Ha lehetséges, próbálja meg elkerülni ezt a
megközelítést, mivel ez a katasztrófa receptje lehet. Amikor ezzel próbálkoztam, a kód nagy részét
mindig kidobtam. Az én

tapasztalataim alapján a projektet a kész állapot előtt elkezdeni mindig inkább megnövelte, mint
megmentette az időt.

A tervek és a drótvázak határozzák meg a weboldal felépítésének tervét. Az Ön feladata lesz, hogy
ezeket a terveket valósággá alakítsa. Egy tipikus projekt során a legtöbb ügyfél a következőket
szeretné tudni a költségeket. Ez azt jelenti, hogy a vízesés-módszertan iránti gyűlöleted és az agilis
módszertan iránti szereteted ellenére rendkívül valószínű, hogy becslést kell adnod arról, hogy a
projekt mennyi ideig tart majd a projekt kezdetén. Az idő- és költségbecslés nagyon összetett feladat,
különösen, ha ez az első Episerver-projektje. Hogyan adhatna pontos becslést anélkül, hogy teljes
mértékben

a platform megértése nélkül? Sajnos ez az a világ, amelyben élünk. Az Ön feladata lesz, hogy az elején
becsléseket adjon, függetlenül attól, hogy mennyire érti az Episerver-t. A cím lefedése

a becslések részletes bemutatását egy könyv lenne önmagában! Adok azonban néhány olyan eszközt,
amely segít kezelni ezt a forgatókönyvet. Mivel az előzetes becslések készítése nagyon gyakori
feladat, ezért ez a következőképp néz ki itt fogjuk kezdeni az utazásunkat.
A projektbecslés elkészítése általában egy táblázatban történik. Először is fel kell írnia az összes olyan
feladatot és lépést, amelyek Ön szerint szükségesek a projekt megvalósításához.

Ez a folyamat nehéz lehet, és egy kicsit kényelmetlenül érezheti magát, különösen, ha új a vállalati
szintű webfejlesztésben. Sok esetben a projekt még nem lesz teljes körűen megtervezve. Ez teszi

lehetetlenné teszi, hogy 100%-os pontosságú becsléseket adjunk. Lehet, hogy szorong és tétovázik,
hogy helytelen becsléseket adjon. Senki sem szeret téves információkat adni, amelyekért Önt is
felelősségre vonhatják a későbbiekben.

Amikor arra kérik, hogy vállaljon becslést, akkor azt tanácsolom, hogy a lehető legpontosabb legyen.
Minél több feladatot tud leírni, annál nagyobb az esélye annak, hogy a becslése

pontos lesz. A számok megállapításának folyamata egyszerű. A táblázatban szereplő minden egyes
feladathoz adjon hozzá egy kis időt. A becsült időt akár órák vagy embernapok felhasználásával is
hozzáadhatja. Én az órákat részesítem előnyben.

Miután minden egyes feladathoz hozzárendelt egy kis időt a lapon, adjon hozzá néhány szorzót. Az
általam javasolt közös szorzók közé tartoznak:

• TIme to write test scripts


• Testing time
• Project management oversight
• Team-lead oversight
• Release management time
• Ceremony time (sprint planning, retros, etc..)
• Tesztelési szkriptek írásának ideje
• Tesztelési idő
• A projektmenedzsment felügyelete
• Csapatvezetői felügyelet
• Kiadási menedzsment idő
• Ceremóniaidő (sprinttervezés, retró stb...)

Bármennyire is szorgalmas, a projekt ezen szakaszában lehetetlen 100%-os pontosságú becslést adni.
Ismét visszatérve A mítikus emberhónaphoz, az emberek elfogultak a becslésben.

Természetes módon mindenki hajlamos alulbecsülni, hogy mennyi ideig fog tartani egy feladat, ezért
a becslés során ezt a tényt szem előtt kell tartanod, és túl kell kompenzálnod. Szintén ebben a
szakaszban nem lehet tudni az összes szükséges feladatot, így a megértés hiányának és a becslési
torzításnak az ellensúlyozására hajlamos vagyok megduplázni a becslésemet ezen a ponton.

Nem számít, mennyire szorgalmas, a projekt ezen szakaszában lehetetlen 100%-os pontosságú
becslést adni. Ismét visszatérve A mítikus emberhónap című könyvre, a könyv rámutat arra, hogy mi,
mint embereknek van egy becslési torzításunk. Természetes módon mindenki hajlamos alulbecsülni,
hogy mennyi ideig fog tartani egy feladat, ezért a becslés során ezt a tényt szem előtt kell tartanod,
és túl kell kompenzálnod. Szintén ebben a szakaszban lehetetlen megismerni a szükséges feladatok
végleges listáját. Ezt a teljes listát csak a projekt előrehaladtával tudja majd meghatározni, és csak
akkor lesz képes jobban megérteni. A címre a megértés hiányát és a becslés torzítását
ellensúlyozandó, ebben a szakaszban hajlamos vagyok megduplázni a becslésemet.
A legtöbb projekt esetében nagyon valószínű, hogy a tervezőcsapat még soha nem dolgozott
korábban Episerverrel. Következésképpen fogalmuk sincs arról, hogy mi működik jól az Episerverben.
A tervezőcsapat általában nem elég műszaki szakember ahhoz, hogy megértse, mire képes egy CMS.
Ez azt jelenti, hogy általában a fejlesztőcsapat feladata megtervezni, hogyan fog működni a backend.
Ez egy olyan problémát jelent.

Egy rendszer tervezésekor a fejlesztő hajlamos arra összpontosítani, hogy valami funkcionálisan
működő dolgot készítsen. Általában a backend-fejlesztők ritkán gondolnak a használhatóságra. Van
egy természetes feszültség aközött, hogy valami funkcionálisan működjön, és aközött, hogy valami
használható legyen. A tartalomszerkesztők általában nem műszaki szakemberek. Amikor a nem
műszaki szakemberek tartalmat használnak és írnak egy CMS-en belül, nagy a valószínűsége annak,
hogy valaki olyasmit tesz, ami időről időre tönkreteszi a weboldalt. A tartalomszerkesztőknek sajnos
megvan a képessége arra, hogy elrontsanak dolgokat.

Annak az esélyét, hogy egy tartalomszerkesztő tönkretegye a weboldalt, sok fejlesztő azzal a
megközelítéssel igyekszik ellensúlyozni, hogy a CMS-t nagyon korlátozóvá teszi. Érvényesítések
hozzáadása és a tartalom szerkesztőnek minimális rugalmasságot adva megakadályozza, hogy
véletlenül tönkretegye a webhelyet. A sok validáció hozzáadásával és a CMS nagyon korlátozóvá
tételével az a kompromisszum, hogy a CMS-t nagyon frusztrálóvá teszi a CMS használatát.

A fejlesztőknek ritkán kell tartalmat írniuk. Valójában a legtöbb CMS-fejlesztőnek soha nem kell sok
tartalmat írnia egy CMS segítségével egész pályafutása során. A fejlesztő egy drága erőforrás. Egy
fejlesztőt megkérhetnek arra, hogy egyszer-egyszer a kék holdon finomítson néhány tartalmat, de
ritkán kell hosszabb ideig tartalmat írnia.

A funkcionalitás és a használhatóság közötti egyensúly megtalálása eléggé hiánypótló képesség. A


tapasztalatlan, az Episerverrel újonnan ismerkedő fejlesztők könnyen félreérthetik ezt az egyensúlyt.
Ha a fejlesztőcsapatnak tartalmat kellene írnia, akkor nagyon biztos vagyok benne, hogy bármi, ami
az írás élményét nehézkessé teszi, gyorsan eltávolításra kerülne. A dolgok betöltésére várni és a
tartalom újraírására kényszerülni az frusztráló. Érezte már úgy, hogy dühöng, amikor megpróbál
kitölteni és elküldeni egy online űrlapot, az érvényesítés beindul, majd elveszíti az űrlap összes
adatát? Ez nagyon bosszantó. Túl sok érvényesítés hozzáadása ezt a bosszúságot a
tartalomszerkesztő életének mindennapos részévé teszi.

Lehet, hogy kísértésbe esik, hogy figyelmen kívül hagyja a tartalomszerkesztő igényeit egy
projektben. Ez hiba. Láttam már, hogy a boldogtalan tartalomszerkesztők miatt megromlik a
kapcsolat egy ügynökséggel. Ha megtervezi a Episerver weboldalát úgy, hogy az ne legyen
használható a tartalomszerkesztők számára, akkor rossz munkát végzett. CMS-fejlesztőként az a
kihívás, hogy olyan weboldalt tervezzen, amely úgy néz ki és úgy viselkedik, ahogyan az a tervezők
szándéka szerint, ÉS lehetővé tegye a tartalomszerkesztők számára is, hogy napi szintű dühöngés
nélkül írjanak tartalmat.

Ennek az egyensúlynak a helyes megteremtése az, ahol a szilárd Episerver-ismeretek


kulcsfontosságúak. Az Episerver használatának egyik fő előnye, hogy nagyon rugalmas. Lehetőség van
arra, hogy az ugyanazt a dizájnt számos módon megvalósítani. Miközben ezt a könyvet olvassa,
figyeljen a dizájn és a tartalomszerkesztők CMS-en belüli interakciója közötti egyensúlyra. A
tartalomszerkesztő szem előtt tartása segít egy jobb megoldás létrehozásában.
What The Heck Is A Page Type - Mi a fene az az oldaltípus
Mindenki tudja, mi az a sablon. A sablonok nem újak. A sablonok már az első CMS platformok
megjelenése óta léteznek. A sablon egy egyszerűen felfogható fogalom. Egy sablon egy olyan
oldaltípusnak felel meg, amelyet a weboldalon létre lehet hozni. Általában egy oldaltípus egy
sablonhoz rendelhető. Példák a közös sablonokra, amelyekkel bármelyik oldalon találkozhat
projektben megtalálhatóak:

• Homepage
• Search Page
• Landing Page
• 404 Page
• Content Page ( Tartalom oldal)

A különböző CMS-rendszerek különböző terminológiát használnak arra, ami alapvetően egy oldal-
sablon. A sablonokra számos kifejezéssel lehet hivatkozni, beleértve a dokumentumtípusokat,
csomópontokat, oldaltípusokat, adattípusok, tartalomtípusok és végül oldalak.

Az Episerver terminológiájában egy hagyományos sablont oldal-típusnak nevezünk. Ebben a


könyvben, amikor sablonra, tartalomtípusra vagy oldaltípusra hivatkozom, ugyanerre a fogalomra
utalok. Technikailag van néhány apró árnyalatnyi különbség az egyes kifejezések között - amelyekről
rövidesen szó lesz -, de az egyszerűség kedvéért tegyük fel, hogy ugyanazt jelentik.

Klasszikus sablonok, klasszikus problémákkal


A 90-es években, amikor a pörgő .gif fájlok voltak a divatban, és a CMS rendszerek első hulláma
elérhetővé vált, a sablonok egy-egy oldalhoz tartoztak. Egy CMS a következő elemekből állt

sablonokból állt, amelyeket a tartalomszerkesztő használhatott a tartalom megírásához. Ezek a


sablonok egy nagyon fix elrendezést határoztak meg.

Ha egy tartalomszerkesztő meg akarta változtatni egy sablon elrendezését, akkor kénytelen volt
változtatási kérelmet benyújtani a technikai csapathoz. A kérés bekerült a fejlesztő számára a
hátralévő munkák közé, hogy a fejlesztő dolgozhasson rajta.

dolgozzon. Amikor a kérés elég magas prioritásúnak minősült, egy fejlesztő kapta meg a feladatot.
Miután a kódváltoztatásokat elvégezték, a forráskód-ellenőrzésbe bevitték, és tesztelték, akkor egy

a gyártáshoz szükséges kiadásra kerülne sor. A termelési telepítések kockázatot jelentenek a webhely
stabilitására nézve. A kockázat csökkentése és a hatékony munkavégzés érdekében a legtöbb vállalat
hajlamos arra, hogy több kötegelt változtatásokat egy kiadásba, mielőtt a telepítésre kerülne sor.

Ez azt jelenti, hogy több hónap is eltelhetett a tartalomszerkesztő által kért elrendezésváltoztatás és
a termelésben való megjelenés között. Ez a munkafolyamat nyilvánvalóan nem volt ideális, és
frusztrációt okozott. A fejlesztőket frusztrálta, hogy hétköznapi feladatokon kellett dolgozniuk. A
tartalomszerkesztőket frusztrálta, hogy ilyen sokáig kellett várniuk az egyszerű
elrendezésmódosításokra. A vállalkozás pénzt is veszített, mivel az egyszerű változtatások
végrehajtása túl sokba került. Mivel a hagyományos sablonok sok korlátozással jártak, az Episerver a
V7-ben bevezette a "tartalom" fogalmát. A "tartalom" fogalmával az Episerver kiszélesítette a
tartalomszerkesztők tevékenységi körét a CMS-en belül. A "tartalom" modell felé való elmozdulás a
"sablon" modell helyett megszüntette az oldal és a sablon közötti egy az egyben megfeleltetést.
What is a Block - Mi az a blokk?
A legnagyobb tervezési paradigmaváltás, amely a "tartalom" fogalmával együtt jött, a blokk volt. A
"blokk" az Episerver terminológiája annak, amit a legtöbben komponensnek neveznek. Néhány
gyakori példák a blokkokra, amelyekkel egy átlagos Episerver-építés során találkozhatunk:

• Call To Action
• Carousel
• Contact Form
• Accordion
• Hero Banner
• Felhívás a cselekvésre
• Körhinta
• Kapcsolat űrlap
• Akkordion
• Hero banner

A blokkokban az a jó, hogy sokkal nagyobb hatalmat adnak a tartalomszerkesztőknek az oldal


elrendezése felett. A blokkok a tartalomszerkesztő által választott sorrendben rendezhetők és
szervezhetők az oldalon. Az egyik oldalon a tartalomszerkesztő dönthet úgy, hogy a blokkokat úgy
rendezi el, hogy az oldal tetején egy banner jelenjen meg. Egy másik oldalon a tartalomszerkesztő
dönthet úgy, hogy a bannert teljesen elhagyja. A CMS amely lehetővé teszi a tartalomszerkesztők
számára a rugalmas elrendezés kialakítását, jó értékesítési szempont. Bárki, aki Episerver-licencet
vásárol, elvárja, hogy a webhelyet blokkarchitektúrát szem előtt tartva építse fel.

A blokkok az architektúra szempontjából is sok technikai előnyt nyújtanak. A blokkok megjelenése


előtt nagyon gyakori volt, hogy egy webhely több nagy monolitikus sablonból állt össze. Ez volt nem
volt ritka, hogy rendszeresen olyan sablonokon dolgoztunk, amelyek megsértették a KLOC (több ezer
sornyi kód) határát. Ezek az istenszerű sablonok rengeteg spagettikódból és funkció-jelzőkből álltak,
amelyek a kevés értelme volt annak, aki először vette kézbe a projektet. Ezekkel a sablonokkal
borzalmas volt dolgozni, és igazi karbantartási rémálmot okoztak.

A blokkarchitektúra használatával a CMS-fejlesztők mostantól ezeket az óriási sablonokat kisebb


alkomponensekre bonthatják. Ez a képesség, hogy a sablonokat kisebb komponensekre bontják, segít
egyszerűsíteni a kódbázis egyszerűsítését. A blokkok manapság talán kézenfekvő megoldásnak
tűnnek, de amikor először bevezették őket, teljesen megváltoztatták a játékot. Egy CMS rendszer
blokkokkal történő tervezése határozottan a dolgok jobbá tételét. Mint minden új programozási
technika, a blokkok is számos új mintát és anti-mintát vezettek be.

Az egyik anti-mintázat, amelybe sok, az Episerverrel újonnan ismerkedő fejlesztő hajlamos beleesni, a
beágyazás. Az Episerverben lehetőség van arra, hogy blokkokat hozzunk létre más blokkokon belül.
Mint a legtöbb dolog az életben, ez is lehetséges, hogy a jóból túl sok van. A túl sok egymásba
ágyazott blokk a tartalomszerkesztők számára unalmas backend CMS-élményt eredményezhet. A túl
sok egymásba ágyazott blokkot tartalmazó oldalakon való áthaladás fájdalmas. Néhány szélsőséges
esetben találkoztam olyan weboldalakkal, amelyek annyira egymásba ágyazottak és összetettek,
hogy a tartalomszerkesztő képtelen volt oldalakat létrehozni egy fejlesztő segítsége nélkül.

A korlátlan tartalomszerkesztői rugalmasság és a tartalomszerkesztő használhatósága közötti


kompromisszumot nagyon finom egyensúlyt kell megtalálni. Egy jó ökölszabály, hogy csak egyszintű
egymásba ágyazottságra kell törekedni. Egy Episerver rendszer, amely a blokkok minimális egymásba
ágyazásával épül fel, jobb tartalomszerkesztési élményt nyújt.

Local Blocks, Shared Blocks And Content Areas - Helyi blokkok, megosztott
blokkok és tartalmi területek
Az Episerverben kétféle blokk használható, a globális blokkok és a helyi blokkok. A helyi blokk, ahogy
a neve is mutatja, egy olyan blokk, amelynek tartalma csak az adott oldalon érhető el. A címre helyi
blokkot hozzon létre, fejlesztőként a blokk típusának meghatározását tulajdonságként keményen be
kell kódolnia egy sablonba. Ha egy blokkot keményen kódolunk egy sablonba, akkor ugyanúgy fog
viselkedni mint bármely más tulajdonság, amelyet definiál.

A megosztott/globális blokk sokkal rugalmasabb. A megosztott/globális blokkot a kódban pontosan


ugyanúgy kell definiálni, mint a helyi blokkot. A kettő közötti különbség a blokkok létrehozásának
módja.

Míg a local-blockok definiálása egy sablonba történő kemény kódolással történik. A megosztott
blokkot a CMS-en belül a tartalomszerkesztők hozzák létre. A megosztott blokk akkor jön létre,
amikor egy tartalomszerkesztő létrehoz egy blokkot egy úgynevezett "Tartalomtartalom területén"
belül.

A tartalmi terület egy speciális Episerver tulajdonság. A tartalmi terület lehetővé teszi a
tartalomszerkesztők számára, hogy blokkokat/komponenseket adjanak hozzá egy oldalhoz. A tartalmi
területek nagyon rugalmasak, és lehetővé teszik a tartalomszerkesztők számára, hogy hogy olyan
klassz dolgokat adjanak meg, mint például:

• The width of the block (full, half, quarter, etc..)


• The type of blocks to add to a page
• The order the blocks appear on a page
• A blokk szélessége (teljes, fél, negyed, stb...)
• Az oldalhoz hozzáadandó blokkok típusa
• A blokkok megjelenési sorrendje az oldalon

Ha a blokkarchitektúrát A/B teszteléssel kombinálja - ami az Episerverrel már alapból benne van a
dobozban -, akkor a tartalomszerkesztők számára egy nagyon hatékony módot kap a webhely
weboldalainak strukturálásához és majd mérőszámokkal validálják a döntéseiket. Képzelje el, hogy
cége javítani szeretné egy, a honlapon reklámozott termék konverziós arányát. Egy
tartalomszerkesztő, aki csak blokkokat használ, képes ezt megteheti.

Egy tartalomszerkesztő létrehozhat egy A/B kísérletet két különböző típusú blokk használatával,
amelyek mindkettő a termék megvásárlására próbálja csábítani a felhasználót. Miután az egyik blokk
eléri a "statisztikai szignifikanciát" a az átkattintási arányok tekintetében, a kevésbé hatékony blokkot
nem lehet közzétenni, és a kísérletet le lehet zárni. Az A/B teszteléssel a tartalomszerkesztők olyan
weboldal elrendezést hozhatnak létre, amelyet matematikailag ahelyett, hogy egyszerűen arra
hagyatkoznának, amit a tervező remél, hogy konvertálni fog. A webhely látogatói élmény ilyen
módon történő finomítása az Episerver használatának igen nagy üzleti előnye.

Mindez persze remekül hangzik, rugalmas elrendezésekkel és A/B teszteléssel a dobozból. Van
azonban egy hátulütője is. A tanulási görbe meredekebb. A sok e-mail alapján, amit az emberektől
kaptam a világ minden tájáról, sok fejlesztő számára a tervezés sablonokra és blokkokra bontásának
kitalálása jelenti a nehézséget.
Deciding What Episerver Pages And Blocks You Need - Annak eldöntése, hogy
milyen Episerver oldalakra és blokkokra van szüksége
Ennek a vizsgálati fázisnak a kimenete egy specifikáció lesz, amelyet a csapat felhasználhat a
fejlesztés megkezdéséhez. Az Ön feladata lesz, hogy fogadja a terveket, kitalálja, mit kell építeni,
majd létrehozzon egy dokumentumot, vagy egy köteg JIRA-jegyet, hogy a fejlesztőcsapat
elkezdhesse. Rövidesen részletesen végigvezetem az általam követett folyamatot, azonban célszerű
lehet, ha egy gyakran figyelmen kívül hagyott témával, a nyomással.

Amikor először kezdi el felülvizsgálni a terveket, és átalakítani azokat az Episerverben létrehozandó


sablonokká és blokkokká, amelyekről úgy gondolja, hogy létre kell hozni őket, előfordulhat, hogy
bizonyos érzéseket érez majd szorongás. Nem számít, milyen szintű programozási tapasztalattal
rendelkezik, egy új CMS-projekt elkezdése ijesztő érzés lehet. Ez a szorongás érzése általában két
tényező egyikének eredménye:

• Imposter-szindróma, az a kis hang a fejedben, amely azt mondja, hogy nem vagy elég okos
ahhoz, hogy valamit csinálj...
• Analízisbénulás, a túlterheltség érzése, amikor az agy túl sok lehetőséggel szembesül. Az
analízisbénulás a normális élet minden területén előfordulhat. Voltál már valaha is
döntésképtelen egy étteremben, amikor egy menü sok választási lehetőségével szembesült?
Képzelje el, milyen rosszul tud beindulni az analízisparalízis, amikor arra kérik, hogy tervezzen
meg valamit, ami sokkal bonyolultabb, mint egy mint egy étlap?

Már az is lehetetlen feladatnak tűnhet, hogy tudjuk, hol kezdjük el. Nem könnyű kitalálni, hogyan
fogsz egy új projektbe belevágni. Senki sem születik szakértőnek semmiben. A webes ismeretek
elsajátítása webfejlesztés időbe telik. Nem számít, mennyire tapasztalt, minden új projektnél mindig
lesznek olyan dolgok, amelyekben nem vagy biztos.

Lehet, hogy először használja az Episervert, vagy ez lehet az első e-kereskedelmi projekt, amelyen
dolgozik. Integrációs szempontból lehet, hogy egy új keretrendszert, eszközt kell implementálnia,
vagy programozási nyelvet, amellyel még soha nem dolgozott. A CI/CD csővezeték felállításáról már
ne is beszéljünk. Ez a lista a megfontolandó dolgokról még hosszan folytatható lenne. Ez a lista is
naponta változik.

Azért írom ezt, hogy felkészülhess. Egy projekt elindítása kétségeket és szorongást okozhat, ez
normális. Nem ön lesz az első, aki így érez, és nem is az utolsó. Ezek a érzések annak az eredménye,
hogy a komfortzónádon kívülre lépsz. Ha elkezded átélni ezeket az érzéseket, az azt jelenti, hogy
tanulsz, és ez jó!. Azzal a tudattal, hogy ebből a könyvből magaddal viszel, és egy nagyon egyszerű
folyamatot követve egy ijesztő projektet is sok apró, könnyebben kezelhető részfeladatra bonthatsz.
Ehhez beszélnünk kell a folyamatról.

Én egy nagyon pragmatikus megközelítést követek, amikor új projektbe kezdek. Azzal kezdem, hogy
egyszerűen egyetlen oldalra összpontosítok a terveken belül. Átnézem az oldalt, és kitalálom az
összes összetevőt és tulajdonságokat, amelyekre szükség lesz, és dokumentálom őket. Miután egy
oldal finomítottam, kiválasztok egy másik oldalt, és azt is finomítom. Ezt a folyamatot aztán
megismétlem, egy-egy tervvel, amíg az összes terv át nem nézem.

Van valami a terv megvalósítási tervvé alakításában, ami tényleg segít abban, hogy sokkal jobb
mentális modellt kapjon arról, hogy mit kell megépíteni. A szokásos finomítási folyamat a tervek
számától függően egy naptól néhány hétig is eltarthat. A tervezés finomításakor próbáljon meg nem
ragaszkodni a tökéletességhez. A cél az, hogy jobban megértsük a projektet. A fejlődés, nem pedig a
tökéletesség.

Amikor először kezdtem CMS-rendszereket építeni, a digitális ügynökségek hajlamosak voltak


vízesésszerűen dolgozni. A szokásos folyamat része volt egy monolitikus specifikáció megírása a
projekt kezdetén. Hasonló A dokumentum a legójátékokhoz hasonlóan tartalmazott egy sor utasítást
arra vonatkozóan, hogy hogyan kell felépíteni a weboldalt. Amikor az ügyfél elégedett volt a
specifikációval, aláírta azt, és a fejlesztés megkezdődhetett. Ezzel a megközelítéssel több jelentős
probléma is volt.

Először is, a specifikáció általában nagyon gyorsan elavul. Még ha a specifikáció elkészítése több
hónapot is vett igénybe, az élet ritkán áll meg, hogy egy Word dokumentumon dolgozzanak, a dolgok
változnak. A szállítási nyomás és a szoros határidők miatt a projektben részt vevő fejlesztőknek
gyakran nem volt idejük arra, hogy a specifikációt a legújabb módosításokkal naprakészen tartsák. Ez
azt jelenti, hogy néhány kezdeti olvasás után a specifikációban már nem bíztak, mint a projekt
evangéliumában, és általában valakinek az asztalfiókjába került, hogy soha többé ne lásson
napvilágot. Ha Ön egy projekten dolgozott és elég szerencsés volt ahhoz, hogy valaki frissítse a
specifikációt, egy másik probléma a verziókezelés volt. Gyakran előfordulhatott, hogy egyazon csapat
fejlesztői a specifikáció különböző verzióival dolgoztak. Másodszor, ezek a monolitikus
dokumentumok általában hosszúak, nagyon technikai jellegűek és nagyon szárazak voltak. Ez azt
jelentette, hogy az ügyfél legtöbbször nem értette igazán, hogy mit is ír alá. A megértés hiányának
következménye gyakran azt jelentette, hogy a végső weboldal gyakran nem azt csinálta, amit az
ügyfél valójában akart.

Egy Episerver projekt magában foglalja egy sablonkészlet és egy nagyszámú komponensgyűjtemény
létrehozását, amelyek lehetővé teszik a vállalat számára, hogy gazdag és dinamikus tartalmat építsen.
Ahelyett, hogy pontosan meghatároznánk, hogy egy weboldal hogyan fog működni, inkább azokat az
összetevőket kell részleteznie, amelyek a tartalomszerkesztők számára elérhetőek lesznek, hogy
tartalmakat hozzanak létre velük. Lehetetlen lesz minden egyes permutációt meghatározni, amelyet
egy tartalom szerkesztő potenciálisan egymásra rakhatja a blokkokat. Ezért a hagyományos
specifikáció nem túl hasznos az Episerver-projekteknél.

Amikor egy új Episerver-projektbe kezdek, a hagyományos specifikáció helyett inkább egy olyan
dokumentumot készítek, amelyet komponenskatalógusnak nevezek. Feltételezem, hogy más
ügynökségek is hasonló technikát használnak, azonban, amikor erről írtam több mint 10 évvel
ezelőtt, egyetlen más blog, könyv vagy weboldal sem említett semmi hasonlót, így ezt az én
ötletemnek állítom!

A komponenskatalógus megszületése annak az eredménye volt, hogy időhiány miatt nem volt elég
idő egy megfelelő specifikáció megírására. Ahelyett, hogy egy "hagyományos" specifikációt
készítettem volna, egy képernyőképes eszközt használtam, hogy gyorsan prototipizáljam az összes
Episerver oldalt és blokkot, amelyet a projekt a terv alapján használni fog. Ezután a képernyőképeket
színes dobozokkal kommentáltam, és hozzáadtam néhány információt arról, hogy a fejlesztőnek
hogyan kell felépítenie az egyes komponenseket. Ezt a dokumentumot végül projektbibliának
neveztem el, és annyira hasznos volt, hogy azóta is ugyanezt a folyamatot követem.

A komponenskatalógus célja, hogy legyen valami, ami vegyíti a vizuális elemeket, miközben elkerüli a
sok száraz tartalmat. Célja, hogy mind az ügyfél, mind a fejlesztők számára könnyen érthető legyen. A
legtöbb A legfontosabb, hogy könnyen és gyorsan változtatható legyen. Komponenskatalógust
Wordben is létrehozhat, azonban a formázás helyes megtartása fájdalmas. A verziókezelés Wordben
szintén fájdalmas. Ha a katalógust e-mailben elküldik a csapatnak visszajelzés céljából, akkor a
legutóbbi változtatások nyomon követése és visszaolvasztása a főverzióba egyszerűen időpocsékolás.
Az én javaslatom az, hogy hozzon létre egy komponenskatalógust a confluence-en belül. Amikor egy
komponens készen áll a felülvizsgálatra, a linket meg lehet osztani a csapatban. Az emberek ezután
könnyen visszajelezhetik az ötleteket, ha megjegyzéseket hagynak az oldalon. I általában azt
tapasztalom, hogy az ebben a felülvizsgálati fázisban az emberek által hagyott megjegyzések olyan
típusú projektinformációk, amelyek máshol soha nem kerülnek rögzítésre. Ezek a megjegyzések
nagyon hasznosak lehetnek a jövőbeli fejlesztők számára akiknek fel kell venniük a projektet, és meg
kell érteniük, hogy miért épültek meg a dolgok egy bizonyos módon.

Egy komponens dokumentálásához a komponenskatalóguson belül menjen végig a


terveken/vezetékkereteken, és egy képernyőfelvevő eszközzel készítsen egy képernyőfelvételt a
vizsgált elemről. A legjobb eszköz, amivel rendelkezem erre a célra a GreenShot nevű ingyenes
eszköz. A GreenShotnak van egy nagyszerű megjegyzési funkciója, amely lehetővé teszi, hogy
alakzatokat rajzoljon a képernyőképen lévő komponensek köré. Bármilyen eszköz megfelel, ha
könnyen megjegyzésekkel látja el a képernyőképeket. A GreenShot telepítése után egyszerűen
nyomja meg a képernyőnyomtatás gombot, hogy képernyőképet készítsen, amelyet aztán
szerkeszthet. Mielőtt erre a felülvizsgálatra vállalkozna, ne feledje, hogy a terven belül megadott
oldalak és komponensek általában nem egy az egyben leképezhetőek egy Episerver komponensre.
Még az is előfordulhat, hogy ellenállás a tervezőktől ebben a fázisban. Itt álljon helyt. A
tervdokumentumban meghatározott komponensek közvetlen leképezése az Episerver
komponensekre egy másik csapda, amely igazán CMS-élményhez vezethet. Több ügynökséget láttam,
akik kizárólag a tervben meghatározott komponensek alapján építettek Episerver-alapú
weboldalakat. Ezeket a weboldalakat mindig nehézkes használni. A komponenseknek gyakran kevés
értelme van a tartalomszerkesztők számára, és ami azt illeti, bárki számára, aki nem volt az eredeti
projektcsapat tagja.

Miután befejezte a tervek átnézését, a végeredmény egy komponenskatalógus lesz, amely felsorolja
az összes olyan oldalt és blokkot, amelyet az Episerverben kell felépítenie. Ezen a ponton pontosabb
újbóli becslést kell tudnia adni, mivel sokkal jobban meg fogja érteni a projektet. Amikor a
komponensek definiálva vannak, az összes tulajdonságukkal és integrációs pontjukkal együtt
figyelembe véve, sokkal részletesebben fogja értékelni az egyes komponensek összetettségét. Egy
pólóméretű időbecslés hozzáadása - kicsi, közepes, nagy, extra nagy - minden egyes komponenshez,
segít figyelembe venni a komplexitást.

Step-By-Step Component Catalog Guide - Lépésről lépésre komponens


katalógus útmutató
Az alkatrészkatalógusomat három fő részből szoktam összeállítani:

• Pages - used to list all the templates


• Blocks - used to list all the blocks
• Share Components - used to list anything that is shared between pages, like the header and
footer
• Oldalak - az összes sablon felsorolására szolgál
• Blokkok - az összes blokk felsorolására szolgál
• Share Components - az oldalak között megosztott elemek, például a fejléc és a lábléc
felsorolására szolgál.
Az ok, amiért a megosztott komponensek szekciót támogatom, az az, hogy elkerüljük a duplikált
munkát. Függetlenül attól, hogy kódolok vagy tartalmat írok, a DRY-elv szerint dolgozom. Ne
ismételjük meg ne ismételd magad. A fejléc és a lábléc számos oldalon fog létezni. A megosztott
szakasz lehetővé teszi, hogy egyszer definiáljon egy komponenst, nem pedig minden egyes sablonon.

A leglogikusabb oldal a honlap, ahol a tervek lebontását el lehet kezdeni. A kezdőlap a weboldal
bevezetője. Ez a gyökércsomópont a weboldal oldalhierarchiájában. Ön meg kell építenie a
kezdőlapot, mielőtt bármilyen más oldalt létrehozhatna az Episerverben. Tehát hacsak nincs rá jó
oka, kezdje a kezdőlappal.

A folyamat megkezdéséhez készítsen egy képernyőfotót a kezdőlapról a tervezésből. Használja a


GreenShot "szerkesztő mód" funkcióját. Kezdje el kiemelni a különböző tulajdonságokat, amelyek
némi kódolást igényelnek erőfeszítés. Ez általában az oldalon található összes szöveget, képet és
linket tartalmazza. Határozza meg a lehetséges tartalmi területeket és blokkokat.

Egy példa erre a feladatra az alábbiakban látható:

Megjegyzések készítéséhez válassza ki a GreenShot szerkesztő módban a "Téglalap rajzolása" eszközt.


Az áttekintés közben szeretné:

• Kiemelni az összes tulajdonságot


• Kiemelni mindent, amiről úgy gondolja, hogy blokk lesz
Sokkal könnyebbé teszi az életét, ha minden megjegyzéshez más színt használ, hogy könnyen
megkülönböztesse a különböző komponenseket. Egyes vállalatok számokat használnak az egyes
elemek meghatározására a megjegyzéseket. Nem ajánlom ezt a megközelítést, mivel több időt vesz
igénybe a beállítás és a kezelés. A folyamat végén egy képernyőképet kell kapnia, amelyen rengeteg
színes téglalap van. A következő lépés a kísérő confluence oldal létrehozása. Adja hozzá a létrehozott
képernyőképet GreenShotban készített képernyőképet az oldal tetejére. A kép alatt hozzon létre egy
táblázatot 5 oszloppal. Az oszlopok nevei a következők legyenek:

• Colour
• Name
• Type
• Tab
• Notes

Az alábbiakban részletesen leírjuk, hogy mit kell hozzáadni az egyes oszlopokhoz.

Szín A GreenShot segítségével kiemelt terület színe a képernyőképen belül.

Név Az oldal/blokk megjelenített neve a szerkesztőn belül. Ennek a folyamatnak nem kell egzakt
tudománynak lennie. A jó névadás azonban fontos, ezért gondosan gondolja át!

Type A tulajdonság típusa, vagy az általa használt blokkra/komponensre való hivatkozás.

Tab A CMS-en belül annak a lapnak a neve, amelyen a tulajdonság megjelenik. A gyakori lapnevek
lehetnek main, content, settings, vagy media.

Megjegyzések Bármilyen további megjegyzés, például, hogy a tulajdonságnak szüksége van-e


érvényesítésre, vagy az adatforrás.

Egy példa arra, hogy ez hogyan nézhet ki, az alábbiakban látható:

Ha azonosította azokat az új blokkokat, amelyekre az oldalon szükség lesz, a következő lépés az, hogy
létrehozza a megfelelő oldalt minden egyes blokkhoz a confluence-en belül. Minden egyes blokkhoz
megismétlem a folyamatot a fent leírtakat. Képernyőképet készítek a blokkhoz tartozó tervezetről a
GreenShot segítségével. A képernyőképet jegyezze meg színes dobozokkal, amelyek az összes
tulajdonságot és minden olyan tartalmi területet vagy más blokkot ábrázolnak, amelyet azonosítani.
A kép alatt hozzon létre egy táblázatot, amely leírja, hogy az egyes tulajdonságok és blokkok hogyan
épülnek fel a CMS-en belül.

Miután befejezte az összes megjegyzést egy blokkhoz, végül frissíteném az eredeti sablonoldalt a
Confluence-en belül. A blokkot befogadó tartalmi terület jegyzetek szakaszán belül a blokknak helyet
adó tartalmi területhez, én hozzáadnék egy linket, amely a blokk specifikációját tartalmazó új
confluence oldalra mutat. Az oldalra mutató link hozzáadása talán macerásnak tűnik, de ez azt
jelenti, hogy egyszerűen hivatkozhat arra az oldalra blokkra a confluence bármely más oldalán,
beleértve más sablonokat is, nagyon egyszerűen.

Hogy nagyjából érzékeltessem, mennyi ideig tarthat ez a folyamat, egy körülbelül 20 oldalt és 40
blokkot tartalmazó katalógus meghatározása összesen nem több mint 3 napot vesz igénybe. Ne
feledje, a cél a katalógus célja, hogy jó kiindulópontot adjon. Nem az a cél, hogy tökéletes legyen,
hanem az, hogy segítsen a projekt továbblépésében.

Egy terv Episerver komponensekre való lebontása összetett tevékenység. Mint minden új készség
elsajátítása, az első próbálkozás lesz a legnehezebb. Gyakori, hogy némi szorongást érzünk, amikor
amikor először vállalkozik egy felülvizsgálatra. Mivel nincs véglegesen helyes vagy helytelen
megoldás, nehéz lehet tudni, hogy optimálisan alakította-e át a dolgokat. Az alkatrész célja katalógus
célja, hogy segítsen az előrehaladásra összpontosítani. Továbbá ne aggódjon túlságosan, ha ebben a
fejezetben néhány dolognak még nincs teljes értelme. Jegyezze fel azokat a területeket, amelyekkel
kapcsolatban aggályai voltak.

Később részletesebben kutassa fel ezeket az ötleteket. Az ok, amiért ezt a fejezetet az Episerver
részletesebb bemutatása elé helyeztem, az az, hogy ez pontosabban szimulálja, hogyan indul egy
valós projekt.

Practice Makes Perfect - Gyakorlat teszi a mestert


Ahelyett, hogy csak úgy a farkasok elé vetnénk, nézzünk át néhány különböző módszert, amellyel a
tervezést Episerver-összetevőkre bonthatjuk. Ennek a gyakorlatnak az a lényege, hogy
elgondolkodjon a következőkön néhány valós tervezési megfontolásra. Ne érezze magát
túlterheltnek, ha még nem ért mindent. A cél az, hogy elkezdjen gondolkodni a rugalmas
elrendezések és a és az egyszerű tartalomszerkesztési élmény között. Az alábbi dizájnt véve lássuk,
hogyan építenénk ezt fel az Episerverben.
1. megközelítés: Az Episerver teljes megkerülése. Keményen kódoljon néhány HTML-t egy
szabványos MVC részleges nézeten belül, és hivatkozzon a részleges nézetre a fő MVC elrendezésen
belül.

PROS

• Gyors és könnyen megvalósítható

CONS

• A tartalomszerkesztők nem tudják szerkeszteni vagy frissíteni a hivatkozásokat.


• A tartalom a webhely minden oldalán megjelenik, mivel a HTML keményen kódolt a fő
elrendezésen belül.
• A jövőbeni módosítások elvégzéséhez gyártói kiadásra lesz szükség.

2. megközelítés: Adja hozzá a gombok megjelenítéséhez szükséges összes tulajdonságot egy


Episerver oldal sablonjához. Minden gombhoz három tulajdonságra lesz szükség. Egy képet, egy
linket és a gomb szövegét, tehát tizennyolc tulajdonságok összesen. A CMS-en belül a tulajdonságok
ugyanazon a lapon lesznek megjelenítve.

PROS

• A tartalomszerkesztők a CMS-en keresztül frissíthetik a gombokat.

CONS

• A tulajdonságok ilyen módon történő megkettőzése sérti a DRY elvét.


• Sok hasonló tulajdonság létrehozása több fejlesztési időt vesz igénybe.
• A gombok száma az oldalon fix. Ha a követelmény megváltozna, hogy 6 gombot
jelenítsen meg, akkor egy gyártási kiadásra lenne szükség.

3. megközelítés: Hozzon létre egy helyi blokkot, amely a tartalomszerkesztő által a képek, az URL-
címek és a gombszöveg konfigurálásához szükséges összes tulajdonságot magába foglalja.

Ez a megközelítés hasonló a második megközelítéshez. A tartalomszerkesztő nem észlelne semmilyen


különbséget a CMS-en belül. A háttértár szinte ugyanúgy nézne ki. A fő különbség a kettő között a két
megközelítés között az, hogy a tulajdonságok hol tárolódnak. Ha az összes tulajdonságot egy helyi
blokkba vonjuk ki, az adatok nem kerülnek közvetlenül az oldalra mentésre.

PRO

• A tartalomszerkesztők a CMS-en belül frissíthetik a gombokat


• A tulajdonságok helyi blokkba csoportosítása megkönnyíti az oldal későbbi refaktorálását

CON

• A lokális blokkban található duplikált tulajdonságok sértik a DRY-elvét.


• A tartalomszerkesztők nem tudták maguk eltávolítani a blokkot az oldalról. Ehhez egy
kiadásra lenne szükség

4. megközelítés: Hozzon létre egy megosztott blokkot, amely a link megjelenítéséhez szükséges
összes tulajdonságot magába foglalja. Ezt a blokkot nevezhetnénk olyan fantáziadúsan, mint
'CallToActionBlock'. A 'CallToActionBlock' három tulajdonságot foglalna magába: a képet, a link URL-
jét és a gomb szövegét. Az oldal sablonjához hozzá kellene adni egy tartalmi területet, hogy a
tartalomszerkesztő létrehozhassa és megjeleníthesse a linket gombokat adjon hozzá az oldalhoz.
PRO

• A tartalomszerkesztő szabályozhatja, hogy hány gomb kerüljön az oldalra. Létrehozhat


egy vagy száz gombot.
• Jobb design. A kód nem sérti a DRY elveket.

CON

• Nagyobb esélyt vezet be arra, hogy a tartalomszerkesztő tönkreteszi a dizájnt azzal, hogy
túl sok gombot ad az oldalra. Mi történik, ha a tartalomszerkesztő ezer gombot ad hozzá?
Ez a probléma egyéni érvényesítéssel kezelhető. Az egyéni érvényesítéssel később
foglalkozunk.
• Egy extra blokkot és nézeti modellt kell létrehozni

A fent vázolt megközelítések mindegyike életképes módja az Episerverben való építkezésnek.


Mindegyik technikát láttam már termelésben használni. Egyik megközelítést sem lehet a
következőnek nevezni rossznak. Egyes megközelítések nyilvánvalóan jobban megfelelnek bizonyos
helyzetekben, mint mások. Ebben a helyzetben azt tanácsolnám, hogy hozza létre a cselekvésre hívó
blokkot, és adjon hozzá egy tartalmi területet az oldalhoz.

Ez adja a legtöbb újrafelhasználási lehetőséget. Ezután foglalkozzunk egy kicsit összetettebb dologgal,
egy egész oldallal.

Az oldal tetején kezdődik. Az első két kiemelt mező a címsorok. Mindkét címszót közvetlenül az oldal
sablonjához adnám hozzá tulajdonságként. A tulajdonságok neve 'header' és 'subheader'. Ezek string
tulajdonságként jönnek létre.

A címsorok alatt narancssárgával kiemelve számos közösségi ikon található. A közösségi ikonokat
helyi blokkként hoznám létre, azaz a sablonba keményen kódolt blokkként. A blokkot a 'közösségi
ikonok blokk'. Azért használnék helyi blokkot, mert a közösségi ikonokat az oldal két területén
használják. A blokk használata biztosítja, hogy a linkek és a gombok nem kerülnek szinkronba. Ezáltal
továbbá nem kell kétszer létrehozni ugyanazt a komponenst.
A fő hős banner alatt a design egy rácsszerkezetet határoz meg. A rács három sorból áll. Ezt a
területet a tartalmi terület tulajdonság használatával építeném fel. A tartalmi területet egy
tulajdonságként adnánk hozzá az oldaltípushoz. A tartalmi terület lehetővé teszi a
tartalomszerkesztők számára, hogy különböző blokkokat adjanak hozzá az oldalhoz.

A rácson belüli komponensek kezeléséhez mindegyiket blokkokká alakítanám. Az első sorban két
általános blokkot építenék, amelyek nagyon rugalmasak. A rich-text blokkot és a képblokkot.

A rich-text blokknak egyetlen tulajdonsága lesz, amelynek típusa XHtmlString. Az image blokk
tartalmazhatna egy képválasztót egy asztali képhez, egy képválasztót egy kisebb mobil képhez, és egy
szöveges tulajdonságot az alt címkékhez. Ha azt szeretnénk, hogy a kép egy linket is tartalmazzon,
akkor egy linkválasztót is tartalmazhatna.

Ezeknek a szuperegyszerű általános blokkoknak a létrehozása nagy szabadságot ad a


tartalomszerkesztőnek. Ha engedélyezi a megjelenítési opciókat - amelyekről később lesz szó - egy
frontend grid keretrendszerrel kombinálva, mint például a bootstrap, akkor ezek az egyszerű kép- és
szövegblokkok a tartalomszerkesztőnek sok választási lehetőséget biztosítanak az elrendezés körül.

Ha a rugalmasság fontos tényező a projektben, egy másik blokk-típus, amelynek építését


megfontolhatja, a HTML-blokk. Ahogy a neve is jelzi, a HTML blokk lehetővé tenné a
tartalomszerkesztők számára, hogy hozzáadjanak HTML-t közvetlenül az oldalra. Én általában
kerülöm a HTML-blokk építését, mivel erre általában csak akkor van szükség, ha a backend nem
optimálisan lett megtervezve.

Feltételezve, hogy az Episerver megjelenítési opció funkciója engedélyezve van, akkor a rács első sora
két blokk segítségével hozható létre, mindkettő félszélességű megjelenítésre állítva. Az első blokk a
gazdag szövegű blokk a második a képblokk.

A második és harmadik sorban lévő komponensek már érdekesebbek. A dizájn két nagyon hasonló
kinézetű komponenssel rendelkezik. Ezt többféleképpen is meg lehet építeni.

Az egyik lehetőség a második és harmadik sorban lévő komponenseket egyetlen blokkba, a


"cselekvésre hívó blokkba" kombinálná. A "felhívás a cselekvésre" blokk tartalmazhatna egy gazdag
szövegű területet, egy képválasztót, egy linket, és egy karakterlánc tulajdonságot, amely lehetővé
teszi az egyéni gombszöveget. A blokk kétféleképpen jelenne meg. Az egyik mód a gombbal. A másik
anélkül. Az üzemmódok megkülönböztetéséhez egy boolean jelölőnégyzetet is hozzáadhatnánk a
választási lehetőségek kiválasztásához. A tartalomszerkesztő a CMS-ben a jelölőnégyzet
kiválasztásával/kiválasztásának megszüntetésével tudná megadni, hogy mikor jelenjen meg a gomb.

A szerkesztési élmény némileg jobbá tételéhez hozzáadhatna egy olyan logikát, amely csak akkor
jeleníti meg a gombot, ha a link tulajdonság be van állítva. Az ilyen típusú logikát a vezérlőn belül
adhatja hozzá. Ez a megközelítés azt jelentené, hogy a megjelenítő gomb jelölőnégyzetére már nem
lenne szükség. Mivel a gomb automatikusan elrejtené/megjelenítené a CMS-szerkesztő által
hozzáadott tartalom alapján.

Ez a terület egy példa arra, hogy a tervezés nem illeszkedik szépen az Episerveren belüli megfelelő
hasonló komponenshez. Miért hozzon létre két komponenst, ha elkerülheti őket? Mint egy másik
alternatív módja ennek a komponensnek, két blokkot is létrehozhatna, a "call to action" és a "call to
action with a link" blokkokat. Az egyik blokk tartalmazna egy gombot. A másik anélkül. Egy utolsó
alternatíva a 2. és a 3. sor egyetlen blokkba építése. Ha a két komponensnek mindig együtt kell
megjelenítenie, akkor egyetlen blokkban való egyesítésüknek lehet értelme.
Az utolsó megjegyzendő komponens az alsó. Én ezt egy blokkként építeném fel, amit "banner
blokknak" neveznék. A banner blokk tartalmazna egy képet és egy cím tulajdonságot. Használnám a
"közösségi gombok blokkot" a láblécen belül.

Component Catalog Tips - Komponens katalógus tippek


Sokféleképpen tervezheti ugyanazt az oldalt az Episerverben. Attól függően, hogy hol dolgozik, az
ügyfél, a vállalat és a csapat általában befolyásolja, hogy milyen megközelítést alkalmaz. Episerver, és
azt, hogy hogyan tervezi meg a komponenseket a katalóguson belül.

Dolgoztam például olyan projekteken, ahol az ügyfelek kifejezetten azt kérték, hogy a
tartalomszerkesztők a CMS-en keresztül közvetlenül az oldalra kemény kódolt HTML-t adhassanak
hozzá. Azoknak a vállalatoknak, amelyeknek nincs szükségük nem kell aggódniuk a jogi megfelelés
miatt, ez elfogadható megközelítés lehet. A jogszabályok által jobban korlátozott ágazatokban
működő vállalatok, például a pénzügyek esetében ez a fajta megközelítés a következő problémákat
okozhatja potenciális felelősségi aggályokat okozhat. Az alábbiakban felsorolunk néhány tippet,
amelyeket hasznosnak találhat szem előtt tartani a katalógus létrehozásakor.

Avoid Nesting - Kerülje a fészekrakást


Mint korábban említettük, kerülje a túl sok blokk egymásba ágyazását. Egy, vagy két szintű egymásba
ágyazás elfogadható. Az a kialakítás, amely arra kényszeríti a szerkesztőket, hogy rendszeresen
interakcióba lépjenek a négy vagy öt következő tartalmi területtel szintek mélységében, rossz
szerkesztői élményt fog eredményezni.

Az egymásba ágyazáshoz vezető gyakori forgatókönyvek a következők:

• The template is too generic, the fix would be to create a specific page-specific template
• The page is being built from too many generic blocks, the fix is to create a more specific block
• The use of blocks to render CSS, blocks whose sole purpose is to wrap a <div>, or some CSS
around other blocks can cause deep nesting. The fix would be to use display options, or, look
at alternative ways of passing CSS data into the page
• The use of blocks to render configuration data, same as above
• The use of a shared-block when a local-block or a property on the page would suffice, fix use
a property instead
• Block used for unordered HTML lists, using a block to render an unordered list is not a good
solution, use a listed property instead.

• A sablon túl általános, a megoldás egy speciális oldal-specifikus sablon létrehozása lenne.
• Az oldal túl sok általános blokkból épül fel, a megoldás egy specifikusabb blokk létrehozása.
• A CSS megjelenítésére szolgáló blokkok, az olyan blokkok, amelyek egyetlen célja egy <div>
vagy más blokkok körüli CSS beburkolása, mély beágyazódást okozhatnak. A megoldás a
megjelenítési opciók használata lenne, vagy a CSS-adatok oldalra történő átvitelének
alternatív módjainak vizsgálata.
• A blokkok használata a konfigurációs adatok megjelenítésére, a fentiekkel megegyezően.
• A megosztott blokk használata, amikor egy helyi blokk vagy egy tulajdonság az oldalon
elegendő lenne, rögzítse a tulajdonság használatát helyette.
• A rendezetlen HTML-listákhoz használt blokk, a blokk használata egy rendezetlen lista
megjelenítéséhez nem jó megoldás, használjon helyette egy listázott tulajdonságot.
Nem lenne bölcs dolog blokkok használata nélkül tervezni egy Episerver weboldalt, így a tartalmi
területek bizonyos szintű egymásba ágyazása mindig is létezni fog. Amikor a tartalmi területek
háromnál több szintnél többször kezdenek egymásba ágyazódni mélyen álljon meg, és kérdezze meg,
hogy van-e jobb megközelítés, és tervezze újra a katalógust ennek megfelelően.

The Catch-All Option - A Catch-All opció


Előfordulhat olyan eset is, amikor egy komponenst próbál meghatározni, és nem tudja, hogy melyik
opciót válassza. Ha elakad, azt tanácsolom, hogy válassza a legegyszerűbb opciót, ami eszébe jut.

Később bármikor konfigurálhatóbbá és bonyolultabbá teheti. Ha valaha is nagyon elakadsz valaminek


a felépítésével kapcsolatban, akkor azt javaslom, hogy a problémás területet csomagold be egy
blokkba, és engedd meg, hogy a tartalomszerkesztőknek, hogy a blokkot egy tartalmi területen
keresztül adják hozzá az oldalhoz. Ez adja a legnagyobb rugalmasságot a későbbi változtatáshoz,
mivel könnyen törölhető lesz!

Keep The Homepage Simple - Tartsa a honlapot egyszerűnek


Amikor elkezdesz végigmenni a terveken, előfordulhat, hogy olyan beállításokkal és tulajdonságokkal
találkozol, amelyekkel nem vagy biztos benne, hogy mit kell tenned, és hol kell tárolnod őket. Ezek a
globális beállítások egy gyakori szükségszerűség minden projektben. A globális beállítások közé
tartozhatnak a fejléc vagy a lábléc által megkövetelt tulajdonságok, a funkció-jelzők vagy az egész
webhelyre kiterjedő metaadatok.

A globális beállítások kezelését később tárgyaljuk, de ebben a gyakorlatban próbáljuk meg elkerülni,
hogy olyan tulajdonságokat adjunk hozzá, amelyek nem oda tartoznak. A globális beállítások
kezelésének egyik megközelítése, hogy hozzáadjuk őket a kezdőlap tulajdonságaiként adjuk meg.
Ebben a szakaszban kerüljük el, hogy ebbe a csapdába essünk. Ne adjon hozzá olyan globális
tulajdonságokat a kezdőlaphoz, amelyekre nincs kifejezett szükség. A komponenskatalógus
készítésekor auditálását, javaslom, hogy hozzon létre egy külön beállítási oldalt a "Megosztott"
szakaszon belül. Ha nem teljesen biztos abban, hogy hova tegyen egy beállítást vagy tulajdonságot,
akkor adja hozzá a beállítások szakaszhoz, majd hivatkozzon a következőre a sablonoldalról.

Use Generic Page Types - Általános oldaltípusok használata


Egy általános oldaltípus létrehozása, amely egyetlen tartalmi területet tartalmaz, amelyhez bármilyen
blokk hozzáadható, nagyon hatékony eszköz a tartalomszerkesztők számára. Javaslom, hogy adjon
meg egy ilyen általános oldaltípust minden projektjében. Ha úgy dönt, hogy egy általános sablont is
felvesz a projektjébe, akkor ne felejtse el felvenni a katalógusba.

Use Page-Specific Templates Whenever Security Is concerned - Használjon oldalspecifikus


sablonokat, ha a biztonságról van szó
Oldalain belül, ha biztonsági és/vagy adatvédelmi korlátozásokkal rendelkezik, ne használjon
általános sablont, hanem inkább használjon egy speciális oldalsablont. Bejelentkezési oldalak, tagsági
területek, pénztár oldalak és a fizetési folyamatok feldolgozására szolgáló oldalaknak mind egyedi
sablonoknak kell lenniük. Ha a biztonságról van szó, ne rövidítsen meg semmit. Ne engedje, hogy a
tartalomszerkesztő blokkokból maga építse fel az oldalakat. Például, ha egy bejelentkezési oldalt kell
létrehoznia, akkor ne úgy tervezze meg a rendszert, hogy a tartalomszerkesztő meg tudja azt bontani
a szerkesztőn belüli blokk eltávolításával. Ne kockáztasson a biztonsággal. Ne engedje, hogy a
tartalomszerkesztők véletlenül megtörjék a kulcsfontosságú oldalakat amelyek érzékeny adatokat
tartalmaznak.
Start Template Focused - Start sablon fókuszált
Az Episerverrel újonnan ismerkedő fejlesztők számára jó tanács, hogy inkább sablon-, mint
blokkközpontúak legyenek. Ha ezt a megközelítést alkalmazza, akkor később rugalmasabbá teheti, ha
szüksége van rá. Ha a valaminek blokknak kell lennie, sokkal könnyebb a funkciókat egy sablonból egy
blokkba átdolgozni, mint fordítva. Egy blokk létrehozása extra fejlesztési erőfeszítést igényel. Miért
pazarolni az erőfeszítést, ha nincs rá szükség. Az Episerver azt is megakadályozza, hogy egy blokk-
típust törölni lehessen, amíg annak minden hivatkozása/eseménye el nem tűnik a tartalomfából. Egy
olyan eszköz nélkül, mint a az Episerver Cms Audit plug-in, nehéz lesz megtalálni az összes olyan
oldalt a CMS-en belül, amely hivatkozik rá.

Backlog Time - Hátralékos idő

Mindezen ismeretekkel felvértezve most már képesnek kell lennie arra, hogy elkészítse az első
komponenskatalógus tervezetét. A katalógus kimenete egy csomó oldal és blokk lesz, amelyekre
most szüksége lesz a CMS-en belül kell felépítenie. Ha agilis módszertant követ, akkor ez a lista lehet
a backlog alapja. A katalógusban azonosított minden egyes elem megfeleltethető egy feladatnak vagy
egy epicnek a Jira-ban. Ez a folyamat nem fogja feltárni az összes projektfeladatot, azonban most már
van egy kiindulópontja.

Azt tanácsolom, hogy ne stresszeljen azon, hogy az első alkalommal tökéletes legyen az összetevők
katalógusa. Egy projekt elején szerintem fontosabb, hogy mélyebb megértést szerezzen a projektről,
mint egy egészének megértése, minthogy a tökéletesség megteremtése az elejétől fogva
megakadjon.

HTML integráció
Egy másik szempont, amelyet a projekt kezdetén meg kell vizsgálnia, hogy hogyan fogja kezelni a
HTML integrációt. Hogyan dolgozzanak a front-end fejlesztők a projekten?

Minden Episerver-projekt kezdetén meg kell határoznia azt a folyamatot, amelyet a front-end
fejlesztői csapat követni fog a HTML-íráshoz az Episerverben. Kétféle megközelítés létezik közül
választhat:

Írjon egy önálló statikus HTML-weboldalt, majd másolja a HTML-t az Episerver verzióba. A frontend-
fejlesztők írják meg a HTML-t közvetlenül a .NET nézeteken belül.

Az egyszerűség szempontjából a legegyszerűbb megközelítés az, ha a front-end csapat számára


lehetővé tesszük, hogy a HTML-t, a CSS-t és a JS-t egy statikus weboldalon belül írják meg. A
blokkarchitektúra jellege miatt, egy front-end fejlesztő számára nagyon nehéz feladat lehet annak
megértése, hogy a rendszeren belüli összes komponens hogyan függ össze.

Az egyik később tárgyalandó téma a "Megjelenítési beállítások". Az a lehetőség, hogy a


tartalomszerkesztők a CMS-en belül megadhatják, hogy a blokkok milyen szélességben jelenjenek
meg egy oldalon. Amikor ez a funkció engedélyezve van, a frontend-fejlesztő számára nagyon
megnehezítheti, hogy tudja, hol kell frissítenie a HTML-t, mivel a nézetek több fájlra oszthatók.

Egy másik szempont a költség. Ha azt szeretné, hogy a frontend csapat a CMS-en belül dolgozzon,
akkor a Visual Studiót kell használniuk, ami nem lesz ideális számukra. A licencköltségek tekintetében
ez szintén nem optimális. Az MSDN-előfizetés megvásárlása a vállalat összes frontend-tervezője
számára drága. Egy MSDN-előfizetés körülbelül 2000 font évente. Ha az összes front-end tervezőt,
hogy az Episerverben dolgozzon, akkor már a licencköltségek is gyorsan összeadódhatnak. Ha 5
tervezője van, akkor ez majdnem évi 10 000 font többletköltséget jelent a szoftverlicencekre. Ez
nagyon sok több pénz ahhoz képest, hogy egy szabad szövegszerkesztővel, például a VS-Code-mal
dolgozhassanak. A statikus webhely használatának hátránya, hogy a HTML-t a statikus webhelyről
kell átmásolni az Episerver nézetekbe. Minden egyes alkalommal, amikor a statikus webhelyen belül
HTML-beállításokat hajtunk végre, ez a változás szorgalmasan át kell másolni egy nézetbe az
Episerverben. Ezt a munkafolyamatot követve nagyon könnyen előfordulhatnak másolási hibák.
Mivel a CSS-t is egy kissé eltérő weboldal ellenében írják.

tervezési hibák időről időre előfordulnak. Időt lehet veszíteni azzal, hogy azon tűnődünk, hogy az
oldal az Episerverben miért nem ugyanúgy jelenik meg, mint a statikus webhelyen.

A fent felsorolt két megközelítés egyike sem ideális, azonban ezek a korlátok a HTML hozzáadásakor
az Episerver weboldalhoz. Egy tökéletes világban a statikus webhely teljesen működőképes lenne és
aláírva, mielőtt megkísérelné a HTML integrálását az Episerverben. Ez azonban ritkán lehetséges.

A másik megoldás egy egyoldalas alkalmazás (Single Page App, SPA) létrehozása a React és a
tartalomszolgáltatási API használatával. Az Episerver használata headless architektúrában sokkal
egyszerűbbé teszi a HTML integráció kérdését.

kezelése. Egyáltalán nem lesz szükség HTML-másolásra! Az SPA használata azt jelenti, hogy a HTML-t
nem kell másolni a statikus weboldal és az Episerver weboldal között. Ez sok mindent felszabadít időt
takarít meg, azonban ez egy kompromisszummal jár.

Az SPA használata azt jelenti, hogy sok olyan gyakori Episerver-bővítmény, amelyet csak a
szerveroldali webhelyek támogatására írtak, már nem fog működni. Ez azt jelenti, hogy valószínűleg,
hogy sok extra dolgot kell a semmiből felépítenie, ahelyett, hogy a szerveroldali megközelítés
használatához képest.

Attól, hogy fej nélkülire váltasz, a fű nem feltétlenül zöldebb. A headless megközelítés nem
feltétlenül csökkenti a teljes szükséges munka mennyiségét. Egyszerűen csak áthelyezi a felelősséget,
hogy ki mit csinál. Egy SPA létrehozásakor a frontend csapat nagyobb felelősséggel tartozik majd a
kód megírásáért, az API-kkal való beszélgetésért és az állapotkezeléssel való foglalkozásért.

A HTML-integráció esetén azt javaslom, hogy statikus webhelyet építsen. Építse meg az összes HTML-
t a statikus webhelyen, mielőtt megfontolná annak integrálását a nézetekbe. Ez a leghatékonyabb
munkamódszer. Ne feledje, hogy a projekttervbe számítsa bele ezt az időt, mivel időre lesz szüksége
a HTML integrálásához.

Exercises and Further Reading - Gyakorlatok és további olvasnivalók


Ha gyakorolni szeretné a felosztási készségeit, javaslom, hogy válasszon ki egy tetszőleges weboldalt,
mint például az eBay, Amazon, stb... és egyszerűen próbálja meg kitalálni, hogyan osztaná fel egy
Episerver weboldalra. Amikor én először próbálkoztam ezzel a folyamattal, ezt a témát használtam,
tiszta blog téma. Ez a téma meglehetősen egyszerű, és kevesebb mint fél óra alatt képesnek kell
lennie arra, hogy végigcsörgesse. Az én tippjeim, hogy menjen végig ezen a folyamaton:

• Az összes oldaltípus azonosítása


• Menjen végig minden egyes sablonon, és azonosítsa az összetevőket/blokkokat.
• Azonosítsa a sablon tulajdonságait és tulajdonságtípusait.
• Minden egyes azonosított blokkhoz hozzon létre egy új oldalt a katalógusban, és ismételje
meg az ellenőrzési folyamatot.
• Frissítse a katalóguson belüli lapbejegyzést az újonnan létrehozott blokkoldalakra mutató
linkekkel.
• Adja hozzá az azonosított globális beállításokat egy külön területen

Amikor erre a folyamatra vállalkozik, nincs helyes vagy helytelen válasz, ezért ne izguljon túlságosan.
Ha igazán próbára akarod tenni magad, akkor ismételd meg a folyamatot néhányszor, és állítsd
kihívás elé magad, hogy találjon teljesen más módot a lapok/blokkok felépítésére minden egyes
átfutásnál. Hasonlítsa össze és állítsa szembe a különböző megközelítéseket, hogy jobb betekintést
nyerjen.
Az Episerver telepítése fejlesztési célokra
Ebben a fejezetben megtudhatja, hogyan telepítheti és állíthatja be az Episerver kezdőcsomagot a
számítógépén. Megtanulja, hogyan konfigurálhatja a fejlesztői környezetét, hogy minél produktívabb
legyen a lehető legjobban. A beállítás lényeges eleme kell, hogy legyen, hogy lehetővé tegye a kód
gyors írását és hibakeresését. Egy projekt során a rosszul konfigurált fejlesztőkörnyezet
időveszteséget okoz.

Ha várnia kell a képernyők betöltésére és az összeállítások lefordítására, az megakadályozhatja, hogy


áramlási állapotba kerüljön. Biztosítsuk tehát, hogy a sikerhez van beállítva!

Az Episerver telepítéséhez többféle megközelítést is követhet. A leggyorsabb megközelítés a Visual


Studio bővítmény használata. Ez a bővítmény telepít egy sablont a Visual Studio-n belül, amely
lehetővé teszi a kezdőcsomag telepítését. Nem fogja konfigurálni a számítógépét vagy a starter-kitet,
hogy a lehető legjobb fejlesztési élményt nyújtsa. Ehhez néhány további konfigurációs finomhangolás
szükséges szükséges.

A bővítmény nem telepít, és nem csatol adatbázist egy SQL szerver példányon belül. Ehelyett az
adatbázist egy olyan fájl fogja tárolni, amely a webroot 'App_Data' mappába kerül telepítésre.

Az SQL Server Compact segítségével lehet elérni ezt a fájlt. Egy ilyen módon konfigurált adatbázissal
rendelkező webhely futtatása akkor jó, ha egy egyszerű demo-webhelyet szeretne létrehozni és
futtatni, hogy lássa, mi az Episerver lényege.a Episerver. Ez a megközelítés nem működik, ha a
tökéletes Episerver fejlesztési élményt keresi. Például egy adatbázis fájl mérete több gigabájtra
nőhet, hogyan adjuk hozzá az fájlt a forráskontrolba, hogy biztosítsa a biztonsági mentést? Hogyan
állíthat vissza időben egy adatbázist egy pillanatképes biztonsági mentésből egy esetleges baleset
esetén?

A bővítmény a helyi IIS-példányt sem fogja beállítani és konfigurálni. Ez azt jelenti, hogy
alapértelmezés szerint csak az IIS express segítségével tudja majd futtatni a weboldalt. Ez nem
ideális, mivel azt jelenti, hogy csak akkor férhet hozzá a webhelyhez, ha az IIS express fut. Ez aztán
megakadályozza, hogy ezzel egyidejűleg kódmódosításokat hajtson végre, mivel a Visual Studio
hibakeresési módban lesz. Egy hatékonyabb módja a fejlesztőkörnyezet beállításának, ha a termelési
környezetet tükrözzük. Ezt úgy lehet megtenni, hogy egy webhelyet futtatunk ezen a konfiguráción
belül:

• Az adatbázist az SQL szerveren keresztül érjük el.


• A kapcsolati karakterlánc vegyes hitelesítési módra van állítva a valós kiszolgáló szimulálása
érdekében.
• A webhely az IIS-en belül van elhelyezve
• A webhely eléréséhez egy hostnevet használunk

Ha úgy konfigurálja a fejlesztőkörnyezetét, hogy az tükrözze a termelési konfigurációt, akkor a lehető


legtöbb kódot tudja majd előállítani. Feltéve, hogy rendelkezik ReAttach telepítve van, akkor a
debugger csatolása is gyorsabb.

Ha már volt tapasztalata .NET weboldalak telepítésében, akkor a jó hír az, hogy a fejezetben szereplő
lépések ismerősek lesznek. Az Episerver telepítése során számoljon azzal, hogy néhány akadályokba
ütközik az út során. Egy új Episerver weboldal beállítása általában egyszerű, azonban, akárcsak az
életben, néha váratlan dolgok történnek. A telepítés során előforduló problémák a következők
általában a környezettel kapcsolatosak. Mindegyik csodálatos olvasónak egyedi PC-konfigurációval
rendelkezik. A környezetek az Episerver, a Visual Studio, az IIS, az SQL Server különböző verzióitól
függően változhatnak, és a Windows között. Néhány fejlesztő nagyon korlátozott hálózaton belül fog
dolgozni, más olvasóknak pedig korlátozott felhasználói jogosultságaik lehetnek a PC-jükhöz.

Lehetetlen lenne számomra, hogy minden egyes telepítési hibára kitérjek, amivel találkozhatunk. Ha
a dolgok rosszul mennek, ne essünk pánikba. A fejezet vége a gyakori hibák megoldásának van
szentelve telepítési problémák megoldására, amelyekkel valószínűleg találkozhat. Az ebben a
fejezetben leírt lépésekkel és a leggyakoribb hibák megoldására vonatkozó néhány ötlettel
felvértezve nagyon bízom benne, hogy a webhelyet fel tudja állítani, és működőképes lesz, anélkül,
hogy túl sok fájdalmat okozna.

Előfeltételek
Az Episerver telepítéséhez a következő dolgokra lesz szüksége:

Visual Studio: A kisebb költségvetéssel rendelkezők a Visual Studio közösségi verzióját szerezhetik be.
A nagyobb költségvetéssel rendelkezők töltsék le a professzionális, vagy vállalati kiadást. A Visual
Studio telepítésekor ügyeljünk arra, hogy a .NET keretrendszer minden verzióját engedélyezzük.

SQL Server és SSMS: Ismét a Microsoft oldalára kell menni. A közösségi kiadás rendben van fejlesztési
célokra. Győződjön meg róla, hogy telepíti az SQL Server Management Studiót, más néven SSMS
néven ismert eszköz is.

IIS Enabled: Ezt a Windowson belül, a 'Turn Windows Features Off/On' képernyő segítségével lehet
megtenni. Az IIS telepítésekor javaslom, hogy engedélyezze a beállításokat:

• Application Development:
o ASP .NET
o NET Extensibility
o ASP
o ISAPI Extensions
o ISAPI Filters
o Application Initialization
• Common HTTP Features
o Static Content
o Default Document
o Directory Browsing
o HTTP Errors
o HTTP Redirection
• Performance
o Static Content Compression
o Dynamic Content Compression
o Under the Security
o URL Authorization
• Alkalmazásfejlesztés:
o NET
o NET bővíthetőség
o ASP
o ISAPI-bővítések
o ISAPI szűrők
o Alkalmazás inicializálás
• Közös HTTP-funkciók
o Statikus tartalom
o Alapértelmezett dokumentum
o Könyvtár böngészés
o HTTP hibák
o HTTP átirányítás
• Teljesítmény
o Statikus tartalom tömörítése
o Dinamikus tartalomtömörítés
o A biztonság alatt
o URL-engedélyezés

A ReAttach Visual Studio bővítmény telepítve: A hibakeresés gyorsabbá tétele érdekében javaslom,
hogy töltse le és telepítse a ReAttach-ot. A ReAttach lehetővé teszi a hibakereső gyors csatolását egy
IIS-ben tárolt webhelyhez. A hibakeresés során a W3WP.exe folyamathoz kell csatolni. A Visual
Studio-ban a Debug → Attach Debugger. Jelölje be a 'Show All Process' (Minden folyamat
megjelenítése) jelölőnégyzetet, majd csatolja a 'W3WP.exe'

Az Episerver Nuget Feed hozzáadása a Visual Studióban: Episerver saját Nuget feeddel rendelkezik.
Ezt a feedet hozzá kell adnia az elérhető Nuget források listájához. Ehhez a Visual Studio-ban nyissa
meg a Nuget Settings, 'Tools' -> 'Nuget Package Manager' -> 'Package Manager Settings'. Egy új forrás
hozzáadásához navigáljon a 'Package Sources' (Csomagforrások) menüpontra. Kattintson a '+' ikonra
egy hírfolyam hozzáadásához.

Ezen belül adjon hozzá egy hivatkozást az EpiServer feedre:

http://nuget.episerver.com/feed/packages.svc/

Miután sikeresen hozzáadta az Episerver feedet, képesnek kell lennie az új csomagok böngészésére
és telepítésére. Ha rákeres az 'Episerver' kifejezésre, akkor két csomagot kell találnia a tetején.

Episerver.CMS és Episerver.Core néven. Ezek az Episerver alapcsomagjai, amelyeket telepíteni kell


ahhoz, hogy a CMS működjön.

Ha inkább dev-ops szemléletű vagy, akkor lehetőséged van a feed regisztrálására egy PowerShell
szkript segítségével is. Ha ezt a szkriptet bejelöli a forráskontrolba, akkor más fejlesztők egyszerűen
csak futtatni ahelyett, hogy manuálisan hozzáadnák:
Az Episerver Visual Studio bővítmény telepítve: Az Episerver telepítésének legegyszerűbb módja a
bővítmény használata. A bővítmény egy új típusú Visual Studio projektsablont telepít. Ez a

sablon segítségével új Episerver-weboldalak hozhatók létre a Visual Studióban. A bővítményt a Visual


Studio Marketplace, Episerver CMS Visual Studio Extension című oldaláról telepítheti.

A bővítmény telepítése után egy új, 'Episerver' nevű sablonnak kell léteznie. A Visual Studio-ban
kattintson az 'Új projekt' gombra, majd keresse meg az 'Episerver' szót a helyőrző szöveggel ellátott
keresősávban 'sablon keresése', és meg kell találnia. Használja ezt alapsablonnak egy új projekt
létrehozásához. A sablon ezután végigvezeti Önt a telepítési folyamaton.

Egy fejlesztői licenc: Az Episerver weboldal IIS-en keresztül történő futtatásához szükség van egy
licencre. Érvényes licencfájl nélkül minden alkalommal, amikor megpróbál egy Episerver webhelyet
megtekinteni, egy kis licencelési hibaüzenet jelenik meg varázslatos módon megjelenik az oldal
közepén. Az Episerver ingyenes 30 napos ideiglenes licenceket biztosít a fejlesztők számára. Ezek
közül az egyik licencet használhatja az oldalához.

Ha lustának érzi magát, akkor kísértésbe eshet, hogy figyelmen kívül hagyja a licenchibát, és
egyszerűen együtt éljen vele. Ne tegye ezt. A licenc JavaScript segítségével kerül be az oldalra. Sok-
sok tapasztalatból, ez a Javascript-befecskendezés tönkreteheti az oldaladat. Láttam már mindenféle
furcsa és csodálatos dolgot történni, ami ennek a figyelmeztetésnek az oldalra történő beillesztése
miatt történt. Amikor Ön licenc hibát lát, állítsa le és generáljon egy új licencfájlt. Hosszú távon ezzel
időt takaríthat meg. Több órát pazaroltam el az életemből arra, hogy kitaláljam, miért nem töltődött
be megfelelően egy oldal, hogy végül rájöjjek, hogy az új licenc újratermelésének lustasága volt a
kiváltó ok.

Bárki ingyenesen generálhat fejlesztői licencet. A licenc megszerzéséhez menjen az Episerver License
Centerbe, a https://license.episerver.com címre, és generáljon egyet. Licencet csak akkor tudsz
generálni, ha 30 naponként egy e-mail címre vonatkozóan. Ha Episerver partner vagy, akkor
hozzáférhetsz egy partnerlicenchez, amely sokkal tovább tart, és nem jár le olyan gyorsan. A partneri
licenszhez való hozzáféréshez való hozzáférés megtanulása licencekhez, beszéljen
fiókmenedzserével, vagy írjon e-mailt az Episerver ügyfélszolgálatának.
A normál fejlesztői licenc generálásához vagy a számítógép MAC-címét, vagy az IP-címét kell a
licenchez kötnie. Én inkább a MAC-cím használatát részesítem előnyben, mivel ez nem fog nem
változik. A számítógéped Mac-címének kiderítéséhez nyisd meg a parancssort a start menü 'cmd'
parancsának 'futtatás' beírásával, és a parancssorba írd be a következőt:

A parancs futtatása után a beállítások listája fog felvillanni. Ebből a listából meg kell keresnie az
'Ethernet adapter' vagy hasonló nevű részt. A következő bejegyzést keresi Fizikai cím. A cím egy 12
számjegyű, kötőjellel elválasztott formátumban lesz, másolja ki.

A licenc generálásához lépjen az Episerver fejlesztői portálra. Töltse ki a demo licenc megrendelése
űrlapot. Válassza ki az "Episerver 7"-et, mint a terméket, amelyhez licencet szeretne regisztrálni. A
verzió a legördülő listában évek óta nem frissült! Az űrlap elküldése után azonnal megkapja e-
mailben a License.config nevű fájlt. Adja hozzá ezt a fájlt a webhelye webrootjához. Miután
hozzáadta a licenc hozzáadása után töltse be újra a webhelyet, és a bosszantó felugró ablaknak el kell
tűnnie.

Ha a licencfájl hozzáadása után is hiba jelenik m eg, végezzen egy IIS-visszaállítást. Ha


ez nem javítja a licencfigyelmeztetést, lépjen be a CMS-be, és navigáljon az adminisztrációs részbe.
Kattintson a 'Weboldalak kezelése' menüpontra.

Ezen a képernyőn megkeresheti azt a helyet, ahol az Episerver a licencfájlt várja.


Az Episerver telepítése
A starter-kit telepítéséhez nyissa meg a Visual Studiót, és hozzon létre egy új projektet. A szokásos
MVC/.NET Core projektsablon helyett az Episerver sablont kell használnia. A oldalról.

Visual Studios projektek sablon képernyőjén győződjön meg róla, hogy a 'telepítve' van kiválasztva,
és keressen egy 'Episerver Web Site' nevű sablont. A sablon két telepítési lehetőséggel rendelkezik:

• Üres weboldal - Egy csupasz csontváz, amely minimális kóddal és minimális zajjal
rendelkezik.
• Alloy Sample Site - Teljesen működő weboldal, sok mintakóddal és tartalommal.

Ha először telepíti az Episerver-t, használja az Alloy mintaoldalt. Amikor bármi újat tanulok,
könnyebbnek találom, ha kis lépésekben haladok, mintha túlságosan megterhelő lenne, hogy meg
kell tennem egyszerre több száz dolgot kell csinálnom. Ha megpróbálja az üres sablont egy működő
weboldallá alakítani mindenféle Episerver-tudás nélkül, az nagy kérés lesz, ami sok frusztrációt fog
okozni. Hajlamos vagyok új technológiákat és keretrendszereket a meglévő kódok megtekintésével
megtanulni. Az Alloy mintaoldallal kapcsolatban az a jó, hogy rengeteg előre telepített
funkcionalitással érkezik, amit Ön amiből tanulhatsz. Az Alloy oldalakkal, részoldalakkal, blokkokkal,
vezérlőkkel, megjelenítési lehetőségekkel és egy sor más funkcióval rendelkezik, amelyek
engedélyezve vannak. A telepítő még néhány tartalmat is hozzáad a CMS-hez az Ön számára.

TIPP Ne építse fel a produktív weboldalát az Alloy-ban anélkül, hogy előbb eltávolítaná az összes
feleslegesen felduzzasztott részt!

TIPP Ne építse fel a weboldalt az Alloy rendszeren belül anélkül, hogy először eltávolítaná az összes
feleslegesen felduzzadt elemet!

Az Alloy oldal hátránya, hogy rengeteg olyan kódot tartalmaz, amelyre nem lesz szükséged. Az Alloy
oldal célja az volt, hogy bemutassa az Episervers teljes körű képességeit. Nem úgy terveztük, hogy
gyártásra kész kezdőcsomagnak szánták.

Az évek során számtalan csapatot láttam, akik az Alloy-t használták a produktív weboldaluk
kiindulópontjaként. A legtöbb csapat általában az Alloy-t gyors győzelemként használja, hogy gyorsan
el tudjanak indulni. Ezek a csapatok hajlamosak telepíteni az Alloy-t, törölni az oldalakat és a hozzá
tartozó blokkokat, majd azt gondolják, hogy a munka kész. Ha ezt az utat követi, legyen tisztában
azzal, hogy nem biztos, hogy annyi időt takarít meg, mint gondolja.

Ha az Alloy-t használja egy projekt kiindulópontjaként, akkor valószínűleg a megoldáson belül a


kódnak csak körülbelül 40%-át kell majd használnia. Ez két problémát okoz. Először is, megnő az
esélye annak, hogy hogy a frissítés később meghiúsuljon. A logika e mögött egyszerű. Minél kevesebb
kódsort kell frissíteni, annál nagyobb az esélye annak, hogy a frissítés sikeresen lefut.

Másodszor, a projekt karbantartási ideje megnő, mivel a megoldás sok olyan kódot tartalmaz majd,
amelyet nem ért, és amelyet szintén Önnek kell karbantartania. Az "Episerver varázslat" egy gyakori
kifejezés, amelyet olyan csapatok használnak, amelyek nem tudják leírni, hogy valami miért viselkedik
egy Episerver weboldalon belül egy bizonyos módon. Ha megérti az Alloy-hoz tartozó minden egyes
fájl célját, akkor időbe telik.

Az indulással való rohanásban a legtöbb csapat nem szán időt arra, hogy megtanulja az Alloy minden
csínját-bínját. Ez azt jelenti, hogy sok projekt olyan kódot tartalmaz, amelyet a csapatban senki sem
ért teljesen. Amikor a "Episerver varázslat" történik, megnő a hibaelhárítás időigénye. Egy bizonyos
ponton szükség lesz egy projekt tavaszi nagytakarításra, hogy csökkentsük a "varázslat" mennyiségét.

A tesztelés jól ismert törvénye, hogy minél hamarabb találunk egy hibát az életciklusban, annál
olcsóbb a javítás. Ugyanez vonatkozik a karbantartásra is. Nem fordítunk időt az Alloy starter kit kit
kitakarítására mielőtt elkezdenénk egy projektet, általában hamis pozitív eredményt hoz. Lehet, hogy
hamarabb beindul és működőképes lesz. Minél tovább hagyja a refaktorálást, akkor annál tovább tart
majd később a tisztítás. Amikor kiszámítja a a nem szükséges kód frissítésére, refaktorálására és
hibakeresésre elvesztegetett időt, akkor ez a technikai adósság általában nem éri meg.

Amikor egy új termelési projektbe kezd, azt javaslom, hogy kezdje az üres sablonnal. Először a
kezdőlap működésének elérésére összpontosítson. Csak akkor adjon hozzá kódot, ha szükség van rá.
Ezt követően megközelítés biztosítja, hogy a webhely ne tartalmazzon olyan kódot, amelyet nem ért,
és amelyre nincs szüksége. Emellett sokkal többet fog tanulni.

Az IIS konfigurálása
A telepítőprogram befejezése után az első feladata az lesz, hogy ellenőrizze, minden megfelelően
települt-e. Ezt úgy teheti meg, hogy megnyomja az 'F5' billentyűt, és elindítja a webhelyet a Visual
Studio-ban. Ha az üres projektet telepítette, akkor a webhely betöltésekor egy 404-es oldalt kell
látnia. Ha telepítette az Alloy-t, akkor egy kezdőlapot kell látnia némi tartalommal. Hogy
megbizonyosodjon arról, hogy be tud lépni a CMS-be, egyszerűen adja hozzá a '/episerver' szót az
URL végéhez, és máris megjelenik az Episerver bejelentkezési oldala, például:

Ha megjelenik az Episerver bejelentkezési képernyő, akkor helyesen lett telepítve. Az Episerver


szerkesztőbe való bejelentkezéshez ugyanazt a Windows-fiókot használhatja, amellyel a
számítógépére is bejelentkezett. Annak ellenőrzéséhez, hogy az aktuális felhasználóneve, írja be a
következőt egy parancssorba:

A Windows-fiókjának két fontos funkciót kell engedélyeznie. A PC rendszergazdájának kell lennie.


Jelszóval kell rendelkeznie. Ha munkahelyi számítógépet használ, akkor ez valószínűleg nem fog nem
lesz probléma. Ha otthoni számítógépét használja, és a gondolat, hogy minden egyes bekapcsoláskor
jelszóval kell belépnie a laptopjába, túl nagy gondnak tűnik, akkor létrehozhat egy új helyi Windows-
felhasználót. A felhasználók létrehozásához és szerkesztéséhez a Windowson belül a "Felhasználói
fiókok kezelése" oldalt használhatja.

MEGJEGYZÉS Előfordulhat, hogy ki kell jelentkeznie a Windowsból, majd újra be kell jelentkeznie,
mielőtt a Windows felhasználói módosításokkal hozzáférhet az Episerverhez.
Ha valamilyen okból kifolyólag még mindig nehezen tud bejelentkezni a CMS-be, akkor egy gyors
megoldás, ha létrehoz egy admin felhasználót a kódban. Így garantálhatja, hogy a felhasználó/jelszó
érvényes. A címre ehhez hozzon létre egy fájlt a webrootban, és nevezze el 'NewUser.aspx'-nek. Adja
hozzá ezt a kódot:

<%@ Page Language="C#" AutoEventWireup="true" %>


<%
try
{
Roles.CreateRole("Administrators");
}
catch (Exception) { }
try
{
var user = Membership.CreateUser(
"episerver",
"episerver",
"episerver@episerver.com");
user.IsApproved = true;
}
catch (Exception) {}
try
{
Roles.AddUserToRole(
"episerver",
"Administrators");
}
catch (Exception) {}
%>

Töltse újra a webhelyet, és nyissa meg az oldalt egy böngészőben. Most már egy "episerver" nevű
felhasználónak kell elérhetőnek lennie, amelynek jelszava "episerver".

IIS beállítása: A webhely IIS Express használatával történő elérése rendben van egyszeri
hibakereséshez vagy annak megállapításához, hogy a webhely helyesen van-e telepítve. Nem ez a
leghatékonyabb módja a webhelyen való napi szintű munkának.

Ha a Visual Studio nem fut, akkor a webhely nem lesz elérhető a böngészéshez. Jobb stratégia, ha az
IIS-en keresztül érjük el a webhelyet. Ez azt jelenti, hogy mindig böngészni tudja a webhelyet. Ezek a
időmegtakarítási taktikák valóban összeadódnak. A webhely IIS-en belüli telepítésének lépései a
következők:

• Create a new website within IIS


• Point the website to the folder that contains the web files
• Configure a hostname
• Ensure the web folder has the correct Windows permissions
• Ensure that the app pool user has the correct permissions
• Új webhely létrehozása az IIS-en belül
• Mutasson a weboldalra a webes fájlokat tartalmazó mappára.
• Konfiguráljon egy hostnevet
• Győződjön meg arról, hogy a webmappa rendelkezik a megfelelő Windows-engedélyekkel.
• Győződjön meg arról, hogy az alkalmazáskészlet felhasználója rendelkezik a megfelelő
jogosultságokkal.

Az IIS-t a Windows tálcáján található keresőbe beírva az 'IIS' szót nyithatja meg. Az IIS-en belül
kattintson a jobb gombbal a gyökércsomópontra, és válassza a 'Weboldal hozzáadása' lehetőséget.
Adjon meg egy nevet a webhelynek. Állítsa be a mappa helyét a webhely mappáját a webes fájlokat
tartalmazó mappára állítsa be. A webhely IIS-en keresztül történő eléréséhez be kell állítania és
engedélyeznie kell egy hostnevet. A hosztnév értéke tetszőleges lehet. Én általában a formátumhoz
ragaszkodom:

Mielőtt a hostnév feloldódna, regisztrálnia kell a számítógépén lévő hostfájlban. A host fájlt
bármilyen szövegszerkesztővel módosíthatja. Az egyetlen kikötés, hogy a következő programot kell
futtatnia alkalmazást rendszergazdai jogosultságokkal kell futtatnia. Adminisztrátori jogosultságok
nélkül a Windows megakadályozza, hogy a szerkesztő elmentse a fájlt. A host fájl itt található:

Ahhoz, hogy a 'jondjones.local' hostnevet az IIS feloldásához hozzárendeljük, a host-fájl alján ezt a
bejegyzést kell hozzáadni:

A host-fájl sikeres frissítése után. Próbálja meg betölteni a weboldalt a hostnevet beírva egy
böngészőben, és nézze meg, mi történik. Ha mindent helyesen konfigurált, akkor a a kérésnek az új
weboldalra kell irányulnia. Ha .NET hibát lát, akkor tudja, hogy a hostnév működik. Ehhez a lépéshez
csak győződjön meg róla, hogy az IIS a megfelelő mappába oldja fel a feladatot. A következő lépésben
ezt a hibát fogjuk kijavítani.

Ha furcsa hibát tapasztal, amikor megpróbálja elérni a webhelyet, és nem biztos benne, hogy a
hostnév helyesen oldódik-e fel, akkor elvégezheti ezt a tesztet. Először próbálja meg elérni a
webhelyet egy böngészőben. Következő, lépjen be az IIS-be, és kapcsolja ki a webhelyet. Végül
próbálja meg újra elérni a webhelyet egy böngészőben. Ha a hosztnév helyesen van beállítva, akkor a
hibaüzenetnek meg kell változnia. Ha a hostnév nem működik, ellenőrizze a hostfájlt és a webhelyek
kötését az IIS-en belül, amíg nem működik.

Setting Up SQL Server

Episerver Licensing
A Simple Episerver Architecture, and Best Practice Playbook - Egy
egyszerű Episerver architektúra és a legjobb gyakorlatok kézikönyve
Mielőtt bármilyen egyéni kód írásához hozzákezdene, először is meg kell beszélnünk, hogyan fogja
strukturálni az osztálykönyvtárakat és mappákat a megoldáson belül. Az évek során sok időt
töltöttem azzal, hogy megnéztem a különböző kódbázisokat, megjegyezve olyan dolgokat, mint a
mappaszerkezetek és a névadási konvenciók. Ez a szakasz az általam tapasztalt legjobb elnevezési
gyakorlatokat tartalmazza.

Class Libraries Patterns - Osztálykönyvtárak mintái


A legtöbb fejlesztő hajlamos keveset gondolkodni azon, hogy milyen módon tárolja optimálisan a
fájlokat egy megoldáson belül. A projekt indításának rohanásában nem ritka, hogy az összes kódot
egyetlen "üzleti" mappába kerül a webes alkalmazáson belül. Ha megnézi az Alloy mintaoldalt,
láthatja, honnan indult ez a minta.

A projekt kezdetén az összes kód hozzáadása a fő webalkalmazáson belül a leggyorsabb módja a


kezdésnek. Ez lehet a gyors megoldás, de nem a legjobb. A jövőben, ha szüksége van frissíteni kell a
CMS-t, vagy egy további osztály-könyvtárból kell hozzáférnie a kódjához, akkor számtalan órát tölthet
a kód refaktorálásával, csak azért, hogy valami működjön.

Képzeljük el, hogy van egy 'SongsRadar' nevű osztályunk, amely egy adatbázisból származó dalok
listáját jeleníti meg egy weboldalon. A 'SongsRadar' osztály a webes alkalmazáson belül található. Egy
nap a vezérigazgató azt mondja, hogy szeretné, ha egy másik alkalmazásban is hozzáférhetne ehhez a
dallistához. A kód duplikálása helyett úgy dönt, hogy a kódot egy osztálykönyvtárba helyezi át, hogy
megosztható legyen. A refaktorálás érdekében a kódot, úgy dönt, hogy a 'SongsRadar' kódot
áthelyezi az újonnan létrehozott osztálykönyvtárba. A 'SongsRadar' osztályba számos függőséget
injektáltak a konstruktorán keresztül. Mindezek a függőségek szintén a webes alkalmazásban is
megtalálhatóak.

A 'SongsRadar' refaktorálásához az összes függőségét át kell helyezni a webes alkalmazásból az


osztálykönyvtárba. Ezeknek az alfüggőségeknek is megvannak a saját függőségeik. Ez azt
eredményezi, hogy megismételni a folyamatot, és több kódot refaktorálni. Ez a refaktorálás
folyamatosan ismétlődik, amíg az összes kód ki nem kerül a webes projektből az osztálykönyvtárba.
Ezt a folyamatot a többször is elvégeztem. Napokig is eltarthat, amíg minden újra működik. Ezért is
vagyok annyira híve annak, hogy az összes kódot ne magában a webes alkalmazásban adjuk hozzá.

Azok a csapatok, akik ellenzik a kódnak a webalkalmazási projekten kívüli áthelyezését, általában
puristák. Az összes kódnak a webalkalmazási projekten belül tartását az indokolja, hogy a dolgok
egyszerűek maradjanak.

Apró webhelyek esetében ennek a megközelítésnek lehet értelme. Nagyobb projektek esetében nem
annyira. Van egy jól ismert mondás: ha nem tervezünk, akkor a kudarcot tervezzük. Minden
weboldal-projektre vonatkozóan az a garancia, hogy hogy a dolgok idővel változni fognak. A
megoldás hosszú távú növekedésre és sikerre való beállítása a kezdetektől fogva jól befektetett idő.
Ha az összes egyéni kódot egy osztálykönyvtárba helyezi, az segít ennek biztosításában.

Ha bizonytalan vagy, hogy ezt megtedd-e, akkor egy jó tanács a feltörekvő műszaki építészek
számára, hogy ha két lehetőséggel szembesülsz, válaszd azt, amelyik a jövőre nézve is biztos. Jobb azt
a lehetőséget választani, amelyik pénzt takarít meg a vállalatnak, és hosszú távon javítja a szállítási
időt. Ha a vállalatnak kell állnia a számlát, hogy egy fejlesztő egy hetet töltsön a megoldás későbbi
refaktorálásával, akkor a kudarcot vallott.

How To Structure Class Libraries - Hogyan strukturáljuk az osztálykönyvtárakat


Számos különböző architektúrális megközelítés létezik annak eldöntéséhez, hogy hogyan strukturálja
a megoldások projektjeit. A Bob bácsi által írt Clean Architecture számos tervezési mintát tartalmaz,
amelyekkel figyelembe vehet. Az egyik megközelítés a Common Closure Principle (CCP) követése
lenne. A CCP megközelítésben az osztálykönyvtárakat a projektben a változtatás oka alapján osztja
fel.

Egy Episerver weboldalon belül az osztálykönyvtárakat a különböző típusú felhasználók szerint


oszthatná fel. Ez a következőképpen lehetne felosztani:

• root
o Customers
o Members
o ContentEditors
o Administrators

Ez a felépítés meglehetősen radikális ahhoz képest, ahogyan a legtöbb CMS-projekt felépítése


történik. Egy CMS-projektben az összes módosítási kérelem valószínűleg egy területhez kapcsolódik.
Ennek a mintának az elfogadása és az osztályok csoportosítása könyvtárak csoportosítása aszerint,
hogy miért változhat, segíthet a kiadási folyamat egyszerűsítésében.

Ha a CCP nem felel meg Önnek. Egy hagyományosabb módja az osztálykönyvtárak kialakításának a
cél szerint. Amikor ezt az imperatívabb stílust követem, akkor hajlamos vagyok a könyvtáraimat így
felosztani:
root/
| |- DatabaseSetup
|- ClientName.Core
|- ClientName.Core.Tests
|- ClientName.Data
|- ClientName.IntegrationTests
|- ClientName.Import
|- ClientName.Interfaces
|- Agency.Shared / Core
|- ClientName.Website

Az egyes könyvtárak szándéka és célja remélhetőleg elég intuitív.

DatabaseSetup: adatbázis biztonsági mentési fájlok, szakító/szakító szkriptek élnek itt.

Core: ide kerül a projekthez kapcsolódó egyéni kódok nagy része.

Egy ügynökségnél megeshet, hogy a könyvtárakat tovább osztja egy "Client.Core" könyvtárra a
projekttel kapcsolatos kódok és a projektek között újrafelhasználásra kerülő kódok számára. Nem
vagyok híve annak, hogy egy osztály könyvtárnak, amely több száz olyan funkciót tartalmaz, amelyek
a régebbi projektekben hasznosak lehettek volna, de az aktuális projektben csak néhány módszert
használnak.
Tapasztalatom szerint, ha közvetlenül olyan kódot másolsz egy megoldásba, amelyet soha nem fogsz
használni, akkor a végén csak időt pazarolsz. Értelmetlen olyan kódot karbantartani, amelyet soha
nem használnak.

Core.Tests: A core könyvtár egységtesztjei ide kerülnek

Data: Minden kód, amely bármilyen harmadik féltől származó adathozzáféréshez kapcsolódik, akár
SQL, akár NoSQL, akár külső API ide kerül. Ha egy teljes körű API rétegre van szüksége, akkor egyetlen
osztálykönyvtár nem lesz elegendő.

Egyszerű igények esetén ez is megteszi.

Import: minden olyan kódhoz, amely a tartalom migrációjához, fordításokhoz vagy ütemezett
feladatokhoz kapcsolódik.

Integrációs tesztek: manapság a Cypress.js segítségével írt tesztek. Ez a könyvtár általában tartalmaz
egy Cypress projektet.

Interfészek: A Core és Data könyvtárak által használt összes interfészt egy külön osztálykönyvtárba
teszem. Elsőre furcsának tűnhet ez a megközelítés, de van egy előnye.

Weboldal: Ez az a projekt, amelybe az Episerver szerver telepítője beépül.

Folder Structure Patterns - Mappaszerkezeti minták


Ha CSS-t vagy SASS-t írsz, akkor ismerheted a 7 az 1-ben architektúra mintát. A 7 az 1-ben minta egy
olyan irányelv, amely meghatározza a SASS projekt mappaszerkezetét és azt, hogy a fájlok kell
elhelyezni. A 7 az 1-ben minta követése azt jelenti, hogy egy fejlesztő felvehet egy SASS projektet, és
intuitív módon tudja, hogy hol találhatók a fájlok. Amikor egy Episerver-projekten dolgozik, akkor
ugyanígy kell eljárni. Az Episerver-projekten belüli mappák strukturálását illetően még nem találtam
senkit, aki szabványosított Episerver mappastruktúrát javasolt volna. Az alábbiakban felvázoljuk a
mappakonvenciót, amelyet általában követek:

ClientName.Core/
| |- Blocks / # Block definitions
|- Controllers/
| |- Pages/
| |- Blocks/
| |- Base/
| |- Partials/
| |- MVC/
|- Dependencies/ # Code related to IoC set-up
|- Episerver/
| |- Attributes/ # Custom Episerver attributes that can be applied to pages/blocks
| |- Content Area Renderers/ # Custom content area-specific code goes here
| |- EditorDescriptors / # Custom Episerver property styles
| |- Filters/ # Custom code for things like Authorization Filter
| |- Media/ # Media definitions, needed to allow content editors to use images and pdf file extensions
| |- ImageFile.cs
| |- PdfFile.cs
| |- PropertyList/ # Property-list definitions
| |- SelectionFactories/ # Episerver drop-downs
|- Extension/ # Any extension methods you may need
|- Helpers/ # Misc utility helpers
|- Pages/ # Page definition classes
|- Resources/ # Global constants
|- Services/ # custom code to get data you need
|- StartUp/
| |- RouteConfig.cs
| |- CustomViewEngines.cs
| |- Startup.cs
| |- WebApiConfig.cs
|- ViewModels/
| |- Pages/
| |- Blocks/
| |- Base/
| |- MVC/

Greenfield telepítési problémák

Minden weboldal, amellyel dolgozik, más és más lesz. Nem számít, hogy új az Episerver, vagy már
évek óta használja, néha nehézséget jelenthet egy webhely üzembe helyezése. Ez a

szakasz remélhetőleg segít a hibakeresésben és a felmerülő telepítési problémák


diagnosztizálásában.

Hálózattal kapcsolatos vagy példányspecifikus hiba lépett fel az SQL Serverrel való kapcsolat
létrehozása során. A kiszolgálót nem találták, vagy nem volt elérhető

A hálózattal kapcsolatos kivétel azt jelenti, hogy az adatbázis konfigurációja rossz. Gyakori okok: vagy
elírás a weboldal csatlakozási karakterláncában, vagy az SQL-kiszolgáló konfigurációja rossz. A címre a
hibaelhárításhoz először is győződjön meg arról, hogy a csatlakozási karakterláncon belül kézzel is
tudja használni azokat az adatokat, amelyekkel az SQL-hez próbál csatlakozni. Próbáljon meg
bejelentkezni az SQL-kezelőbe az SQL-hitelesítés használatával manuálisan. Gyakori hibák a
következők:

• Az SQL-fiók engedélyezve van


• A helyes jelszót használja
• Az SQL-fiók az adatbázis tulajdonosa
• A vegyes módú hitelesítés engedélyezve van.

No Homepage - Nincs honlap


Ha a kezdőlap nem töltődik be, akkor valószínűleg a következő problémák valamelyike áll fenn:

• A hosztnév nincs konfigurálva, vagy rosszul van beállítva. Győződjön meg róla, hogy a
hosztnév le van képezve a webhelydefiníciókban.
• Többnyelvű webhely esetén győződjön meg arról, hogy a megfelelő kultúra van definiálva a
webhelyen.
• A site-definíciókban nincs start-oldal definiálva. A site-definíciókban ellenőrizze, hogy a
helyes kezdőoldal van-e beállítva.

Ha a site-definíció helyesnek tűnik, de a site mégsem működik, törölje és hozza létre újra a site-
definíciót. Egy nemrégiben végzett projektnél a site-definíció helyesnek tűnt, de a definíció törlése
kiürített egy gyorsítótárazási problémát. Végül, ha a webhely még mindig nem működik, és kifogyott
az ötletekből, akkor íme néhány további ötlet:
• Hozzon létre egy index.html nevű statikus HTML-fájlt a webgyökérben. El tudja érni egy
böngészőn keresztül? Ha nem, akkor ez egy IIS-probléma.
• Ellenőrizze a Windows eseménynaplóját, tartalmaz-e releváns problémákat?
• Vannak-e hibák az Episerver naplóban, ezek az "App_data" mappában találhatók.
• El tudja érni a szerkesztőt, vagy a webhely egy másik oldalát? Ha egy másik oldalhoz is
hozzáfér, akkor a honlap sablonjával van probléma.
• Létezik az 'App_data' könyvtár?
• A Chrome konzol vagy a hálózati lap mutat hibát?
• Van érvényes Episerver licenc? Ez nem fogja megtörni az oldalt, de megtörheti a JS-t az
oldalon.

Legacy Installation Errors - Legacy telepítési hibák


Ha megkérdeznénk a legtöbb fejlesztőt, hogy milyen típusú projekten szeretne dolgozni,
feltételezném, hogy a legtöbben azt mondanák, hogy egy zöldmezős projekt. Az élet nem mindig
engedi meg, hogy új projekteken dolgozzunk projekteken dolgozni. A munka nagy része egy már
meglévő weboldalon lesz. Egy meglévő weboldal helyi telepítése egyszerű lehet. Sajnos sok örökölt
projekt telepítése rémálom lehet. Az egyik meghatározó tényezője annak, hogy mennyire lesz
egyszerű az élet, a telepítési útmutató. A részletes utasítások segítségével a csapat számtalan órát
takaríthat meg, amikor egy új csapattagnak kell beállítania egy projektet.

Ha egy zöldmezős projekten dolgozik, készítsen jó projektbeállítási utasításokat. Ha egy régi


projekten dolgozik, akkor ne felejtse el frissíteni a hiányzó lépéseket, amelyekkel találkozik a meglévő
útmutatókban. Egy jó beállítási útmutató mindent elmond, amit egy webhely telepítéséhez és
üzembe helyezéséhez meg kell tennie. A beállítási útmutatókat a readme.md fájlban kell megírni, a
megoldáson belül kell létrehozni, és ellenőrizni kell a forráskód-ellenőrzésben.

Egy örökölt projekt beállítása beállítási útmutató nélkül a legrosszabb forgatókönyv. Egy bonyolult
webhely és beállítási útmutató nélkül nagyon frusztráló és időigényes megoldás lehet. Az
alábbiakban felsorolunk egy néhány tippet, ha ilyen helyzetben találja magát.

404-es hibák letiltása: Ha a webhely elérésekor 404-es oldallal vagy barátságos hibaüzenettel
találkozik, akkor azt le kell tiltania. A web.config-on belül először biztosítsa, hogy az egyéni hibák
szakaszban a csomópontot "off"-ra állítsa be, például így:

<customErrors mode="Off">
<error statusCode="404" redirect="/page-not-found/" />
</customErrors>

Másodszor, törölje teljesen azhttpErrors szakaszt:


<httpErrors existingResponse="Auto" errorMode="DetailedLocalOnly">
<remove statusCode="404" subStatusCode="-1" />
</httpErrors>

Most már látnia kell a stack trace kivételüzenet teljes szépségét. Ez remélhetőleg jobb irányba mutat.

Oldaldefiníciók frissítése: Az első alkalommal, amikor egy meglévő adatbázissal rendelkező örökölt
projektet telepít, a webhelydefiníció hibás lesz. Jelentkezzen be a CMS-be, és győződjön meg róla,
hogy a helyi hosztnév hozzá van adva.
Ellenőrizze a naplókat: Az App_data mappában található. Ellenőrizze, hogy naplóznak-e valamit. Ha
nem keletkeznek naplók, akkor az Episerver melyik verziójától függően próbálja megnyitni a
'EpiServerLog.config' fájlt, és ellenőrizze a 'fileLogAppender' részt. Ha a naplók nem tartalmaznak
hasznos információkat, érdemes a naplózási szintet 'warning' üzemmódról 'info' üzemmódra
változtatni. Ez a ismét az 'EPiServerLog.config' fájlban történik.

Ellenőrizze a hiányzó összeállításokat: a régi projektek gyakran támaszkodhatnak olyan


függőségekre, amelyek nem a Nugetből vannak behúzva. Egyetlen hiányzó függőség az egész
webhely hibáját okozhatja. A Visual Studióban ellenőrizze az egyes könyvtárak hivatkozásait, hogy
biztosítsa, hogy egyik sem hiányzik. A hiányzó hivatkozást egy kis sárga figyelmeztető ikonnal lehet
azonosítani bármi előtt.

Ha olyan hiányzó összeállításokat talál, amelyek nincsenek ellenőrizve a forrásellenőrzésben, akkor


erősen ajánlom, hogy hozzon létre egy "Libs" mappát valahol a megoldáson belül, és adja hozzá őket
saját maga. A hiányzó összeállítások hozzáadása legendává teszi Önt, mivel más szerencsétlen
léleknek nem kell még egyszer ugyanezzel a fájdalommal megküzdenie!

Hiányzó egyéni adatbázisok: Ha hálózattal kapcsolatos hibát lát, nézze meg a 'web.config'
állományban a kapcsolati karakterlánc beállításait. Az Episerver kapcsolati karakterlánc neve
'EpiserverDB'. Ha más kapcsolódási karakterláncot észlel, akkor lehetséges, hogy valaki elfelejtett
megadni egy olyan egyéni adatbázist, amelyre a webhely támaszkodik. Ennek kijavításához
jelentkezzen be a gyártó SQL-kiszolgálóra és készítsen másolatot a kapcsolati karakterlánc-
beállításokban felsorolt adatbázisokról. Helyi visszaállításukkal a hibát meg kell oldani.

Hiányzik a Blob tároló: Az Episerver a CMS-be feltöltött összes eszközt, képet és médiát a blob
tárolóba tárolja. Ha a webhely nem képes betölteni a képeket, JS-t stb., akkor ellenőrizze, hogy a blob
tárolás helyesen van-e beállítva.

Hiányzó VPP mappák: A VPP rendszer az Episerver CMS 7.5-ben elavulttá vált, azonban a régi
Episerver oldalak még mindig léteznek. Ha hiányzik egy VPP mappa, akkor a webhelye összeomlik.

A hiba kijavításához szerezzen egy másolatot a VPP mappáról a termelő webhelyről, majd másolja azt
a megfelelő mappa helyére helyileg. A helyes hely az AppData tulajdonságban található, a
EPiServerFramework.config konfigurációs fájlban található.

Végső gondolat
Nem létezik mindenre egyforma tanács arra, hogy minden egyes örökölt webhelyet működőképessé
tegyen. Minden weboldal egy egyedi mérnöki műalkotás. Olyan, amelynek megvannak a maga
furcsaságai. Hacking away until amíg egy webhelyet működésre nem bír, az egy érvényes technika, de
megfoszthatjuk magunkat néhány jó tanulságtól. Minél több időt fordít a webhely és a hibák
megértésére, annál több ötletet kaphat generálhatsz, hogy megpróbáld kijavítani őket.
Shared Database Vs Local Database - Megosztott adatbázis kontra helyi adatbázis
Az Episerver adatbázis helyi beállításának ismerete fontos, azonban ez csak a csata egyik fele. Azt is
figyelembe kell vennie, hogy mi a legoptimálisabb módja a csapat munkájának? Az egyik CMS-projekt
elindításának egyik fő mozzanata annak eldöntése, hogy hogyan szinkronizálhatók a CMS módosításai
a csapattagok között. Minden CMS-adatot egy adatbázisban tárolnak. Hogyan kezelje tehát az
adatbázis módosításait a különböző környezetek között?

Ha több fejlesztőnek kell dolgoznia egy projekten, két bevett adatbázis-stratégia közül választhat:

• Megosztott adatbázis
• Helyi adatbázis

Minden csapattagnak a saját helyi adatbázisából kell dolgoznia, vagy az egész csapat egy közös
adatbázishoz csatlakozik? Azt, hogy hogyan válaszol erre a kérdésre, két tényező befolyásolja.

• Hogyan szinkronizáljuk a tartalomtípus-változásokat


• Hogyan szinkronizáljuk a tartalmi módosításokat.

Beszéljük meg részletesen ezeket a tényezőket.

A Content-Type változások szinkronizálása


Tapasztalataim szerint a helyi adatbázis használata a fejlesztéshez általában megkönnyíti az életet,
amikor új oldalakat és blokkokat hoz létre. Az emberek helyben dolgozhatnak a saját jegyeiken
anélkül, hogy anélkül, hogy aggódniuk kellene bárki más miatt.

Helyi adatbázis konfigurációja Ebben a beállításban:

1. Minden fejlesztőnek saját helyi adatbázisa van, ideális esetben a saját gépén.

2. A fejlesztő minden változtatást helyben végez.

3. Amikor a módosítások készen állnak az integrálásra, a kódot átadják a forráskód-


ellenőrzésbe.

4. Egy másik fejlesztő átveszi a változtatásokat a forráskontrolból, és lefordítja a kódot.

5. Az Episerver az alkalmazás indításakor szinkronizálja a tartalomtípusokat a második


fejlesztő helyi adatbázisában.

Ez a folyamat kikényszeríti a jó gyakorlatokat. A csapatban mindenkinek használnia kell a


forráskontrolt, és a változások könnyen nyomon követhetők.

Közös adatbázis-konfiguráció Ezt a megközelítést követve a csapat mindannyian egy olyan


adatbázishoz csatlakoznak, amelyet egy közös szerveren tárolnak, és amelyhez minden fejlesztő
csatlakozhat.

A megosztott adatbázis-konfigurációban figyelembe kell vennie, hogy a fejlesztők hogyan fognak


hozzáférni ehhez a szerverhez? VPN-en keresztül kell majd csatlakozniuk? Otthonról is tudnak majd
dolgozni a projekten?
A konfigurációkezelés egyszerűbb az ilyen típusú beállításoknál. Minden csapattag ugyanazokat a
kapcsolati karakterláncadatokat fogja használni. Ez azt jelenti, hogy nem kell aggódnia amiatt, hogy a
fejlesztők felülbírálják a egymás beállításait, amikor a web.config-ot a forráskontrolba helyezik.

Az ok, amiért sok csapat ezt a megközelítést antimintának tekinti, az elérhetőség. Ha a megosztott
adatbázis megsérül, vagy a kiszolgáló elérhetetlenné válik, akkor az egész csapat blokkolva lesz a
fejlesztésben.

A helyi adatbázisú felállásban nem kell aggódni a csapat leállása miatt, a csapattagok önállóan
dolgozhatnak. Ha csak a tartalomtípusok szinkronizálását kellene figyelembe vennünk, akkor a helyi
adatbázis felállítása egyértelműen a nyerő megközelítés. A projektmunka sajnos nem ilyen egyszerű.
A tartalmi módosításokat is szinkronizálni kell.

Content Amends - Tartalom Módosítások


Amikor új weboldalt épít, az új oldalsablonok és blokksablonok létrehozása mellett gyakran kell
létrehoznia a megfelelő tartalmat a CMS-en belül. Ez a tartalom más fejlesztők számára is
elérhetőnek kell lennie, hogy megtekinthessék és tesztelhessék. Ez problémát jelent, mivel a
tartalomszinkronizálást az Episerver nem kezeli.

Számos tényező befolyásolhatja a választott tartalomszinkronizálási stratégiát. E tényezők


bemutatásához sétáljunk végig egy nagyon kontrasztos felhasználási eseten.

Képzeljük el, hogy két fejlesztő, Dave és Tarquin egy projekten dolgozik. Dave-et néhány blogfunkció
létrehozásával bízták meg. Tarquint pedig arra kérték, hogy készítsen egy terméklistázó oldalt a
webhely e-kereskedelmi részének létrehozásához. Mindkét fejlesztőnek hasonló feladatai vannak.
Ahhoz, hogy a jegyet késznek lehessen tekinteni, mindkét fejlesztőnek létre kell hoznia egy új
tartalomtípust, létre kell hoznia néhány kapcsolódó tartalmat, majd végül létrehozni egy linket a
kezdőlapról az új területekre. A jegy elkészülte után ki kell osztaniuk a munkájukat egy tesztelőre,
hogy a változtatásokat validálni lehessen.

Mindkét fejlesztőnek új oldal-típusok létrehozására van szüksége. Mindkét fejlesztőnek szüksége lesz
néhány kapcsolódó tartalom és beállítás létrehozására. Mindkét fejlesztő párhuzamosan dolgozik.
Hogyan kezeli ezzel?

Az Episerver a sablonok létrehozásához kód-első megközelítéssel dolgozik. Ezt a témát a következő


fejezetben részletesen ismertetjük. Egyelőre a fő hangsúly azon van, hogy a tartalomtípus-változások
szinkronizálása egyszerű legyen.

A kódot szükség szerint lehet a GIT-ből húzni/tolni, de mi a helyzet a tartalommal?

Az egyik megoldás az lenne, ha a páros manuálisan szinkronizálná a tartalmat a környezetek között.


Ahogy Tarquin halad a jegyével, folyamatosan tájékoztatja Dave-et azokról az oldalakról és
blokkokról, amelyeknek a helyben kell létrehoznia, és fordítva. Az oldalakhoz szükséges eszközöket,
például a képeket e-mailben osztja meg. A tartalom kézi hozzáadása időigényes, hibakényes és
fárasztó feladat.

Tarquin bevezet egy új beállítások laptípust, hogy a landing page-hez szükséges számos beállítást
tárolhasson. Tarquin ezt a kódot közvetlenül azelőtt rögzíti, hogy kéthetes kirándulásra indul egy
karibi hajóútra. A Másnap Dave bejön az irodába, és a master ágból húzza le. A helyi weboldala most
nem indul el Tarquin commitja miatt. Dave kénytelen abbahagyni, amit eddig csinált, és helyette a
helyi oldal javítására koncentráljon. Dave ellenőrzi a forrásellenőrzést, és észreveszi az új beállítások
oldaltípusát.
Mivel Dave a legfrissebb kódot húzta ki, a 'settings page' séma már a CMS-ében van. Dave megpróbál
létrehozni egy megfelelő "beállítási oldalt" a helyi verzióján, azonban egy másik probléma is felmerül.

A Tarquin által írt kód szerint a beállítások oldalának oldalazonosítója 3. Az Episerver által generált
oldalazonosító a "beállítások oldalához" Daves helyi verziójában más. Az egyetlen módja annak, hogy
Dave a probléma megoldására az, hogy vagy átdolgozza a kódot, vagy szerezzen egy adatbázis
biztonsági másolatot Tarquintól. Ez a történet rávilágít néhány olyan problémára, amellyel akkor
szembesül, ha kizárólag a tartalom kézi szinkronizálására hagyatkozik. Nagyon frusztráló tud lenni,
amikor abba kell hagynia, amit éppen csinál, hogy hogy kijavítson egy váratlan problémát, amit egy
commit okozott. Másodszor, a CMS-en belüli tartalomkészítés dinamikus jellege miatt lesznek apró
árnyalatok. Az oldalazonosítók eltérőek lesznek, a tartalom valószínűleg finom eltéréseket tartalmaz,
a beállítások eltérőek lehetnek, vagy a jogosultságok és a felhasználói csoportok eltérőek lehetnek.
Ezek az árnyalatok a hibák táptalajául szolgálnak.

Dave készíthetett volna egy biztonsági másolatot a Tarquins adatbázisáról, és helyben visszaállíthatta
volna, azonban van egy bökkenő. Ez azt jelentette volna, hogy Dave elveszíti az összes helyi tartalmi
módosítást, amit a következő években végzett.

a jegyéhez, a bloghoz kapcsolódott. Ha egy nagy csapatban dolgozunk, az adatbázis másolása nem
járható út. Mit tegyünk tehát?

A megosztott adatbázis-megközelítés jobban megfelel az ilyen típusú problémákra. A megosztott


adatbázis-beállításban a csapat minden fejlesztője a saját helyi verzióját ugyanarra a megosztott
adatbázisra irányítja. Amikor a valaki a CMS-en belül tartalmat ad hozzá, szerkeszt vagy töröl, az
összes többi fejlesztő azonnal látja a változást. Ez a megközelítés kiküszöböli a tartalom
szinkronizálásának szükségességét a csapat között.

A megosztott adatbázis használatának hátrányára már korábban felhívtuk a figyelmet. Az adatbázis


egyetlen hibaponttá válik. Az egész csapat az adatbázis működésére van utalva. Ha az adatbázis
elromlik az egész csapat leállhat. Általánosságban elmondható, hogy a megosztott adatbázis
leállásának gyakorisága a csapatban dolgozó fejlesztők számával arányosan romlik. A következő
gyakori okok a VPN-problémák, szerverproblémák és refaktorálási problémák lehetnek.

A másik fő probléma, amely a megosztott adatbázis használatából adódhat, az, hogy tudni kell, hogy
egy oldal a webhelyen még mindig folyamatban van-e, vagy már befejezettként van-e aláírva. Amikor
egy fejlesztő elkezd dolgozni egy új funkción.

nagy a valószínűsége, hogy a dolgok változni fognak. Csak azért, mert a tartalmi módosítások azonnal
megosztásra kerülnek, még nem jelenti azt, hogy az már készen áll a többiek számára.

A tartalomszinkronizálás stabilabb megközelítése az, ha a fejlesztők helyi adatbázissal rendelkeznek,


és automatizálással viszik át a tartalmat a környezetek között. A két fő automatizálás

útvonalak a következők:

Episerver Import/Export: Az Episerver import/export funkciója a legegyszerűbb megoldás a


környezetek közötti tartalom szinkronizálására. Az importálás és exportálás funkció nem meglepő
módon lehetővé teszi a tartalmak és eszközök átvitelét az Episerver webhelyek között.

Az exportőr segítségével egy olyan exportfájl hozható létre, amely a webhely összes tartalmának
biztonsági másolatát tartalmazza. Az importőr ezután átveheti ezt a fájlt, és visszaimportálhatja a
tartalmat a CMS-be.
MEGJEGYZÉS Ez az importálás/exportálás funkció az, ahogyan a tartalom varázslatosan létrejön az
Alloy weboldal telepítésekor. Ha megnézi az App_Data mappában, akkor látni fog egy '.epidata'
kiterjesztésű fájlt kiterjesztést.

Az exportfájlt vagy a CMS-en belülről, vagy egyéni kód segítségével lehet létrehozni. Én a CMS-en
belülről szoktam létrehozni a fájlt, mivel ez egyszerűbb. Az exportfájl megosztása tekintetében a
legegyszerűbb, ha a forráskód-ellenőrzésbe csekkoljuk.

Amikor bármilyen új tartalmi változás készen áll a csapat általi felhasználásra, egy frissített exportfájlt
lehet generálni és hozzáadni ugyanabban a commitban, mint a funkciót. Ha az exportfájl verziója a
forráskontrolban van, nagyon könnyen visszaállítható a CMS egy adott időpontra. Ez azért praktikus,
mert megakadályozhatja, hogy mások blokkolják a munkafolyamatot.

Az exportált fájlokkal felfegyverkezve most már importálhatja azt. A tartalom importálása szerintem
jobban kezelhető a kódban. Általában létrehozok egy tartalomimportáló inicializáló modult minden
egyes projektben, amelyen dolgozom.

A tartalom így automatikusan importálható a CMS-be indításkor, kézi beavatkozás nélkül. Ezt az
importálási folyamatot ezzel a kóddal lehet elérni:
public ImportPages(ContentReference startNode, IDataImporter dataImporter)
{
var basePath = EPiServer.Framework.Configuration
.EPiServerFrameworkSection.Instance.AppData.BasePath;
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var importFilePath = baseDirectory + basePath +
"/ExportedFile.epidata";
var fileStream = new FileStream(importFilePath, FileMode.Open);
var options = ImportOptions.DefaultOptions;
options.KeepIdentity = true;
options.ValidateDestination = true;
options.EnsureContentNameUniqueness = false;
options.IsTest = false;
dataImporter.Import(fileStream, startNode, options);

A CMS-be történő tartalomimportáláshoz az IDataImporter API-t kell használnia. Az IDataImporter


API rendelkezik egy Import() nevű metódussal, amely három paramétert igényel:

1. Egy fájlfolyam, amely a szerializált exportált fájlt tartalmazza.


2. Hivatkozás arra a CMS-oldalra, amely alá a tartalmat importálni kívánja.
3. Importálási lehetőségek.

Javaslom, hogy a KeepIdentity tulajdonság mindig legyen engedélyezve. Ez a jelző azt mondja az
importőrnek, hogy ugyanazokat az oldalazonosítókat és blokkazonosítókat használja, amelyeket az
exportfájlban definiált. Ez biztosítja, hogy az azonosítók megmaradnak konzisztensek maradnak a
különböző fejlesztői környezetek között. Szintén jó gyakorlat az IsTest explicit beállítása false

A fenti kód a .NET FileStream API-t használja az exportált fájl sorozatba rendezéséhez egy folyamba,
amelyet aztán az alkalmazás használhat. Ebben a példában feltételezem, hogy az exportált fájl a
AppData mappában található. A teljes webhely importálásakor a ContentReference.RootPage oldalt
kell használni szülőoldalként.

Egy dolgot nem szabad elfelejteni: az importálás/exportálás nem végez adatbázis biztonsági mentést
és visszaállítást. Ez egy fontos különbség, amit szem előtt kell tartani. Az importálás mellékhatása
ahelyett, hogy másolás helyett az, hogy az importálás meghiúsulhat. A hiba gyakori okai a
következők:

Validátorok: Az exportfájl egy adott időpontban jön létre. Ha később új érvényesítési szabályokat ad
hozzá, amelyeknek az exportfájlban lévő tartalom nem felel meg, akkor a tartalom nem fog sikerülni
importálása.

Tartalom hozzáadása új nyelvhez: Ha a tartalom olyan kultúra ellenében készült, amely nincs
telepítve/engedélyezve a helyi számítógépen, az importálás sikertelen lesz.

Tartalomtípusok átdolgozása: Egy adott időpontban exportfájl jön létre. Ha valaki módosítja
bármelyik tartalomtípust vagy annak tulajdonságait, akkor az importálás sikertelen lehet. A
leggyakoribb okok közé tartozik a következők törlése tulajdonságok törlése és a tulajdonságok
típusának megváltoztatása.

Property<T>: Az importálási folyamat nem tudja, hogyan kell szerializálni a Property<T>-ben lévő T-n
belül használt objektumokat. Ezért a Property<T> használatakor maradjunk az egyszerű típusoknál.

Az importáló használatának legrosszabb része az a hiba, amit az Episerver ad, ha a dolgok rosszul
mennek. A sikertelen importálás üzenete nagyon általános és nem túl hasznos. A hiba nem tartalmaz
semmilyen részletes információt arról, hogy miért nem sikerült az importálás. Egyszerűen el fog
bukni, és ki kell vizsgálnia, hogy miért. Az ok megtalálása olyan lehet, mintha tűt keresnénk a
szénakazalban.

Két tipp, amely csökkentheti ezt a fájdalmat. Először is, szokjon hozzá, hogy rendszeresen új
exportfájlt készít. Amikor a dolgok meghibásodnak, egy rövidebb időintervallummal könnyebb lesz
diagnosztizálni a meghibásodást változás. Másodszor, ellenőrizze a naplókat. Amikor valami
meghibásodik, általában van egy megfelelő hiba a naplókban.

Egyedi import/export kód


A tartalom importálásának/exportálásának alternatív módja, ha figyelmen kívül hagyja a beépített
Episerver funkciót, és maga írja meg a kódot. Ezt a megközelítést csak egyszer használtam egy
projektnél, és bár elég jól működött szépen működött, az idő szempontjából nem volt indokolt.
Erősen ellenjavallom ezt az utat.

Ezt a megközelítést követve a CMS-en belül szükséges összes tartalmat kódban adja hozzá, nem pedig
a szerkesztőn keresztül. A CMS-be való tartalom hozzáadásához az IContentRepository.Save()
metódust használja.

Oldalanként megírja az összes kódot, amely megmondja az Episerver-nek, hogyan hozza létre az
oldalt, beleértve az összes szükséges tartalmat, képet és blokkot. Ezután ezt a mintát addig ismétli,
amíg minden egyes bitet a tartalom hozzáadása megtörtént. Mint sejthető, egy több ezer oldalas
webhelyen ez nem igazán kivitelezhető. Azon a projekten, ahol ezt a megközelítést kipróbáltam,
miután a projekt élesbe ment, és a tartalomszerkesztők elkezdték a CMS-en belül elkezdtek tartalmat
hozzáadni, az összes egyéni kód elavulttá vált, és a bevezetést követő első hónapban kidobták.

Ha elég bolond vagy ahhoz, hogy ezzel próbálkozz, akkor az importáló kód strukturálásának
leghatékonyabb módja az, ha követed a tárolási mintát. Minden egyes oldalhoz és blokkhoz hozzon
létre egy megfelelő tárolót.

Minden egyes tárolón belül adjunk hozzá legalább két metódust. Az egyiket egy üres elem
létrehozására, amely képes elfogadni az átadott tartalmat, és egy módszert a tartalom CMS-be
történő mentésére. Az alkalmazás indításakor írhat egy inicializáló modult, amely beolvassa a
tartalmat valahonnan, majd meghívja a megfelelő tárolót, hogy létrehozza az oldalt/blokkot a CMS-
en belül.

Továbbá ne aggódjon, ha néhány kifejezés a feje fölött megy el. Az olyan dolgokat, mint a tartalom
lekérdezése és az inicializáló modulok később részletesen tárgyaljuk. Ebben a forgatókönyvben az
inicializáló modul így nézhet ki:
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class FilterConfig : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var repo = ServiceLocator.Instance<IContentPageRepository>();
repo.CreateContentPage(
new ContentPageParameters{
Name = "Page 1",
Parent = ageReference.StartPage}
)
}
public void Uninitialize(InitializationEngine context)
{
}
public void Preload(string[] parameters)
{
}
}

A fenti kód a 'Bevezetett paraméterobjektum' mintát követi az adatok átadásához az


IContentPageRepository-ba. Ez a minta segít megkönnyíteni a kódot azáltal, hogy minimalizálja a
paraméterek számát, amelyeket át kell adni a metódusba. A paraméterminta objektum példája így
nézhet ki:
public class ContentPageParameters
{
public ContentReference Parent{ get; set; }
public string Name { get; set; }
public ContentArea ContentArea { get; set; }
}
A tartalmi oldal nevű oldal-típus tartalmának létrehozására szolgáló tároló így jöhet létre:
public class ContentPageRepository : IContentPageRepository
{
public ContentPage CreateContentPage(ContentPageParameter params)
{
var contentPage = _contentRepository.GetDefault<ContentPage>(params.Parent);
contentPage.Description = params.Description;
contentPage.Name = params.Name;
contentPage.MainArea = params.ContentArea;
_contentRepository_.Save((IContent) contentPage, SaveAction.Publish, 0);
return contentPage;
}
}

Ez a kis példa egyetlen oldalt generál. Egy teljes weboldal importálásához szükséges kód megírása
nyilvánvalóan hatalmas erőfeszítést igényel. Hacsak nincs jó oka rá, ne legyen ne csábuljon el erre az
útra. A beépített importálás/exportálás megteszi azt, amire szüksége van.

Megosztott vagy helyi?: A csapat sikerének biztosítása érdekében azt javaslom, hogy használjon helyi
adatbázist, és használja az importálás/exportálás funkciót a tartalmi módosítások szinkronizálására a
csapatban. Kipróbáltam az összes az ebben a részben vázolt megközelítéseket, és tapasztalataim
szerint egyértelműen ez a kombináció a leghatékonyabb.

Az Episerver adatbázis visszaállítása


Függetlenül attól, hogy melyik megközelítést választja, valamikor valószínűleg szüksége lesz az
importálási/exportálási folyamatra. Az olyan adatbázisba történő importálás, amely már meglévő
tartalmat tartalmaz, nem kívánt mellékhatásokat okozhat. A legtöbb esetben célszerűbb a tartalmat
egy üres vanilla Episerver adatbázisba importálni. A tartalom üres adatbázisba történő importálása
biztosítja a konzisztenciát az csapat között.

Egy vanilla Episerver adatbázis létrehozásához egy praktikus PowerShell szkriptet használhat. Az új
Episerver-adatbázis létrehozására szolgáló szkript a Nuget csomagok könyvtárában található, a
következő helyen Episerver.CMS.Core.*.*.*.*.*\tools mappában. Az ebben a mappában található
szkriptek létrehozzák az összes olyan táblát és tárolt eljárást, amelyre az Episerver működéséhez
szükség van.

Az ebben a mappában található cmdlet a kapcsolati karakterláncban meghatározott kapcsolati


adatokat fogja használni. A szkript futtatása előtt győződjön meg róla, hogy van egy üres adatbázisa
az SQL-ben, amelynek neve megegyezik a adatbázis, amely a kapcsolati karakterláncban van
definiálva. Ellenőrizze, hogy az SQL felhasználónév és jelszó adatai érvényesek-e. A webes projekt
csomagkezelő konzolján belül írja be az Initialize-EPiDatabase.
Ha a szkript sikeresen lefutott, akkor be kell tudnia jelentkezni az Episerver CMS-be, és egy üres
tartalomfát kell látnia.

MEGJEGYZÉS Ha a cmdlet nem fut megfelelően, akkor az általában a helytelen konfiguráció


eredménye. Győződjön meg arról, hogy a web.config fájlban a kapcsolati karakterlánc helyesen van-e
konfigurálva. Győződjön meg róla, hogy az adatbázis név helyes. Győződjön meg arról, hogy az
adatbázisnak megfelelő tulajdonosa van. Javaslom, hogy az SQL manager segítségével csatlakozzon
az adatbázishoz a kapcsolat részleteiben meghatározott felhasználónév és jelszó használatával, hogy
háromszorosan ellenőrizze, hogy engedélyezve vannak-e és érvényesek-e.

Dealing With Team Strings - A csapatszálak kezelése


Ha a helyi adatbázis-stratégiát választja, akkor a következő probléma, amit meg kell oldania, a
beállítások körül lesz. Hogyan kezelje a csapat közötti kapcsolati karakterlánc részleteit? Minden
egyes csapattagnak egyedi kapcsolati karakterlánca lesz. Hogyan lehet megakadályozni, hogy a
csapat egyik tagja véletlenül felülírja a másik fejlesztő beállítását, amikor a forráskód-ellenőrzésből
push/pull történik?

Az alábbiakban felvázolom az általam javasolt megoldási módot erre a problémára. Ez a megközelítés


számtalan munkaórát takarít meg a csapatnak. A csapatnak nem kell többé állandóan elrejtenie,
majd eltávolítania a helyi kapcsolati karakterlánc adatait. Mindez a helyi építési folyamaton belül
alkalmazott egyéni transzformáció bevezetésével lesz lehetséges. Először is, változtassuk meg a
web.config-on belül a connectionStrings szekciót a következőre egy különálló fájlra mutasson:
<connectionStrings configSource="connectionStrings.config" />

A webgyökérben hozzon létre egy megfelelő fájlt 'connectionStrings.config' néven. A fájl tartalmának
így kell kinéznie:
<connectionStrings>
<add name="EPiServerDB"
connectionString="Server=**;Database=**;User Id=**;Password=**;MultipleActiveResultSets=true"
providerName="System.Data.SqlClient" />
</connectionStrings>

Ezután hozzon létre a webrootban egy 'TransformConfig' nevű mappát. Ebben hozzon létre egy új
fájlt. Ez a fájl a helyi fejlesztői kapcsolati karakterlánc adatainak tárolására szolgál. Az elnevezés fájl
elnevezése fontos. A következő konvenciót kell követnie:
connectionStrings.{PC-NAME}.config
A {PC-NAME} helyett a laptop/PC nevét kell megadni, amelyhez a fájlt társítani szeretné. Ebben a
fájlban adja hozzá az EPiServerDB kapcsolat karakterláncát, és állítsa be, hogy az a saját helyi SQL
adatait használja. Vegye figyelembe, hogy az XML transzformációs szabályok {xdt:Transform} és
{xdt:Locator} is hozzáadásra kerültek:
<connectionStrings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<add name="EpiserverDB"
connectionString=""
xdt:Transform="SetAttributes"
xdt:Locator="Match(name)"/>
</connectionStrings>

Ezután nyissa meg a webes alkalmazások projektfájlt, a .csproj kiterjesztésű fájlt. Nyissa meg a fájlt
egy szövegszerkesztő programban, majd görgessen a fájl legalsó részéhez, a Target területhez.
Távolítsa el a <BeforeBuild> szakasz, és cserélje ki erre a részre:
<Target Name="BeforeBuild" BeforeTargets="Build">
<TransformXml Source="connectionStrings.config" Condition="Exists('Transforms\connectionStrings.$(computer-name).config') "
Transform="Transforms\connectionStrings.$(computer-name).config"
</Target>

A fájl mentése után fordítsa le a megoldást. Ha mindent helyesen adtunk hozzá, a helyi SQL-
kapcsolati karakterlánc adatai a 'connectionStrings.config' állományba kerülnek.

Ezután rá kell vennie minden más fejlesztőt, aki a projekten dolgozik, hogy hozza létre a saját helyi
kapcsolati karakterláncfájlját a transzformációs mappában. Most már van egy egyszerű módja annak,
hogy kezelje több kapcsolati karakterláncot! Amikor legközelebb valaki lokálisan fordítja a webhelyet,
a kapcsolati karakterlánc frissülni fog, hogy a helyi SQL-kapcsolat adatait használja! Többé nem
számít, ha valaki felülbírálja a beállításokat a forráskód-ellenőrzésben. Amint valaki helyileg fordítja a
webhelyet, a kapcsolati karakterlánc frissül a helyes adatokkal!

Ha olyan eszközt használ, mint az Octopus, akkor létrehozhat egy második connectionStrings.config
állományt, amelynek neve például connectionStringsProduction.config, majd használhatja a változó
helyettesítését a web.config fájlban annak biztosítására, hogy a helyi fejlesztési kapcsolat adatait
soha ne használják a termelésben.

Kódolási szabványok
Nehéz lehet biztosítani, hogy egy kódbázis úgy nézzen ki, mintha egyetlen személy írta volna.
Képzeljük el, hogy egy olyan szépirodalmi könyvet olvasunk, amelyben minden fejezetet teljesen más
stílusban és megközelítésben írtak. Elég szar lenne.

Egy kódolási szabvány meghatározása jelentősen javíthatja a csapat által írt kód minőségét. A
kódolási szabványt minden vállalat igényli, de csak a legjobb vállalatok érvényesítik. A való életben
nagy különbség van aközött, hogy valaki azt mondja, hogy van egy szabványa, és aközött, hogy
ténylegesen követi is. Hogy megkímélje magát attól, hogy frusztráltan próbáljon egy kódolási
szabványt népszerűsíteni, használhat egy eszközzel érvényre juttathatsz egyet. Az ilyen típusú eszközt
linting eszköznek nevezik.

A StyleCop a C# nyelv defacto linting eszköze. A StyleCop segíthet a csapatnak konzisztens kódot írni.
A szabályokat ellenőrzi és érvényesíti, amikor a fejlesztő lefordítja a megoldást. Linterként ez az
eszköz rákényszeríti a csapatot, hogy kövesse a kódolási szabványt, és az eredmény gyönyörű kód
lesz!
A StyleCop egy szabályalapú eszköz. Ön engedélyezi a szabályokat, amelyek meghatározzák, hogyan
kell strukturálni a kódfájlokat. Ha valamelyik kód nem felel meg a szabványoknak, akkor a StyleCop
megfelelő hibákat dob ki amikor megpróbálja lefordítani az oldalt. A StyleCop a dobozból kivéve
körülbelül 154 szabályt tartalmaz. Ezek a szabályok mindent lefednek, kezdve az olyan szabványoktól,
mint például az {} egy sorban való használatának tilalma, egészen az összes konstruktorok
tartalmazzanak doc-szöveget.

Ha az összes StyleCop-szabály be van kapcsolva, akkor egy nagyon merev és korlátozó


munkamódszerre kényszerít. A StyleCop használatához mindenképpen időre van szükség, amíg egy új
csapat belerázódik a használatába. A StyleCop egy egy kicsit olyan, mint a marmite: vagy szeretni
fogja, vagy utálni fogja az elején. Örömmel vallom be, hogy amikor először kezdtem el használni, vég
nélkül szidtam!

Az egyik ok, amiért az emberek hajlamosak utálni a StyleCopot, az alapértelmezett szabályrendszer.


Sok alapértelmezett szabály értelmetlennek tűnik, és időigényes a karbantartása. Például, én személy
szerint nem hiszem, hogy hogy minden metódusra és tulajdonságra doc-stringet kell kényszeríteni,
hacsak nem egy külső API-t hozunk létre. Ilyen körülmények között használja a Swagger.io-t. Ha az
osztálykönyvtára csak belsőleg szemben, akkor a nagyszerű elnevezési konvenciók és a jó tervezés
elégségesnek kell lennie.

Egy másik StyleCop szabály, amit nagyon nem szeretek, az az "osztályfejléc" szabály. Ez az
alapértelmezett szabály arra kényszeríti Önt, hogy minden alkalommal, amikor egy osztályt frissít,
valamilyen metaadatot adjon meg. Ezek a metaadatok tartalmazzák a aki a módosítást végezte, és a
módosítás dátumát. Az, hogy az embereket arra kényszerítik, hogy kövessék ezeket az értelmetlen,
időigényes szabályokat, az az oka annak, hogy a StyleCop annyi gyűlöletet vált ki. Miért adjunk hozzá
osztályt fejlécadatokat, amikor ugyanez az információ automatikusan megtalálható a forráskód-
ellenőrzésben? Ha telepíti a StyleCopot, és néhány hétig az alapértelmezett szabálykészletet
használja, meg fogja érteni mire gondolok.

Az én kódolási stílusom az, hogy csak olyan kódot írok, ami hozzáadott értéket teremt. Kevés értelme
van egy szabályt csak a látszat kedvéért követni. Ahhoz, hogy a lehető legtöbbet hozza ki a
StyleCopból, saját szabálykészletet kell definiálnia, olyat, amelyik ami a csapatod számára működik.
Az általam használt szabálykészletet itt találja: https://github.com/jondjones/ILoveCSharp.

Az én kódolási stílusom az, hogy csak olyan kódot írok, amely hozzáadott értéket teremt. Kevés
értelme van egy szabályt csak a látszat kedvéért követni. Ahhoz, hogy a lehető legtöbbet hozza ki a
Stylecopból, meg kell határoznia a saját szabályrendszerét, olyat, amelyik ami a csapatod számára
működik. Az általam használt szabálykészletet itt találja:

https://github.com/jondjones/ILoveCSharp

Git elágazási stratégiák

Az utolsó pont, amelyet figyelembe kell vennie, amikor a csapatfolyamatokat sikerre készíti, a
kódváltozások kezelése. Mivel e könyv középpontjában a CMS architektúra és nem a Git áll, röviden
megemlítem a elágazási stratégiákat, amelyeket én használok:

Feature Flag stratégia Minden új funkció/Jira ticket a masterről ágazik le. Amikor a funkció elkészül,
egy pull request készül, és a munka beolvad a master ágba. A kód a master ágban lévő kódnak mindig
gyártásra késznek kell lennie. Ha egy olyan funkciót kell visszaolvasztani a masterbe, amely nem
gyártásra kész, akkor ahelyett, hogy más ágakkal szórakoznánk, a funkciót egy feature flag mögé
rejtjük. A feature-flag kezdetben engedélyezhető, és csak akkor kapcsolható ki a termelésben, amikor
készen áll.

Ez a stratégia az én személyes preferenciám, azonban ez a stratégia csak bizonyos projekteknél


működik igazán jól. Akkor ajánlom ezt a megközelítést, ha hetente többször is kiadhatod az oldalt.
Amikor elfogadja a feature flag kultúrát, és csak havonta egyszer vagy kétszer ad ki, nagyon gyakori,
hogy a telepítések folyamatosan késnek. Akkor használja ezt a stratégiát, ha képes folyamatosan
kódot kiadni.

Release Branch stratégia Ha a DXP-t használja tárhelymegoldásként, akkor hajlamos vagyok a release
branch stratégiát előnyben részesíteni. Ezen a megközelítésen belül egy ág létezik minden egyes
környezethez az Ön csővezetékhez:

Master: Ez az az ág, amely az élő weboldal által használt kódot tartalmazza.

Pre-prod: Ez az ág tartalmazza a következő kiadás kódját

Integráció: A Ci/Cd ág. Ez az ág tartalmazza a csapat WIP kódját.

Amikor egy kiadást terveznek, az integráció beolvad a pre-prod ágba. Ezt az ágat végül beolvasztják a
masterbe és kiadják.

GitFlow: Ha több csapat párhuzamosan dolgozik ugyanazon a tárolón belül, akkor a GitFlow egy
hatékony stratégia. A GitFlow-ról már sokat írtak. Lényegében létrehoz egy "fejlesztési" ágat, egy
"kiadási" ágat, valamint a szokásos "master" ágat. Hotfix ágakat hozunk létre, ha szükséges. A
'development' ágból egy release ág készül. A "release" ág a következő tesztelésre kerül, és végül a
termelésbe kerül. Ezt követően a "release" ág visszaolvad a masterbe. Amikor az Episerverrel
dolgozik, nincsenek forráskóddal kapcsolatos megkötések, amelyek arra kényszerítenék, hogy egy
bizonyos módon dolgozzon. Szabadon használhat bármilyen stratégiát. Én a GIT stratégiát szoktam
választani az alapján választom ki, hogy mennyire felel meg az aktuális igényeimnek. Ha a
pénzügyekben dolgoznék, akkor a napi telepítés nagyon nehéz, így a GitFlow-t, vagy egy release
branch stratégiát fontolgatnék. Ha az ügyfélnek e-kereskedelmi áruháza lenne, és a fő célja a bevétel
növelése lenne az új funkciók néhány naponkénti kiadásával, akkor a feature-flag megközelítést
javasolnám.
Pages and Blocks - Oldalak és blokkok
Itt az ideje, hogy elkezdjünk kódot írni. Ennek a fejezetnek az a célja, hogy megtanítsa, hogyan
hozzon létre olyan oldalakat és blokkokat, amelyeket a CMS-en belül a szerkesztők használhatnak. A
jó hír az, hogy az Episerver rendelkezik a lehetőség a kód-első CMS fejlesztésre. Ez azt jelenti, hogy az
oldalak és blokkok teljes egészében kódban hozhatók létre. Ez jó hír nekünk, fejlesztőknek, mivel ez
azt jelenti, hogy egy Episerver weboldalt teljes egészében a Visual Studióban készíthetünk. Ez a
megközelítés azt is lehetővé teszi számunkra, hogy maximalizáljuk a termelékenységi szintünket.
Nem kell majd olyan gyakran ugrálni a CMS és a kódbázis között, mint a más CMS-rendszerek
megkövetelik.

Még mindig meglepőnek találom, hogy sok vezető CMS rendszer nem biztosítja ezt a képességet.
Gondoljuk végig, hogy miért olyan kevéssé hatékony a hagyományos CMS munkafolyamat. Először is,
a fejlesztőnek be kellene jelentkeznie a CMS-be egy böngészőn keresztül, majd el kell navigálnia
valamilyen adminisztrációs részbe. Innen egy új sablont és bármilyen tulajdonságot kellene
definiálnia. Ha a sablon elégedett, a sablon elmenthető, és máris kezdődhet a fejlesztés.

A fejlesztőnek be kell töltenie a projektet a forráskontrolból, a választott IDE segítségével. A CMS-ből


származó adatok megjelenítéséhez a fejlesztőnek emlékeznie kell a sablon és a tulajdonság aliasokra
amelyeket korábban létrehozott. Ezen aliasok használatával az adatok lekérdezhetők és elérhetők a
CMS-ből. Ahogy a fejlesztő halad előre, kénytelen folyamatosan váltani a CMS felhasználói felülete és
a IDE KÖZÖTT. Az egyetlen fejlesztő által készített weboldalak esetében ez a megközelítés
működőképes. Ha a csapat léptékét növeljük, ez a folyamat nem működik túl jól.

Ennek a munkafolyamatnak az a korlátja, hogy korlátozza a párhuzamosan elvégezhető feladatok


számát. Minden fejlesztőnek egyetlen példányból kell dolgoznia. Nagyobb csapatokban konfliktusok
lépnek fel mert túl sok ember lesz kénytelen egyszerre túl sok dolgot csinálni. Egy nagy projektben
minden fejlesztőnek szüksége lesz egy helyi weboldalra, amelyhez a funkciókat építheti. Mindezek a
változások egy ponton integrálni kell. Az összes egyedi változtatást integrálni és tesztelni kell, hogy
minden összeilleszkedjen. A tesztelőknek szükségük lehet egy olyan környezetre is, ahol

a dolgok működésének ellenőrzésére. Az ügyfél is kérhet egy környezetet a tartalom migrációjának


megkezdéséhez és az új funkciók jóváhagyásához. A különböző környezetek szükségessége gyakori
követelmény a legtöbb projektben.

A hagyományos munkafolyamatot követő CMS-változások szinkronizálásához a fejlesztőnek


manuálisan be kellene jelentkeznie minden egyes környezetbe, és frissítenie kellene a sablonokat,
amikor CMS-frissítésre van szükség. Ez nem optimális, és a megközelítés nyilvánvalóan nem
skálázható jól. Az összes szerver kézi szinkronizálása rengeteg időt veszít. Mint minden manuális
folyamat, a másolási hibák esélye is megnő.

és a dolgok szinkronizálatlanságának esélye nagy.

A kód-első megközelítés racionalizálja a dolgokat. Az új tartalomtípus-definíciókat többé nem kell


manuálisan szinkronizálni. A CMS-en belül egy sablon létrehozásához vagy frissítéséhez
kódmódosításra van szükség. A címre szinkronizálni a CMS-be, a webhelyet újra kell fordítani és újra
kell futtatni. A változtatás kiszolgálóra történő szinkronizálásához a kódot a forráskód-ellenőrzésbe
kell bevinni, majd telepíteni. Ha van egy megfelelő Ci/Cd csővezeték, akkor ennek automatikusan
meg kell történnie. A Code-first nagyon jól megoldja a sablonok környezetek közötti szinkronizálását.
A code-first az Episerverben a következőképpen működik nagyon szép.
Egy új sablon létrehozásához a CMS-en belül létrehoz egy új C# osztályt a megoldáson belül. Ahhoz,
hogy ezt az osztályt Episerver-elemként társítsuk, az osztályt néhány speciális attribútumokkal. A kód
újrafordítása és a weboldal újbóli futtatása után az Episerver kezeli a sablonfrissítéseket a CMS-en
belül az Ön számára. Hogy az Episerver hogyan kezeli ezt a folyamatot, azt részletesen ismertetjük
később. Azoknak az olvasóknak, akik kétségbeesetten várnak egy tippet, ez a reflexió segítségével
működik. Az inicializálás során az Episerver átvizsgálja a bin mappában lévő összes összeszerelést, és
megkeresi az összes olyan osztályt, amely implementálja a bizonyos attribútumokat. Minden olyan
osztály, amelyet ezen attribútumok valamelyikével díszítenek, importálásra kerül a CMS-be.

A kód-első megközelítés használatának másik nagy előnye, hogy robusztusabb kód írását teszi
lehetővé. A kód-első megközelítés használata azt jelenti, hogy erősen kötött modellek használhatók a
kódbázisban.

Bárki, aki ismeri a C# vagy akár a Typescript nyelveket, értékelni fogja a típusellenőrzés előnyeit. A
gyakori hibák, például a gépelési hibák kiküszöbölhetők. A fordító figyelmeztetni fogja a fejlesztőt, ha
a kód hibásnak tűnik. A típusellenőrzés jelentősen csökkenti a projektbe kerülő hibák számát. Az
olyan CMS-rendszerek, amelyek nem biztosítják a kód-előrehaladást, nagyon érzékenyek lesznek a
gépelési hibákra, és a fékezésre.

CMS-frissítések miatti változásokra.

Képzeljük el, hogy egy olyan CMS-ben vagyunk, amely nem biztosítja a code-first-et. A kezdőlapon
létezik egy PageTitle nevű tulajdonság. A PageTitle string típusú. A tulajdonság HTML-en belüli
megjelenítéséhez a következőket kell tennie valahogyan ki kell szereznünk a CMS-ből a 'PageTitle'
tulajdonságot. Az ehhez szükséges kód valószínűleg valahogy így nézne ki:
<div>
@HTML.GetProperty("PageTitle")
</div>

Először is, ha elírta a HTML-t, akkor a tulajdonság nem jelenik meg. Másodszor, ha egy
tartalomszerkesztő bejelentkezett a CMS-be, és átnevezte a tulajdonságot, például megváltoztatta a
"PageTitle"-ről "Title"-re változtatta a nevét, akkor a nézetben használt alias helytelen lesz. Az ilyen
típusú hibák kezelésének két fő módja van. Ha a CMS egy hiba nélküli filozófiát követne, akkor egy a
rendszer kivételt dobna, és az oldal megszakadna. Az ezt az elvet követő CMS-rendszerekben gyakori,
hogy a tartalomszerkesztők tönkreteszik a gyártott oldalt, ha menet közben sablonokat készítenek,
változtatásokat hajtanak végre. Ha a CMS a fail-silently megközelítést követné, akkor a
tartalomszerkesztő nem lenne tudatában annak, hogy épp most tette tönkre az oldalt. Ebben a
forgatókönyvben az egyetlen módja annak, hogy megtudja, hogy az oldal megtört. ha valaki
manuálisan ellenőrizné.

A kód-első megközelítésben ahelyett, hogy a CMS-en belül a felhasználói felület segítségével építené
fel a sablont, a fejlesztő kódban határozza meg a sablont. A Visual Studio segítségével a fejlesztő
refaktorálja a publikus tulajdonságot megfelelően. Mivel a kódot C# nyelven írja, a Visual Studio a
tulajdonságra vonatkozó összes hivatkozást is automatikusan frissíti helyettünk. A fordító használata
a tulajdonság frissítésének biztosítására sokkal megbízhatóbb, mintha kézzel próbálkoznánk ezzel. A
refaktorálás után a fejlesztő újra futtathatja a CMS-t, és a változások importálódnak.

A Code-first lehetővé teszi az egységtesztek írását is. Erősen tipizált modellek nélkül teljes
tesztkészletet írni rémálom. Tapasztalatom szerint a CMS-ben írt tesztek, amelyek nem követik a
kód-első paradigmát követő CMS-ek nagyon törékenyek és megbízhatatlanok lesznek. Ezekben a
rendszerekben a tesztek annyira ingatagok, hogy nincs sok értelme időt áldozni a megírásra és
karbantartásra.

Episerver Content - Episerver tartalom


A "tartalom" fogalmát az Episerver 7-es verziója vezette be. A "tartalom" lényege, hogy rugalmasabb
és dinamikusabb sablonok létrehozását teszi lehetővé. Az Episerver terminológiája szerint a "tartalom
minden olyan dolog, amely az IContent interfészből valósítja meg. Az IContent interfész az
Episerver.Core névtérben található. Meghatározza az osztályok alapvető metódusait és
tulajdonságait kell megvalósítania ahhoz, hogy sikeresen hozzárendelhető legyen egy Episerver
objektumhoz.

TIPP Az Episerver nem homályosítja a kódot. A DotPeek vagy a Reflector segítségével betekinthet
bármelyik core assembly belsejébe, hogy többet tudjon meg a CMS-ről.

Az Episerver.Core, ahogy a neve is mutatja, az a könyvtár, amely a CMS alapkódjának nagy részét
tartalmazza. Az IContent-re való reflection használatával feltárul ez az interfészdefiníció:
public interface IContent : IContentData
{
string Name { get; set; }
ContentReference ContentLink { get; set; }
ContentReference ParentLink { get; set; }
Guid ContentGuid { get; set; }
int ContentTypeID { get; set; }
bool IsDeleted { get; set; }
}

Nézzük át, hogy mit csinálnak az egyes eszközök:

Name - A név az a tulajdonság, amelyet a CMS használ. Kerülje a különleges karakterek használatát a
név létrehozásakor.

ContentLink - Ez az egyedi azonosító tulajdonság, gondoljon az adatbázis elsődleges kulcsára, de a


CMS-tartalomra.

ParentLink - Egy weboldal hierarchikus struktúrából épül fel. Minden tartalomnak mindig lesz egy
szülője. A szülő határozza meg, hogy az elem az oldalhierarchiában hol helyezkedik el. Out of az
Episerver egy speciális tartalomtípussal, a SysRoot-tal rendelkezik. A SysRoot a gyökércsomópont az
oldalfán belül. A weboldal kezdőlapjának szülője ez a speciális SysRoot elem lenne. A dobozból kivéve
az Episerver egy speciális tartalomtípussal, a SysRoot-tal érkezik. A SysRoot a gyökércsomópont az
oldalfán belül. A weboldal kezdőlapjának szülője ez a speciális SysRoot elem lenne.

IsDeleted - Az IsDelete tulajdonság megmutatja, hogy az oldal "puha" törlése megtörtént-e. A puha
törlés azt jelenti, hogy az oldal még mindig létezik az adatbázisban, de a tartalomszerkesztő a
szemétbe helyezte kukába. Ha az elemek a szemetesbe kerültek, akkor nem jelennek meg a
weboldalon.

ContentTypeID - A ContentTypeID egy hivatkozást tartalmaz arra a sablontípusra, amely alapján a


tartalmat létrehozták. Képzeljük el, hogy a kezdőlap sablonhoz a tartalomtípus-azonosítót 1-es
értékkel rendelte hozzá a Episerver a létrehozásakor. Amikor egy új oldal jön létre a honlap sablon
felhasználásával, a tartalomtípus azonosítója 1 lesz.
ContentGuid - A ContentGuid a tartalom egyedi azonosítására szolgál. Erre a tulajdonságra többek
között azért van szükség, hogy támogassa az olyan feladatokat, mint a tartalom migrációja. Ha
megpróbál egy EpiSever tartalommigrációt (import/export) egy régi webhelyről egy új adatbázisba,
akkor könnyen előfordulhat, hogy az új webhelyen van egy másik tartalmi elem ugyanolyan
ContentReference-rel. A ContentGuid biztosítja, hogy ezeket az elemeket meg lehessen
különböztetni.

The ContentReference Explained - A ContentReference magyarázata


Az IContent interfész által definiált ContentLink tulajdonság ContentReference típusú. A
ContentReference az az entitás, amelyet az Episerver egy egyedi azonosító ábrázolására használ. A
legtöbb egyedi azonosító egy értékkel reprezentálható. Az Episerver CMS tartalmak esetében ez nem
így van. Ehelyett az Episerverben az egyedi azonosítót három érték képviseli:
public class ContentReference
{
public string ProviderName { get; set; }
public int WorkID { get; set; }
public int ID { get; set; }
}

ID

Bármikor, amikor egy oldal vagy egy blokk jön létre az Episerverben, egy új bejegyzés készül az
Episerver adatbázisában. Az ID tulajdonság az SQL-ben az adatbázis elsődleges kulcsának felel meg. A
három ContentReference osztályon definiált három tulajdonság közül az ID tulajdonság az, amellyel a
legtöbbet fogunk dolgozni. Ahhoz, hogy kódban hozzáférhessen egy Episerver oldalhoz, egy új
tartalomreferencia-elemet kell létrehozni, a konstruktorban megadva az ID-t, a következőképpen:
var query = new ContentReference(10);

Egy érvényes tartalomreferencia-objektummal felvértezve az Episerver API-k egyikével lekérdezheti a


CMS-t, és adatokat kaphat az adott oldalról.

WorkID

Egy oldal a weboldal élettartama alatt több százszor is frissülhet. Egy oldal új verziója jön létre,
amikor a CMS-en belül bármilyen tartalom frissül. Azzal, hogy egy oldal teljes módosítási
előzményeit, nagyon hasznos. Az előzmények ismerete egyes ügyfelek számára jogi követelmény is
lehet. A pénzügyi szektorban dolgozó ügyfeleknek bizonyítaniuk kell, hogy a weboldal egy adott
időpontban mit javasolt.

Az oldalverzió nem csak a múltbeli oldalak esetében hasznos, hanem a jövőbeli oldalak esetében is!
Az Episerver rendelkezik egy másik praktikus funkcióval, a "projektek"-kel. A projekteket úgy lehet
elképzelni, mint egy óriási vödröt, ahol a tartalomszerkesztő együttesen kezelheti a tartalmi
módosítások egy csoportját. Képzelje el, hogy a CMS-en belül létrehoz egy marketingkampányt.
Amikor a kampány élesedik, az összes kapcsolódó tartalommódosítást egyszerre kell közzétenni.
Ahelyett, hogy kézzel kellene ütemezni a sok független tartalmi módosítást, egy projekt segítségével
az összes módosítást egyszerre lehet közzétenni. Projektek csak a WorkID miatt lehetségesek. A
projekten belül létrehozott tartalomnak más WorkID lesz a címe.
Provider Name - Szolgáltató neve

Az Episerver úgy konfigurálható, hogy több adatforrást használjon a tartalomhoz. Az Episerverrel való
munka során lehetőség van külső adatforrásokból származó "tartalom" integrálására. Az
alapértelmezett CMS adatbázis helyett elméletileg létrehozhat egy tartalomszolgáltatót, és
integrálhat tartalmat egy harmadik fél adatbázisából. Több mint 10 év alatt csak egyszer kellett ezt a
funkciót egy projektben használnom. Hacsak nem a nincs olyan követelménye, hogy a
tartalomszerkesztők a CMS-en belül hozzáférhessenek olyan adatokhoz, amelyek egy külső
adatforrásban is találhatók, valószínűleg soha nem fogja ezt használni.

A ProviderName az adatok forrását jelöli. A WorkID-hez hasonlóan, ha nem ad meg értéket, akkor az
Episerver egy alapértelmezett értéket fog használni. Az alapértelmezett érték az Episerver adatbázis.

Comparing Content References - Tartalmi hivatkozások összehasonlítása

Az ID, a WorkId és a ProviderName együttesen egyedi azonosítót határoz meg az Episerverben.


Bizonyos helyzetekben előfordulhat, hogy két különböző tartalmi hivatkozást szeretne
összehasonlítani. Ha nem teljes mértékben nem érti a tartalomreferenciák felépítését, akkor
kísértésbe eshet, hogy ehhez hasonló kódot írjon:
var contentReferenceOne = new ContentReference(1);
var contentReferenceTwo = new ContentReference(2);
var isEqual = contentReferenceOne.ID == contentReferenceTwo.ID;

Ez a kód úgy tűnhet, hogy működik, sőt, talán még a tesztelésen is átmegy. A ProviderName
figyelmen kívül hagyása azonban hibát okozhat a jövőben. Ha valaki regisztrál egy második
tartalomforrást, akkor ez a kód egy olyan elemmel is egyezhet, amit nem is akartál. Ha két tartalmi
hivatkozást kell összehasonlítania, akkor használja az Equals() vagy a Compare() bővítési
metódusokat. Az Equals() kiterjesztés összehasonlítja az ID-t, a WorkID-t és a ProviderName-et. Ez azt
jelenti, hogy ez az egyenlőségi ellenőrzés a jövőre nézve is biztonságos. Az Equals(), a
következőképpen használható:
var isEqual = contentReferenceOne.Equals(contentReferenceTwo);

Page Types Explained - Oldaltípusok magyarázata

Az Episerverben található tartalom azonosításával kapcsolatos ismeretek birtokában elkezdhetünk


létrehozni néhány oldalt és blokkot. Ez a szakasz az oldal létrehozásának megvitatásával kezdődik.
Tartsa meg a címet szem előtt, hogy a legtöbb tanács ugyanúgy alkalmazható egy blokkra is. Egy új
oldal-típus definiálásához az Episerverben a folyamat a következő lépésekre bontható:

• Hozzon létre egy osztályt, és örökölje a PageData osztályból.


• Díszítse ezt az osztályt Episerver-attribútumokkal a metaadatok meghatározásához.
• Meghatározza a sablonhoz társítandó tulajdonságokat.
• Díszítsük fel az egyes tulajdonságokat Episerver attribútumokkal a metaadatok
meghatározásához.
• Fordítsa le a projektet és töltse be a weboldalt
Egy oldal létrehozásához először is létre kell hoznia egy osztályt, és örökölnie kell a PageData-tól, a
következőképpen:
using EPiServer.Core;
public class Homepage : PageData
{

A PageData alaposztály az EpiServer.Core összeállításban található. A PageData definiálja az összes


olyan tulajdonságot, amelyet egy oldalnak meg kell valósítania ahhoz, hogy az Episerver képes legyen
interakcióba lépni vele sikeresen. Ha a tükrözés segítségével megnézzük a PageData kódját, láthatjuk,
hogy az sok mindent tartalmaz. A jó hír az, hogy a legtöbb ilyen dologról soha nem kell tudni. A
tulajdonságok, amelyeket meg kell ismernie, az alábbiakban láthatóak. Kommentárokat adtunk
hozzá, hogy rövid áttekintést adjunk az egyes tulajdonságok céljáról:
public class PageData : IContent

{
// This mirrors a property found in the setting tab. You can use this to hide/display pages in a menu
public virtual bool VisibleInMenu { get; set; }
// The page type Episerver has assigned your template
public virtual int PageTypeID { get; set; }
// The default language for the page
public virtual string LanguageID { get; set; }
// The Uid
public virtual ContentReference ContentLink { get; set; }
// The scheduled data for the page to be published live
public virtual DateTime StartPublish { get; set; }
// The pages parent ID. For homepage this will be root
public virtual PageReference ParentLink { get; set; }
// The page name
public virtual string PageName { get; set; }
// The internal URL
public virtual string LinkURL { get; set; }
// The URL
public virtual string URLSegment { get; set; }
// Is the page in the recycle bin
public virtual bool IsDeleted { get; set; }
// The external URL
public virtual string ExternalURL { get; set; }
// By default anything returned from the API is read-only
// This method can be used to get an editable version
public PageData CreateWritableClone();
// Allows you to set start-up values when the page is created
public override void SetDefaultValues(ContentType contentType);
}

Decorating the class with Episerver attributes - Az osztály díszítése Episerver attribútumokkal

Egy új oldaltípus Episerverrel való regisztrálásához meg kell adnod néhány metaadatot is az oldalról.
Ezt az osztály [ContentType] attribútummal való díszítésével érhetjük el. [ContentType] az
EPiServer.DataAnnotations névtérben található. A [ContentType] attribútum egy kötelező
attribútum, amely minden oldaltípus és blokk-típus definícióban kötelező.
Episerver szerkesztő

Ha elfelejted az osztályodat [ContentType]-val díszíteni, akkor a tartalomtípus nem fog helyesen


regisztrálni az Episerverben. Az alábbiakban egy példa látható egy oldal-típus definícióra:
[ContentType(
DisplayName = "Home Page",
GUID = "EB15ECE1-341D-4F3D-887B-315963732790",
Description = "Home Page")]
public class Homepage : PageData
{}

A [ContentType] attribútum lehetővé teszi néhány igen hasznos metaadat hozzáadását az oldalról:

AvailableInEditMode: Meghatározza, hogy az oldaltípus látható legyen-e a szerkesztőben. Ha ez a


tulajdonság nincs megadva, akkor ez alapértelmezés szerint true lesz, és az oldaltípus látható lesz a
CMS-BEN. Ezt a tulajdonságot csak akkor használja, ha kifejezetten el akarja rejteni a sablont a CMS-
en belül. Az oldaltípus elrejtése hasznos lehet, ha olyan belső sablonokat szeretne létrehozni,
amelyek a normál tartalomszerkesztők soha nem hozhatnak létre. Például egy admin képernyő

Description: A leírás mező értéke tooltip-súgóként jelenik meg. A súgó a sablonválasztó képernyőn
látható. Ez akkor hasznos, amikor a tartalomszerkesztők eldöntik, hogy melyik A leírásnak elegendő
információt kell nyújtania ahhoz, hogy a tartalomszerkesztő tudja, hogy mit csinál és hol kell
használni.

DisplayName: A CMS által használt név

Order - Sorrend: A sablon pozíciója az "új oldal létrehozása" képernyőn belül.

GUID: Az oldal alternatív egyedi azonosítója. Ez a tulajdonság nem kötelező, azonban mindig
javaslom a használatát. Ha elfelejti beállítani a GUID-t, és sok adatmigrációt végez, akkor ez a a
mulasztás sokba kerülhet. Ha elfelejti megadni a GUID tulajdonságot, a CMS akkor is importálni fogja
a sablont az elvárásoknak megfelelően. Problémák merülhetnek fel, ha a CMS importálás/exportálás
funkcióját kell használnia. Képzelje el, hogy egy fejlesztő létrehoz egy új oldaltípust, és bejegyzi a
forrásellenőrzésbe, egy másik fejlesztő pedig a forrásellenőrzésből való lehíváskor beemeli a
módosítást. A tartalomtípus-azonosítók a két adatbázis között eltérőek lesznek. Az
importálás/exportálás nem biztos, hogy működik. Ez a tulajdonság segíthet a CMS-nek a
tartalomtípusok leképezésében még akkor is, ha az azonosítók eltérőek.
GroupName: Az Episerver új oldal létrehozása képernyőn belül az oldaltípusok csoportosíthatók. A
"csoportok" javítják a szerkesztési élményt, mivel egyszerűbbé teszik a sablonok megtalálását.
GroupName határozza meg, hogy a sablon melyik szekcióhoz lesz hozzárendelve. Ha a GroupName
nincs beállítva, akkor az oldaltípus az alapértelmezett csoportba kerül.

AvailableContentTypes: A tartalomszerkesztők nem mindig megbízhatóak. Ha néhány hónapig hagy


egy csapat tartalomszerkesztőt, nem ritka, hogy a felső szintű tartalomfát a következő tartalmakkal
zsúfolják tele mindenféle tesztoldalakkal. Az [AvailableContentTypes] attribútummal korlátozható,
hogy a tartalomszerkesztő bizonyos helyzetekben milyen oldaltípusokat hozhat létre. Ez egy jó
funkció lehet, amely segíthet abban, hogy ne legyen váratlan sablonok hozzáadása olyan módon,
amiről nem gondoskodtál.

Egy valós példa arra, hogy az oldalkorlátozások hozzáadásának elfelejtése milyen problémát okozott
az életemben, már sok évvel ezelőtt történt. Egy tartalomszerkesztő, akivel együtt dolgoztam, úgy
gondolta, hogy nagyszerű ötlet lenne, ha több mint 200 tesztoldalt hozzon létre közvetlenül a
kezdőlap csomópont alatt. Ez azt jelentette, hogy a szerkesztőnek sokáig tartott betölteni, és nagyon
nehéz volt megtalálni a tartalmat. A probléma megoldására egy korlátozást adtam hozzá, így a
tartalom oldal típusú sablon nem hozható létre a kezdőlap közvetlen gyermekeként. Ha követni
szeretné a jó CMS-gyakorlatokat, mindig használja az [AvailableContentTypes].

Az AvailableContentTypes ötféleképpen konfigurálható:

Include - Tartalmazza: Fehérlistás megközelítést alkalmaz. Ha be van állítva, meghatározza, hogy


mely oldaltípusok hozhatók létre gyermekként.

Exclude: Fekete listás megközelítést használ. Ha be van állítva, meghatározza azokat az


oldaltípusokat, amelyek nem hozhatók létre gyermekként. Én inkább kerülöm ezt a megközelítést,
mivel ezzel megszegjük a DRY elvet. Ennek a szűrőnek a használata hajlamos arra, hogy sok másolást
és beillesztést vezessen be az oldaltípus-definíciók között.

IncludeOn: Ha be van állítva, meghatározza, hogy más oldaltípusok hogyan léphetnek vele
kapcsolatba. Elméletileg ez némileg megszilárdítja a kódot. Az összes szabály arra vonatkozóan, hogy
az oldal hol használható, a ugyanabban a helyen. Tapasztalataim szerint ez a megközelítés hajlamos a
hibákra. Bármikor, amikor egy új oldaltípus kerül definiálásra, nem szabad elfelejteni, hogy minden
egyes oldaltípust frissíteni kell a rendszerben, ami egy fájdalmas.

ExcludeOn: Az IncludeOn fordítottja. Az ExcludeOn kifejezetten meghatározza azokat az


oldaltípusokat, amelyek alatt nem hozható létre.

Availability - Elérhetőség: Meghatározza, hogy minden vagy nulla tartalomtípus legyen elérhető. Ha
egyik sincs beállítva, az attribútum egyéb beállításait figyelmen kívül hagyja.

Javaslom, hogy mindig az Include-ot használja, mivel általában ez a legkönnyebben érthető


megközelítés. Az Exclude-ot ritkán használtam, főleg az alap oldaltípusoknál. Ezt mentálisan
nehezebbnek találom a dolgok csoportosítását ezzel a megközelítéssel. Használhatna egy vegyes
megközelítést is, tehát Include és ExcludeOn, azonban úgy gondolom, hogy ez nehezebben érthető
kódhoz vezet, ezért én ezért nem javaslom. Az AvailableContentTypes attribútum kódban való
használatához lásd az alábbi példát:
[ContentType(
GUID = "f7c40a3a-ddb5-45c0-bd40-124bb367eaa1",
DisplayName = "Home Page")]
[AvailableContentTypes(Include = new[]
{
typeof(LandingPage),
})]
public class HomepagePageType : PageData

Ebben a példában az Include tulajdonság van megadva. Az engedélyezett oldaltípus-definíciók tömbje


kerül átadásra. Ebben az esetben a landing page a kezdőlap alatt hozható létre.

The Access Attribute - Az Access attribútum

Az Access attribútum határozza meg, hogy mely felhasználók és csoportok hozhatnak létre oldalt az
adott típus használatával a CMS-en belül. Ha egy felhasználó nem rendelkezik hozzáféréssel, akkor
nem fogja tudni látni az oldalt a CMS-en belül "új oldal létrehozása" képernyőn. Az Access attribútum
három tulajdonságot tartalmaz:

Users - Felhasználók: Az Episerver felhasználónevek vesszővel elválasztott listája, amely alapján


korlátozni kell. Nem javaslom, hogy ezt a megközelítést soha ne használja. A felhasználónevek kódba
történő kemény kódolása rossz ötlet. Ha valaha is szeretné frissíteni a listát, akkor a termeléshez való
kiadásra lenne szükség.

Roles - Szerepkörök: A tartalomhoz hozzáférő Episerver-szerepkörök vesszővel elválasztott listája. Ez


jobb megoldás, mivel könnyebben kezelhetők a jogosultságok, a felhasználók a CMS-ben
hozzáadhatók/eltávolíthatók a szerepkörökből. Vagyis nem kell kódot telepíteni a lista kezeléséhez.

VisitorGroups: A látogatói csoportok neveinek vesszővel elválasztott listája. A látogatói csoportokkal


később részletesebben foglalkozunk. A látogatói csoportok a személyre szabáshoz használatosak. Így
korlátozhatja a hozzáférést dinamikusan, bizonyos kritériumok alapján.

Az alábbiakban látható egy kódrészlet, amely lezárja az oldaltípust, hogy csak az Episerver
rendszergazdái férhessenek hozzá:
// The CmsAdmin role is the role used to identify Episerver users who have been given the administrator permission.
// A CmsAdmin szerepkör azon Episerver-felhasználók azonosítására szolgál, akik rendszergazdai jogosultságot kaptak.
[Access(Roles = "CmsAdmins")]
public class HomepagePageType : PageData
{}

Általánosságban azt javaslom, hogy ne hagyatkozzon túlságosan az Access attribútumra. Az


oldalkorlátozások kezelése teljes egészében elvégezhető a CMS-en belül, ami a legtöbb esetben jobb
megoldás. Ez a szűrés hasznos az admin és a backend sablonokra. A normál tartalmi sablonok
esetében azt javaslom, hogy a CMS-en belül kezelje a jogosultságokat.

Properties - Tulajdonságok

Miután regisztráltunk egy sablont/tartalomtípust és hozzárendeltünk néhány metaadatot, a


következő lépés néhány mező meghatározása. Ezek a mezők lehetővé teszik a tartalomszerkesztők
számára, hogy adatokat adjanak hozzá az oldalhoz a CMS-BEN. A mezők definiálása az osztály
nyilvános tulajdonságainak hozzáadásával történik. Az oldaltípus osztályban definiált minden egyes
tulajdonságot leképezünk egy alapul szolgáló CMS tulajdonság-definíció-típusra. Ez a
tulajdonságdefiníció típus jelenik meg a CMS-en belül a tartalomszerkesztők számára.
Egy tulajdonság hozzárendelése egy oldal-típushoz hasonlóan történik, mint egy normál tulajdonság
hozzáadása egy osztályhoz. Hozzárendelünk egy nevet, egy típust, egy gettert és egy settert. Az
egyetlen lényeges különbség az, hogy a hogy a tulajdonságot virtuálisnak kell beállítani.
public virtual string MyPropertyName { get; set; }

A tulajdonságdefiníciónak két fő funkciója van. Először is, meghatározza a CMS által a komponens
megjelenítéséhez szükséges metaadatokat. Másodszor, meghatározza azt az adatformátumot,
amelyben az Episerver elmenti a kapcsolódó tartalmat az adatbázisban.

A szabványos tulajdonságtípusok minden fejlesztő számára ismerősek lesznek. Ezek közé tartozik a
Boolean, DateTime, Decimal, Float, Int, Single, String, TimeSpan, Url és DateTime. Például, amikor egy

tulajdonságot int típusúnak állítjuk be. Amikor egy tartalomszerkesztő szerkeszt egy ilyen típusú
oldalt, a felhasználói felület egy számválasztót fog megjeleníteni.

A szabványos .NET-típusokon kívül az Episerver számos egyéni tulajdonságtípust is biztosít. Ezek a


típusok inkább CMS-specifikusak, és olyan dolgokat tartalmaznak, mint a PageReference,
ContentArea, XHtmlString és LinkItemCollection. Az XHTMLString tulajdonságtípus például
szövegszerkesztőként jelenik meg a CMS-en belül. Ez a szövegszerkesztő a Wordhöz hasonló.
Lehetővé teszi a tartalomszerkesztők számára, hogy gazdag szöveget adjon hozzá egy oldalhoz, és
alapvető formázásokat alkalmazzon. A szerkesztő biztosítja az összes szokásos mod-kontot, mint
például a formázás, stílusok alkalmazása, táblázatok stb...

Talán észrevette, hogy itt némi Episerver varázslat történik. Hogyan alakítja át az Episerver a
tulajdonságtípust egy olyan elemmé, amely megjelenik a CMS-ben? A háttérben, további asszociációk
és hozzárendelések zajlanak. Ez a backing-típusokon keresztül történik.

A backing-típusok(Backing-types) nagyon hasonlítanak a property-típusokhoz. A backing-type


megmondja az Episerver-nek, hogyan dolgozzon fel egy mezőt. Az Episerver főbb háttértípusai a
következők:

• PropertyBoolean
• PropertyNumber
• PropertyDate
• PropertyFloatNumber
• PropertyPageType
• PropertyLongString
• PropertyUrl

Ha egy mező karakterláncként van definiálva, akkor a PropertyLongString háttértípusra lesz


felbontva. Ezt a tulajdonságtípus és a háttértípus közötti leképezést egy úgynevezett
BackingTypeResolver. A BackingTypeResolver célja kettős. Először is, meghatározza, hogy az
Episerver milyen UI-komponenst jelenítsen meg a szerkesztőben. Másodszor, meghatározza a
formátumot, amelyet a tulajdonságot kell elmenteni az adatbázisban. A BackingTypeResolver alapból
támogatja ezeket a tulajdonságtípusokat:

• Bool → PropertyBoolean
• Byte → PropertyNumber
• ContentArea → PropertyContentArea
• CategoryList → PropertyCategory
• ContentReference → PropertyContentReference
• DateTime → PropertyDate
• Decimal → PropertyNumber
• Double → PropertyNumber
• Float → PropertyNumber
• LinkItemCollection → PropertyLinkCollection
• PageReference → PropertyPageReference
• PageType → PageType
• Single → PropertyFloatNumber
• String → PropertyLongString
• TimeSpan → PropertyTimeSpan
• Url → PropertyUrl
• XForm → PropertyXForm
• XhtmlString → PropertyXhtmlString

Display Attributes - Attribútumok megjelenítése


A CMS-nek szüksége lesz néhány további metaadatra is az egyes tulajdonságok megjelenítéséhez. Ez
úgy történik, hogy a tulajdonságot a Display attribútummal díszítjük. A Display attribútum a
System.ComponentModel.DataAnnotations névtérben található. A Display attribútumot a
következőképpen kell beállítani:
[Display(
Name = "Page Title",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual string MyTitle { get; set; }

A Display számos olyan tulajdonsággal rendelkezik, amelyekkel további metaadatokat adhat hozzá a
CMS-hez. Egy dolog, amit meg kell jegyezni, hogy a Display attribútum nem Episerver-specifikus
attribútum. Ez egy vanília .NET attribútum, amelyhez az Episerver kapcsolódik. Néhány nyilvános
tulajdonságát az Episerver nem használja, és nem tesz semmi hasznosat. Ezeket a tulajdonságokat
kihagytam.

Episerver UI

Amikor új tulajdonságot definiál a Display attribútummal, a következő főbb tulajdonságokat kell


használnia:

Name: A CMS-ben megjelenő név.

Group name: A lap, amelyen a tulajdonság megjelenik

Description: A tulajdonság mellett megjelenő UI-súgó


The Import Process Explained - Az importálási folyamat magyarázata
Ezzel befejeződött az összes lépés, amelyet egy új oldaltípus létrehozásához követnie kell. Mielőtt
továbblépnénk, itt az ideje, hogy demisztifikáljunk még néhány Episerver varázslatot. Hogyan
működik az Episerver regisztrál egy oldaltípust a CMS-en belül? A weboldal első betöltésekor. Az
alkalmazás indítási eseményén belül egy kezelőt hívunk meg. A kezelő átvizsgálja a 'bin' mappában
található összes összeszerelést. A használata reflexió segítségével minden egyes assembly-t
átvizsgálunk minden olyan osztály után, amelyet a ContentType attribútummal díszítettek.

Ha találunk egyezést, a reflection segítségével kiolvassuk a metaadatokat a ContentType


attribútumból. Ezután ez a metaadat felhasználásra kerül a tartalomtípushoz tartozó adatbázis-
bejegyzés létrehozásához. Ezután az összes nyilvános osztályban definiált összes nyilvános
tulajdonságot beolvassuk és elemezzük. Amikor olyan tulajdonságot találunk, amelyet a Display
attribútummal díszítettek, a metaadatok mellett a BackingType is ellenőrzésre kerül. A tulajdonság
ezután egy kapcsolódó mező létrehozására használjuk, amelyet egy külön adatbázis-táblába
mentünk. A Backing Type resolver ellenőrzi a mező tulajdonságtípusát. A tulajdonság ezután
leképezésre kerül egy backing-type-hoz.

Miután ez a társítás megtörtént, amikor az oldal betöltődik a CMS-en belül, az Episerver ismeri a
megfelelő UI-komponenst, amelyet a szerkesztési képernyőn belül meg kell jeleníteni. Azt is tudja,
hogyan kell tárolni és az adott tulajdonság adatainak tárolása és lekérdezése.

A változtatásaim nem szinkronizálódnak


Ha a kód-először használatával történő módosítások során olyan problémával találkozik, hogy a
módosítások nem jelennek meg a CMS-ben, akkor verziókezelési problémája lehet. Ez egy nagyon
ritka előfordulása, és általában az összeszerelési verzió eltéréséből adódik.

Ha valaha is azt tapasztalja, hogy a CMS nem frissíti a modelleket a várt módon, navigáljon a CMS
Episerver Admin részének "Content Type" fülére. Keresse meg a nem frissülő oldalt/blokkot
helyesen. Ezt a tartalomtípus szekción belül találja meg. Jelölje ki a problémás elemet. A szerkesztési
képernyőre kell navigálnia. Innen, ha egy sárga figyelmeztető üzenetet lát, hasonlóan a akkor tudni
fogja, hogy szinkronizálási problémával találkozott.
Changes in the model for this page type were ignored because its version (1.0.0.0) is lower than version in the database(2.0.0.0)

Az oldaltípus modelljének változásait figyelmen kívül hagyták, mert a verziója (1.0.0.0.0) alacsonyabb,
mint az adatbázisban lévő verzió(2.0.0.0.0).

Ez a hiba azt jelenti, hogy az oldal és a blokk-típus definícióját tartalmazó összeállítás verziója nincs
szinkronban. Ez a hiba akkor jelentkezik, ha a CMS korábban egy újabb verziójával találkozott. Amikor
egy tartalmi elemet a kód-első használatával frissít, az Episerver tárolja a tartalmi elemet tartalmazó
összeállítás aktuális verzióját is, ahol a változtatásokat felfedezték.

Ha megpróbál frissíteni egy modellt egy összeállítás segítségével, és annak alacsonyabb verziója van,
mint az Episerver által az adatbázisban tárolt verzió, az Episerver nem frissíti a modellt. Ez az
ellenőrzés azért lett bevezetve, hogy megakadályozza, hogy a tulajdonságokat véletlenül felülírják a
nem kívánt módosítások. A leggyakoribb ok, amiért a modellek nem szinkronizálódhatnak, az
adatbázis helyreállítása. Ha visszaállít egy adatbázist és ezután elfelejti a megfelelő kódot a
forráskód-ellenőrzésből, lehetséges az eltérés. Ha megnyitja az adatbázist, és megnézi a
tblContentType ModelTye oszlopában lévő adatokat tábla adatait, egy ehhez hasonló bejegyzést fog
látni:
MyProject.Core.Pages.MyPage, MyProject.Core, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null

Ezt a hibát felhasználhatja a könyvtárában használandó verziószám meghatározásához. A verziószám


frissítéséhez több lehetősége van. Egyszerűen megpróbálhatja a legfrissebb kódot előhívni a
forráskontrolból. Kézzel frissítheti a problémát okozó összeállítás verziószámát a Visual Studio-ban,
hogy az nagyobb legyen, mint a CMS által elvárt érték. Végül pedig manuálisan visszaváltani a számot
az adatbázisban. Általában nem javaslom az adatbázis kézi frissítését, azonban ebben az esetben ezek
a módosítások általában biztonságosak. Végül, ha azt szeretné, hogy tömeges frissítést szeretne
végezni a tartalomtípusokon, futtassa ezt az SQL-töredéket:
UPDATE [dbo].[tblContentType]
SET [ModelType] = REPLACE(ModelType, ', Version=2.0.0.0,', ', Version=1.0.0.0,')
WHERE ModelType like '%, Version=2.0.0.0,%'

Ha ez a folyamat zavarosnak tűnik, a jó hír az, hogy az Episerver általában elvonatkoztatja az összes
végrehajtási részletet. Fejlesztőként nagyon ritkán fordul elő, hogy a fenti problémával találkozik. Az
esetek 99%-ában csak annyit kell tennie, hogy definiál egy osztályt és hozzárendeli a megfelelő
típusokat és attribútumokat, minden más automatikusan megtörténik a háttérben. Továbbra is képes
leszel oldalakat készíteni az Episerverben anélkül, hogy teljesen megértenéd ezt az egész elméletet. A
belső működés megértése azonban nagyon hasznos lehet, amikor később hibakeresésbe kezd a
termelési problémáknál.

Mi a Dojo
Röviden említettük, hogy a háttértípus-feloldó arra szolgál, hogy a CMS-en belül megjelenítse a
megfelelő felhasználói felületet egy tulajdonsághoz. Most egy jó pont, hogy tovább magyarázzuk,
hogyan működik ez. A renderelés a háttértípusokhoz kapcsolódó megjelenítések HTML és JavaScript
segítségével íródnak. Az Episerver sajnos egy Dojo nevű JS keretrendszert használ az aszinkron dolgok
nagy részéhez.

A Dojo keretrendszert a 2013-ban kiadott 7-es verzióban adták hozzá az Episerverhez. Amikor a V7-et
kiadták, a Dojo.js egy feltörekvő JS keretrendszer volt. Ha követi a JavaScriptet, akkor értékelni fogja,
hogy a dolgok milyen gyorsan változnak. 2013 óta a JavaScript változott... nagyon sokat. 2020-tól a
Dojo egy elavult keretrendszer. Ez dilemmát okoz nekünk, implementálóknak. Ha egyéni felhasználói
felületet szeretnénk létrehozni egy tulajdonsághoz, hogy javítsuk a szerkesztők tartalomszerkesztési
élményét, akkor meg kell tanulnunk, hogyan működik a dojo.js keretrendszer. Kivéve, ha valamilyen
örökölt szoftvert használ, soha nem kell megtanulnia a dojo-t semmi máshoz. Nem hiszem, hogy a
dojo megtanulása jó időbefektetés lenne.

Ha van egy olyan hiánypótló igénye, amelyről úgy gondolja, hogy egyedi, testre szabott tulajdonságot
kell építeni, akkor van néhány online oktatóanyag, amely segíthet Önnek. Tapasztalatom szerint,
különösen az emberek számára az Episerverrel újonnan ismerkedőknek azt javaslom, hogy felejtsék
el az egyéni tulajdonságok létrehozását a szerkesztőn belül, és maradjanak inkább a kész
tulajdonságoknál.
Blokk típusok
A blokk egy olyan komponens, amelyet a tartalomszerkesztő adhat hozzá egy oldalhoz. A blokkok
kód-első megközelítéssel is definiálhatók. A fő különbség az oldal-típus és a blokk-típus között
meghatározás között az, hogy a blokk nem az PageData, hanem a BlockData adatait örökli. A blokk
létrehozásához szükséges kód így néz ki:
[ContentType(
GUID = "29B97C2A-C4BE-4B2C-8456-C7D2E58121F7",
DisplayName = "Text Block",
Description = "A block of text with heading.")]
public class TextBlock : BlockData
{}

Helyi blokkok

Az Episerverben kétféle blokkot hozhatunk létre: globális blokkokat és helyi blokkokat. A jó hír az,
hogy mind a helyi, mind a globális blokkok ugyanúgy definiálhatók a kódban.

A két típus közötti különbség a felhasználásuk módjában van. A helyi blokk csak egyetlen oldal
számára érhető el. A helyi blokkok nem oszthatók meg oldalak között. A helyi blokk létrehozásához
keményen be kell kódolni a blokk-típus definícióját egy oldaltípus vagy egy másik blokk-típus
tulajdonságaként. Vegyük ezt a példát:
[ContentType(GUID = "A Block")]
public class MyBlock : BlockData
{}

Ahhoz, hogy ez a blokk helyi blokk legyen, keményen kódoljuk be egy oldaltípusba, például így:
[ContentType(GUID = "A Page")]
public class MyPage : PageData
{
public virtual MyBlock MyBlock { get; set; }
}

Javaslom, hogy mindig akkor használjon helyi blokkokat, ha olyan kapcsolódó tulajdonságcsoportok
vannak, amelyeket egynél több helyen kell használni. Az alábbiakban felsoroljuk a három
leggyakoribb helyi blokkot, amelyeket én ajánlom, hogy használjon a projektben:

• LinkBlock - { Name, Url, Target }


• ImageBlock - { URL, Alt Text }
• ButtonBlock - { Link, URL, Text }

A helyi blokk segít egységesíteni a szerkesztési élményt a CMS-en belül. A helyi blokk használata
biztosítja a közös típusok egységes formátumát és elnevezési konvencióját. A sharedblocks
használatával az adatok hasonló formátumot fognak követni. Például, amikor egy képet kell
megjelenítenie egy webhelyen, valószínűleg két tulajdonságot kell használnia, egy URL-t és egy alt
szöveget. Ha hozzáadja a ezeket a tulajdonságokat ad-hoc alapon, amikor egy képre van szükség, a
szerkesztő valószínűleg nem lesz következetes. Az egyik sablonon lehet, hogy a tulajdonság neve
"Url", egy másik oldalon pedig ugyanez a tulajdonság az "Url" tulajdonság neve 'ImageUrl' lehet.
Egyes oldalakon az "Alt" szöveg nevű tulajdonságot megjelenítheti, más oldalakon pedig "Alternatív
szöveg" néven.
A helyi blokkok segítenek feloldani ezeket a kisebb következetlenségeket. Először is, a helyi blokk
használatával nem sérti meg a DRY elvét. A helyi blokk használata azt jelenti, hogy elkerülheti az ilyen
ad-hoc írásokat tulajdonságokat. Ez segít csökkenteni a megírandó boilerplate kód mennyiségét.
Ennek következtében kevesebb egységtesztet is kell majd írnia. Visszatérve a képi példához

létrehozhatjuk ezt a helyi blokkot:

[ContentType(DisplayName = "Image Definition")]


public class ImageBlock : BlockData
{
[Display(Name = "Url", // description, etc..]
public virtual ContentReference Url { get; set; }
[Display(Name = "Url", // description, etc..]
public virtual string AltText { get; set; }
}

Ahhoz, hogy ez egy helyi blokk legyen, az oldaltípus tulajdonságaként kell deklarálnia, például így:
public class MyPage : PageData
{
public virtual ImageBlock Image { get; set; }
}

Az ImageBlock használata bárhol, ahol a tartalomszerkesztő képet szeretne hozzáadni, azt jelenti:

• A CMS-en belüli tulajdonságnevek mind egyezni fognak


• A CMS-en belüli tulajdonságleírások mindegyike megegyezik.
• A tulajdonságok formázása következetes lesz
• Kevesebb kódra lesz szükség a vezérlőkben.
• Kevesebb egységteszt

Jobb kód újrafelhasználás, mivel egy általános "ImageBlock" szolgáltatás létrehozható és újra
felhasználható a különböző oldalakon.

Javaslom, hogy amikor azonosít néhány kapcsolódó tulajdonságot, szánjon időt arra, hogy biztosítsa
egy helyi blokk létrehozását.

Global Blocks and Content Areas - Globális blokkok és tartalmi területek


Mint említettük, a blokkok definiálására szolgáló kód ugyanaz, függetlenül attól, hogy globális vagy
helyi blokkról van szó. A helyi blokkok úgy készülnek, hogy a fejlesztő egy blokkot keményen kódol
egy tulajdonságként egy oldalra vagy egy egy másik blokkhoz. A globális blokkokat dinamikusan
hozzák létre a CMS-en belül a tartalomszerkesztők. A globális blokkok akkor jönnek létre, amikor a
tartalomszerkesztő új blokkot hoz létre egy tartalmi területen belül. Amikor tartalmi terület
tulajdonságot definiál egy tartalomtípuson, a CMS megjelenít egy blokkválasztó komponenst. Ebből a
választóból a tartalomszerkesztő választhat az összes rendelkezésre álló blokk közül a CMS-BŐL. A
tartalom hozzáadása és az oldal közzététele után a komponens megjelenik a frontenden.

A tartalmi területet tartalmazó oldal mentésekor az Episerver hozzáadja a blokkokat a globális


blokkkönyvtárnak nevezett valamibe. A globális blokkkönyvtár hasonló a CMS fő tartalomfájához.

A különbség a kettő között az, hogy a blokk-könyvtár csak a megosztott blokkokat jeleníti meg. Mint
minden fának, a globális blokkkönyvtárnak is van egy gyökércsomópontja. Az oldalfától eltérően a
blokkkönyvtár lehet mappaszerkezet szerint szervezhető, amelynek nem kell tükröznie a webhelyek
oldalszerkezetét. A globális blokkkönyvtár a szerkesztő jobb oldali navigációs ablaktábláján keresztül
érhető el, ahogyan a következő képen látható alább látható:

Episerver editor

A blokkkönyvtár hasznos a tartalomszerkesztők számára, mivel lehetővé teszi számukra a blokkok


újrafelhasználását. Ha egy tartalomszerkesztő újra fel akar használni egy blokkot, egyszerűen
átböngészheti a blokkkönyvtárat, hogy megnézze, mi létezik.

Bár nyilvánvalónak tűnhet, hogy a blokkok újrafelhasználása időt takarít meg. A legtöbb projektben a
tartalomszerkesztők inkább új blokkok létrehozását részesítik előnyben az újrafelhasználás helyett. A
komponensek újrafelhasználása segíthet a teljesítmény töredékesen javítani. Segít továbbá a CMS-t
kevésbé deklarálttá tenni, ezért azt tanácsolnám, hogy próbálja meg a tartalomszerkesztőt a
blokkkönyvtár használatára ösztönözni. Ne tartsa lélegzetét, hogy hallgatni fognak rá!

Content Areas - Tartalmi területek

Itt az ideje, hogy mélyebben belemerüljünk a tartalmi területekbe. Először is, határozzuk meg, hogy
pontosan mi is az a tartalmi terület? A tartalmi terület egy dinamikus rács. A tartalomszerkesztők
blokkokat hozhatnak létre ezen a rácson belül. Tartalom szerkesztők rendezhetik a blokkokat a
rácson belül. A dobozból kivéve a rács csak sorokban működik. Némi extra konfigurációval a rács
beállítható úgy, hogy sorokkal és oszlopokkal is működjön, ez a következő a "megjelenítési
beállítások" nevű eszközzel érhető el.

Amikor egy blokkot hozzáadunk vagy létrehozunk egy tartalmi területen belül, az adott elemre való
hivatkozás a tartalmi terület Elemek gyűjteményében tárolódik. Amikor a tartalmi terület megjelenik
egy oldalon, az Episerver növekvő sorrendben iterálja végig az Items gyűjteményt. Az Episerver az
Items gyűjteményben található minden egyes elem esetében megkísérli meghívni a megfelelő
vezérlőt az összetevők megjelenítéséhez.

HTML. Az alábbiakban egy példa látható arra, hogyan néz ki a tartalmi terület tulajdonsága a
szerkesztőn belül:
Blocks

Egy dolog, ami talán meglepő lehet, hogy oldalakat, valamint blokkokat is hozzá lehet adni egy
tartalmi területen belül. Bármi, ami megvalósítja az IContent interfészt, használható egy tartalommal
együtt területtel. Egy oldal hozzáadása egy tartalmi területhez kissé ellentmondásosnak tűnhet.
Miért akarna egy oldalt hozzáadni egy rácson belül?

Az Episerverben nem korlátozódik arra, hogy egy oldalhoz csak egy vezérlőt társítson. Lehetőség van
több vezérlő és nézet társítására egy oldaltípushoz. Ez az Episerver varázslat a következőképpen
történik címkézéssel történik. Amikor az Episerver a tartalomterületek elemgyűjteményén belül
hozzáadott komponenseken iterál, egy speciális címke társul a kéréshez. Később, amikor az oldal
megjelenítés során ez a tag egy másik vezérlő, egy részleges vezérlő meghívására használható. Ez a
különálló vezérlő ezután különböző HTML megjelenítésére használható. A részleges vezérlők
felhasználhatók a oldalon található adatok komponensként történő megjelenítését. Ez azt jelenti,
hogy egy oldalt blokkként használhat, amikor az egy tartalmi területen belülre kerül. Okos, igaz?

Képzelje el például, hogy van egy termék adatlapja, amely segít eladni egy új hipszter sört. A kínált
sör nyilvánvalóan egy apró dobozba van csomagolva, rajta egy koponyával. Amikor a termékoldal
betöltődik, az Episerver meghívja a kapcsolódó oldalvezérlőt, és a termékoldal a várt módon
megjelenik. A tartalomszerkesztő úgy szeretné növelni a sör eladását, hogy a sörhöz kedvezményt ad,
és a főoldalon promóciót tesz közzé az ajánlatról. Az egyik lehetőség az lenne, hogy létrehoz egy új
promóciós blokkot a honlapon, amely visszalinkel a termékoldalra, és hirdeti az új árat. Ez a
megközelítés működik, de mi történik a következő hónapban, amikor a sör már nem lesz akciós. A
szöveg frissítésre szorul. Az oldalon. Ebben a felállásban a tartalomszerkesztőnek nem szabad
elfelejtenie, hogy a termékoldalon és a promóciós blokkban is meg kell változtatnia az árat. A
tartalomszerkesztő életének megkönnyítése érdekében lehetővé lehetne tenni, hogy hogy a
termékoldalt használhassa a promóció adatforrásaként.

Az oldalvezérlők és részvezérlők létrehozásához szükséges kódot később részletesen tárgyaljuk.


Egyelőre nézzünk át néhány kódot. Egy tartalmi terület tulajdonságot ugyanúgy adunk hozzá, mint
bármely más tulajdonsághoz. Hozzon létre egy nyilvános tulajdonságot. Állítsuk be a tartalom típusát
ContentArea értékre. Adjunk neki nevet és néhány metaadatot:
[Display(
Name = "Main Content Area",
GroupName = SystemTabNames.Content,
Order = 200)]
public virtual ContentArea MyContentArea { get; set; }

Egy furcsaság, amivel tisztában kell lenned, amikor tartalmi területekkel dolgozol, hogy ez két további
<div> taget jelenít meg az oldalon. Ezekre az extra címkékre az Episerver azért van szükség, hogy
lehetővé tegye a soron belüli szerkesztést. A <div> címkék arra szolgálnak, hogy egy elemet
alakítsanak ki az összes tartalmi terület elemei körül, így néhány speciális attribútumot lehet
hozzáadni az oldalhoz. Az Episerver a data-epi-property-name nevű attribútumot használja.
Attribútumot használ a soron belüli szerkesztési kód megkötésére. Az inline-szerkesztés lehetővé
teszi a tartalomszerkesztők számára, hogy közvetlenül az oldalon szerkesszék a tartalmat. Ez jobb
felhasználói élményt nyújt, mintha az admin képernyőket kellene használni. a szerkesztőn belül.

Gyakran ez a két extra <div> tag meglepheti a front-end tervezőket. Különösen, ha a HTML először
egy statikus weboldalon belül épült fel. Ezek a <div> címkékről ismert, hogy megtörik a CSS-t, a front-
end fejlesztők bánatára. Ha Chrome-ellenőrzést végeznél egy tulajdonságon, miközben szerkesztési
módban próbálnád megnézni, a visszakapott jelölés ehhez hasonlóan nézne ki:
<div data-epi-use-mvc="True" data-epi-property-name="PageName" class="epi-editContainer">
My Page Title
</div>

Mint látható, a data-epi-use-mvc és a data-epi-property-name mindkettőt automatikusan hozzáadja


a tartalmi terület. A név lehetővé teszi a szerkesztő számára, hogy a dojo.js segítségével helyesen
kösse meg a tulajdonságot. Ön láthatja az inline-szerkesztést működés közben az ötvözet
mintaoldalán. Amikor az egeret egy szerkeszthető tulajdonság fölé viszi, megjelenik egy színes doboz.
A dobozra kattintva a szerkesztő frissítheti a tartalmat. Ne feledje, az inline-szerkesztés csak olyan
tartalomszerkesztők számára érhető el, akik bejelentkeztek az Episerverbe, és érvényes
munkamenettel rendelkeznek. A normál, nem hitelesített webhelylátogatók nem férnek hozzá a
soron belüli szerkesztéshez.

Ha nem szeretné, hogy a tartalmi terület megjelenítse az extra <div> címkéket, akkor ez is lehetséges.

First, it is possible to override the default elements a tartalomszerkesztő megjeleníti.

Beállítható például, hogy egy <ul> taget jelenítsen meg helyette. A tag típusának megváltoztatásához
átadhat néhány további paramétert a kódban, ahol a tartalmat rendereli, területet, például így:
@Html.PropertyFor(x => Model.ContentArea, new
{
CustomTag = "ul",
CssClass = "list",
ChildrenCustomTagName = "li",
ChildrenCssClass = "list_item",
Tag = string.Empty
})

Ebben az esetben a két <div> címke helyett a tartalmi terület ezt a HTML-t jelenítené meg:
<ul class="list">
<li class="list_item"></li>
</ul>

A külső címke típusát a CustomTag tulajdonság határozza meg. A belső címke típusát a
ChildrenCustomTagName tulajdonság határozza meg. Bármilyen értéket hozzáadhat.

ebben a kódban, mivel nem történik érvényesítés. A segédprogramba átadott értékeknek nem is kell
érvényes HTML-elemet képviselniük. Nagyon furcsa lenne, ha nem egy érvényes HTML-elemet, de a
választás a tiéd. Ha követte az ajánlásomat, és statikus HTML-verziója van a weboldalnak. Győződjön
meg róla, hogy a statikus webhely figyelembe veszi ezeket az extra címkéket.
A div címkék eltávolításának másik módja, hogy teljesen megakadályozza a renderelésüket a ermelési
módban. Ez egy olyan egyéni tartalmi terület renderelő bevezetésével lehetséges, amely kihagyja a
őket. Az ehhez szükséges kód több oldalra fog kiterjedni, és könyv formátumban nem lenne
olvasható. Azoknak, akiket érdekel, mellékeltem egy linket egy általam írt bemutatóhoz, amely
részletesen ismerteti a következőket hogyan lehet ezt megtenni a gyakorlatok részen belül.

Validation Within Content Areas - Tartalmi területeken belüli érvényesítés


A tartalmi terület tulajdonság lehetővé teszi a tartalomszerkesztők számára, hogy oldalakat építsenek
egy rácson belül egymásra helyezett komponensekből. A tartalomszerkesztés szempontjából ez
nagyszerű. A szerkesztők kreatívabbak lehetnek, és kevésbé támaszkodhatnak a fejlesztőcsapattól,
hogy dinamikus elrendezésű oldalakat építsenek a weboldalon belül. Mint a klasszikus SpiderMan
idézet, nagy hatalommal, valami felelősséggel és spandex ruhával, azt jelenti, hogy a
tartalomszerkesztők most sokkal nagyobb valószínűséggel törnek össze dolgokat.

Képzelje el, hogy létrehoz egy 'contact-us' blokkot, és feltételezi, hogy azt csak a 'contact-us' oldalon
fogja használni. A tartalomszerkesztő másképp gondolkodik, és a "kapcsolatfelvétel" blokkot a
honlapra. Ez megtöri a kezdőlapok reszponzív elrendezését. Annak megakadályozására, hogy a
blokkokat nem várt módon használják vissza, általában néhány érvényesítést szeretne hozzáadni a
tartalmi területhez.

Az Episerver számos készleten kívüli attribútumot biztosít ehhez. A két legfontosabb a


RestrictedTypes és az AllowedTypes:

Az AllowedTypes egy átfogó lista az összes olyan típusról, amelyet a tartalomszerkesztők az adott
tartalmi területen belül használhatnak.
[AllowedTypes(new []{ typeof(MyBlock) })]
public virtual ContentArea MainContentArea { get; set; }

A RestrictedTypes az ellenkező viselkedést biztosítja. A RestrictedTypes egy fekete listás szűrő


létrehozására szolgál. Meghatározza az összes olyan blokkot, amelyet egy adott tartalmi területen
nem szabad használni.

[RestrictedTypes = new[] { typeof(MyBlock) }]


public virtual ContentArea MainContentArea { get; set; }

A két lehetőség közül a RestrictedTypes attribútumot tartom hasznosabbnak. A legtöbb helyzetben


általában meg akarja akadályozni, hogy bizonyos blokkokat bizonyos helyeken használjon.

A fő probléma, amit az attribútumok tartalmi területenkénti alkalmazásával kapcsolatban


tapasztaltam, az, hogy a karbantartás nehézkes lehet. Miután a webhely elindult, és új blokk-típusok
kerülnek a CMS-be, a kódban mindenhol emlékeznie kell arra, hogy korlátozni akarja az új blokk
megjelenését. Bizonyos esetekben sokkal egyszerűbb, ha egy globális házirendben engedélyezzük
vagy korlátozni a blokkokat.

Egy ilyen házirend létrehozása néhány okos kódolással elvégezhető. Először is definiáljon egy
szűrőként használandó felületet. Ezt az interfészt úgy hívhatjuk, ahogyan csak akarjuk. Ebben a
példában a következő nevet adtam neki IContentAreaRestricted:

public interface IContentAreaRestricted


{}
Az interfész definiálásával ezután bármely olyan blokkra implementálható, amelyet el akarunk rejteni
a tartalmi területről, például így:

public class MyBlock : IContentAreaRestricted


{}

Ha a korlátozást egy tartalmi területre szeretné alkalmazni, akkor az IContentAreaRestricted-t


adhatja meg típusként, például így:
[RestrictedTypes = new[] { typeof(IContentAreaRestricted) }]
public virtual ContentArea MainContentArea { get; set; }

Egy új blokk létrehozásakor egyszerűen feldíszítheted IContentAreaRestricteddel, és az Episerver meg


fogja akadályozni, hogy a blokkot bármely olyan tartalmi területen használhassa, ahol átadod a
megfelelő interfészt korlátozott típusként adja meg.

Egy interfész ilyen módon történő hozzáadása a RestrictedTypes-hez egy olyan furcsasággal jár,
amely renderelési problémát okoz. A támogató típusfeloldó nem fogja megérteni, hogyan kell
feldolgozni az interfészt, és hibát fog dobni. A címre megelőzni ezt a hibát, egy egyéni
UIDescriptorRegisztrációra lesz szükség. Az UIDescriptorRegistration megmondja az Episerver
háttértípus-feloldónak, hogy hogyan lépjen kapcsolatba a típussal. Példánkban nincs szükségünk arra,
hogy a szerkesztő bármit is megjelenítsen, így megúszhatjuk egy üres descriptor deklarálásával. Ezt a
következőképpen érjük el:

[UIDescriptorRegistration]
public class ContentAreaRestrictedDescriptor : UIDescriptor<IContentAreaRestricted>
{}

A blokkok globális kezelése sokkal egyszerűbbé teszi a karbantartást, ezért javaslom, hogy alkalmazza
ezt a mintát.

Display Options - Megjelenítési lehetőségek


A tartalmi terület beállítható úgy, hogy a rácsot sorok és oszlopok használatával is megjelenítse. A
sorok határozzák meg az összetevők egymásra helyezését. Az oszlopok határozzák meg a
komponensek szélességét. soron belül. Az "oszlop" kifejezést nagyon lazán használom, a komponens
szélessége soronként kerül meghatározásra, nem pedig a tartalmi terület egészére. Ha a
tartalomszerkesztőnek lehetővé tesszük, hogy meghatározza a komponens szélességét, az nagyon jó.
A hátránya az, hogy ez némi extra komplexitást ad a keverékhez. Egyéni kódra lesz szükség ennek a
funkciónak a támogatásához. Ezenkívül több tesztelési időt a projekttervben, mivel a blokkok sokkal
többféleképpen konfigurálhatók.

Az "oszlopok" üzemmód engedélyezéséhez engedélyeznie kell egy úgynevezett "megjelenítési


opciót". Az Alloy mintaoldalon a megjelenítési opciók engedélyezve vannak. Ezek a megjelenítési
opciók a következőkhöz kapcsolódnak az aláfestő rácskerethez, amelyet a webhely CSS-e használ. Az
üres mintaoldal nem tartalmaz semmilyen HTML-t, ezért nem tartalmaz megjelenítési opciókat.

Az ok, amiért a megjelenítési opciók alapértelmezés szerint nincsenek automatikusan beépítve,


egyszerű. Amikor az Episerveren belül készít egy webhelyet, az összes CSS megírásáért ön lesz felelős.
Ez lesz a csapat döntése, hogy melyik reszponzív rácsos keretrendszert szeretné használni. Az Ön által
választott rácskeretrendszer ezután befolyásolja majd a megjelenítési lehetőségeket, amelyeket be
kíván építeni. Megjelenítés opciókat nagyon sokféleképpen lehet meghatározni, és a választott grid
keretrendszerhez vannak kötve. Mivel az Episerver keretrendszer-független, a megjelenítési opciókat
a megvalósítók maguk adhatják hozzá.

Ha nem biztos abban, hogy melyik rácskeretet használja, az én ajánlásom a következő: CSS-grid a
purista CSS-rajongók számára. Bootstrap, azok számára, akik inkább egy keretrendszert használnak.
Az alábbiakban a megjelenítési opciókat mutatjuk be amelyek az Alloy mintaoldalon belül vannak
definiálva.

Mindezeknek a megjelenítési lehetőségeknek értelmet kell adniuk. Nyilvánvalónak kell lennie, hogy a
teljes, a széles, a fél és a keskeny mit jelent. Annak ellenére, hogy annyi megjelenítési lehetőséget
hozhat létre, amennyit csak akar és elnevezheti őket, ahogyan csak jónak látja, én az Alloy-ban
használt egyezményt használom.

Minden egyes megjelenítési opciót le kell rendelni egy CSS-osztályhoz. Ha a Bootstrap-et használja a
rácskerethez, akkor a megjelenítési opciókat a következő megjelenítési opciókhoz rendelheti:

• Full → lg-12
• Wide → lg-9
• Half → lg-6
• Narrow → lg-3

A Bootstrap 12 oszlopos rácsrendszert használ. Egy teljes szélességű komponenst a 12 oszlopos


osztállyal kell megjeleníteni. Egy félszélességű komponens a 6 oszlopos osztályt kapná. Ha a tartalom
szerkesztő két olyan komponenst szeretne létrehozni, amelyek ugyanabban a sorban jelennek meg, a
teljes oszlopszélességnek 12-re kellene összeadódnia, tehát egy 6-os és egy 6-os. Egyszerű. Ha a
tartalomszerkesztők dönthetnek a komponensek szélességéről, az elrendezési problémákat okozhat.
Mi történik, ha a tartalomszerkesztő véletlenül úgy állítja be a megjelenítési beállításokat, hogy azok
meghaladják a 12-t? Ez túllépi a maximális oszlopszélességet 12-ben, mi történik? Az asztali
számítógépen ez rendben van. Mobilon viszont nagyon töröttnek tűnhet. Ha már a mobilról
beszélünk, mi történik, ha a tervezők azt szeretnék, hogy a mobil egyféleképpen viselkedjen, és az
asztali számítógép másképp viselkedjen? Gyakran nincsenek tiszta vagy egyszerű megoldások a
renderelési problémák némelyikére, amelyekkel a projekted során találkozhatsz. Néhány gyakori
megoldás ezekre a problémákra:

Egy sorblokk - A row block: Ebben a konfigurációban egy olyan blokk jön létre, amely egy tartalmi
területet tartalmaz, és semmi mást. A blokk teljes célja a grid által megkövetelt kódoló div tag
hozzáadása. A szülő tartalmi terület úgy van beállítva, hogy azon belül csak sorblokkok hozhatók
létre. A sorblokk olyan érvényesítéssel jön létre, amely biztosítja, hogy a benne hozzáadott elemek
nem haladhatják meg a 12 oszlopot.

Egy adott blokk, amely mindkét elemet megjeleníti ( A specific-block that renders both items):
Ahelyett, hogy a tartalomszerkesztő a megjelenítési beállítások segítségével építené fel a
komponenst, létrehozhat egy blokkot, amely mindkét komponenst megjeleníti. Csak azért, mert

egy terv 50/50 arányú felosztást mutat, nem jelenti azt, hogy megjelenítési opciókat kell használnia.
Ez a megközelítés kevésbé rugalmas, de könnyebben kezelhető a rács.

EPiBootstrapArea: Ha bootstrap-et szeretne használni, és minimális gonddal szeretné megvalósítani


a megjelenítési opciókat, akkor ajánlom figyelmébe az EPiBootstrapArea-t. Ez a plug-in biztosítja
bootstrap-tudatos tartalmi területet biztosít. Ez azt jelenti, hogy az összes megjelenítési opciót és a
megfelelő bootstrap osztályok megjelenítéséhez szükséges HTML-t varázslatos módon elintézi neked.
Ha úgy dönt, hogy engedélyezi a a saját megjelenítési beállításait, akkor a folyamat meglehetősen
egyszerű, azonban a kód eléggé bonyolult. Több fájlt kell létrehoznia több helyen a kódbázisában.
Ehhez ezért nem sok haszna lenne, ha a kódot ide beillesztenénk. A kód több oldalra terjedne ki, és
nehezen követhető lenne. A lépések, amelyeket követnie kell a megjelenítési opciók
engedélyezéséhez a weboldalon belül a következők:

• Az alkalmazás indításakor hozzon létre egy osztályt, amely regisztrálja a megjelenítési


opciókat.
• A kapcsolódó vezérlőn belül díszítse a vezérlőt egy megjelenítési opciós címkével.
• Használja ezt a taget annak eldöntésére, hogy melyik nézetet kell meghívni.
• Hozzon létre különböző nézeteket a különböző méretekhez

A megjelenítési beállítások konfigurálásához a Githubon található egy mintaweboldal, a


JonDJones.Episerver.BaseBuild, amelyet letölthetsz, hogy láss mindent, amit tenned kell. Én is
mellékeltem egy linket a források részben, amely végigvezeti a folyamaton.

Creating Web Pages Within Episerver - Weboldalak létrehozása az Episerverben


Ebben a fejezetben megtanulja, hogyan lehet az Episerver CMS-en belül tárolt tartalmat renderelni és
weblapon megjeleníteni. Az Episerver a Microsoft ASP.NET keretrendszerére épül. A webes
alkalmazások ASP.NET használatával történő építésének ajánlott módja a Model-View-Controller
(MVC) paradigma követése. Ez a tanács akkor is igaz, amikor Episerver oldalakat építünk. A jó hír az
tapasztalt .NET-fejlesztők számára az, hogy az Episerver-tartalom MVC használatával történő
megjelenítésének folyamata nagyon hasonló ahhoz, ahogyan az oldalakat a vanília .NET MVC
munkafolyamatot követve megjelenítenénk.

Az MVC-vel még nem ismerkedők ne féljenek. Az MVC architektúra meglehetősen egyszerűen


elsajátítható. Az MVC egyszerűen egy ajánlás arra, hogyan kell a kódot úgy strukturálni, hogy az
rugalmas és könnyen kezelhető legyen. karbantartható. Egy MVC alkalmazáson belül a kód három
logikai részre oszlik. Ezek a részek három fájlhoz kapcsolódnak, amelyeket létre kell hoznia: egy
nézet, egy vezérlő és egy modell. Mivel az Episerver kód-első megközelítést használ, az előző
fejezetben generált oldal típusú osztály kulcsfontosságú összetevője lesz ennek a folyamatnak.
Minden egyes tartalomtípushoz, amelyet definiál, a következőkre lesz szüksége létrehozni egy
megfelelő vezérlőt. Minden egyes vezérlőn belül meg kell szereznie a HTML megjelenítéséhez
szükséges összes adatot. Ha bármilyen egyéni kódot kell írnia az adatok megszerzéséhez, akkor ez a
hely, ahol azt hozzá kell adni. Ezeket az adatokat egy modellbe csomagoljuk, amely aztán a nézetbe
kerül. A nézet az a fájl, ahol a HTML hozzáadásra kerül. Egyelőre tegyük fel, hogy az oldal-típusú
osztály lesz modellként használjuk, amely a vezérlőből a nézetbe kerül. Később mélyebben
elmélyedünk abban, hogy ez a legjobb megközelítés-e. Egyelőre csak végigvezetem önöket a
végponttól a végpontig. végéig tartó utat. Ezután belemehetünk a legjobb gyakorlatokba.

Az Episerver határozottan rendelkezik néhány furcsasággal, amikor a tartalom útválasztásáról és


megjelenítéséről van szó. Az összes Episerver útválasztási varázslatot később ebben a könyvben
fogjuk megismerni. Egyelőre csak bízzon abban, hogy amikor egy vezérlőt egy tartalomtípushoz
társítasz, az Episerver mindent összeköt neked. Amikor az oldal kérése megtörténik, nem kell
semmilyen útválasztást elvégeznie ahhoz, hogy a vezérlő a meghívásra kerüljön!

A különböző típusú vezérlőkkel kapcsolatos összes árnyalat és lehetőség megértése., a különböző


nézetmodell minták, és a CMS adatok megjelenítésének módja egy nézetben nagyon fontos. Ebben a
fejezetben, minden egyes elembe mélyen bele fogunk merülni. Az Episerverrel használható
különböző típusú vezérlők összehasonlításával kezdjük.

Page Controllers - Oldalvezérlők


Ha olyan CMS oldalt próbált megnézni a weboldalon, amelyhez nem lett beállítva megfelelő
oldalvezérlő, akkor hibaüzenet jelenik meg. 404, az oldal nem található hiba fog jelentkezni. Egy
megfelelő vezérlő vagy nézetfájl nélkül a renderelő csővezeték nem tudja, hogyan dolgozza fel a
bejövő oldalkérést. Az oldalvezérlő célja, hogy minden bejövő kérést eltérítsen a adott
tartalomtípust, és a renderelés felelősségét átadni nekünk. Egy vezérlő action metódusán belül
egyéni logikát adhatunk hozzá. Fejlesztőként a mi felelősségünk, hogy az összes a HTML
megjelenítéséhez szükséges adatokat, eldöntsük, hogy melyik nézetfájlt kell betölteni, mielőtt végül
visszaadjuk a vezérlést a renderelő csővezetéknek.

A nagy különbség az Episerver MVC-vel való munka során a vanilla MVC-hez képest a használt
alaposztályok és attribútumok. Egy normál MVC alkalmazásban az alaptípus, amelyet egy Controller
néven fut. Az Episerverben az oldalakkal való munka során az új alaptípus, amelyet használni kell, a
PageController<T>.

PageController

A PageController egy speciális Episerver alaposztály, amely az Episerver.Core összeállításban


található. A PageController<T> generikusokat használ, ahol T az az oldaltípus, amelyet a vezérlőhöz
társítani szeretnénk. Ahhoz, hogy egy oldaltípust társítson egy vezérlőhöz, a következő lépéseket kell
követnie:

• Hozzon létre egy új osztályt, és nevezze el {PAGE-TYPE-NAME}Controller-nek.


• Az osztályon belül örökölje a PageController-t.
• Adja át a regisztrálni kívánt oldaltípust <T>-ként.
• Hozzon létre egy action metódust a bejövő kérés kezelésére.
• Használja az oldal-típust az action metódus első argumentumaként.
Az alábbiakban egy alapvető példa látható arra, hogyan kell kinéznie egy Episerver vezérlőnek:

public class HomepageController : PageController<Homepage>


{
public ActionResult Index(Homepage currentPage)
{
return View("Homepage", currentPage);
}
}

Ebben a példában, feltételezve, hogy a kódot sikeresen lefordítottuk. Amikor egy Homepage típusú
oldalra érkezik egy kérés, az alapértelmezett Index action metódus kerül meghívásra. A action
metóduson belül az oldal típusa átadásra kerül a 'View'-nak. A nézet neve ebben az esetben
'Homepage.cshtml', és a 'View' mappában kell lennie.

Block Controller - Blokk vezérlő

A blokkvezérlő célja és a tulajdonságai nagyon hasonlóak a PageControlleréhez. A blokk renderelési


kéréseket az Episerver mindig akkor teszi meg, amikor egy tartalmi területet elemez. A oldalon
elméletileg nem kell minden egyes blokkhoz külön vezérlőt létrehozni. Mivel a blokkok részlegesek,
elméletileg lehetséges lenne egyetlen általános blokkvezérlőt létrehozni, amely az összes blokkot
képes feldolgozni.

Tapasztalataim szerint egyetlen hatalmas blokkvezérlőre támaszkodni nagyon rossz ötlet. A vezérlő
hamarosan istenosztály lesz. Ami azt jelenti, hogy olyan nagy és összetett lesz, és olyan sok dolgot,
hogy nehéz lesz megérteni és nehéz lesz karbantartani.

Azt javaslom, hogy mindig hozzon létre egy blokkvezérlőt minden olyan blokkhoz, amelyet globális
blokkként fog használni a megoldáson belül. Ha ezt a tanácsot követi, a megoldás következetes
kialakításnak megfelelően. A konzisztencia előnye, hogy maximalizálja a fejlesztői hatékonyságot. Ha
a tervezés nem konzisztens, akkor a projekt minden egyes fejlesztőjének időt kell töltenie az összes
projekt sajátosságait és árnyalatait. Ez értékes időt emészt fel.

A blokkvezérlő létrehozásához szükséges kód nagyon hasonlít a lapvezérlő kódjához. A nagy


különbség az, hogy nem PageController<T>, hanem BlockController<T> kódból örökölünk.
public class TextBlockController : BlockController<TextBlock>
{
public override ActionResult Index(TextBlock currentBlock)
{
return PartialView("Index");
}
}

Partial Controller - Részleges vezérlő

Az utolsó tárgyalandó Episerver vezérlő a PartialContentController<T>. Ahogy az előző fejezetben


említettük, az Episerver tartogat egy meglepetést. Bármi, ami megvalósítja az IContent interfészt.

egy tartalmi terület belsejébe adható és blokkként kezelhető. A részleges vezérlőket főleg akkor
használjuk, ha egy tartalmi területen belül egy oldaltípus hozzáadását szeretnénk lehetővé tenni.
Amikor egy oldalt adunk hozzá egy tartalmi területen belül. Az Episerver többé nem próbálja
meghívni az alapértelmezett oldalvezérlőt. Ehelyett az Episerver először megpróbál megkeresni egy
megfelelő részleges vezérlőt, amely már az aktuális típushoz társított vezérlővel. A
PartialContentController<T> nagyon hasonlóan működik, mint az oldal- és a blokkvezérlő. Először is,
örökölje az alap PartialContentController<T> osztályt, átadva az oldal-típust T-ként. Ezután írja felül
az alapértelmezett index metódust, és konfigurálja azt szükség szerint. Végül pedig egy speciális
attribútumot kell alkalmaznia a vezérlőhöz, a TemplateDescriptor.
[TemplateDescriptor(Tags=new string[]{"Homepage"})]
public partial class HomepagePartialController : PartialContentController<Homepage>
public override ActionResult Index(Homepage currentContent)
{
return base.Index(currentContent);
}
}

Mindezzel a helyén, amikor egy tartalmi területen belül egy Homepage típusú oldal kerül
hozzáadásra, ez a részleges vezérlő meghívásra kerül. Ez lehetővé teszi a különböző HTML
megjelenítését a tartalmi területet.

HTML

Az MVC architektúrában történő munkavégzés során a HTML egy nézeten belül íródik. A nézet az
MVC V része. Minden vezérlőnek szüksége van egy megfelelő nézetre. A nézeteknek a "view"
mappában kell létrehozni a webrootban. A nézet mappa helye fontos. Az alapértelmezett ASP.NET
MVC keretrendszer előre megírt szabályokkal rendelkezik, amelyek elvárják, hogy a nézetek a
következő helyen legyenek ebben a mappában legyenek. Erősen ajánlom, hogy ne próbáljon eltérni
ettől a megközelítéstől. A nézetek máshová történő hozzáadása több gondot fog okozni, mint
amennyit megér.

Egy másik építészeti döntés, amit meg kell hoznia, hogy hogyan strukturálja a fájlokat és mappákat a
"view" mappán belül. Ha megnézi a nézetek mappát az Alloy demo weboldalon belül észreveheti,
hogy a fájlok elég rosszul vannak megszervezve. Ha egy mappa túl sok fájlt tartalmaz, az akadályozza
a csapatot, amikor megpróbálnak megtalálni egy nézetet. Ha részleges vagy megjelenítési opciókat
használ, akkor mind az oldalak, mind a blokkok több nézetet igényelhetnek. Ez csak súlyosbítja a
rendetlenség problémáját.

Ahelyett, hogy egyszerűen mindent a "nézet" mappába dobna, azt javaslom, hogy a nézeteket
mappák szerint rendszerezze. A 'view' mappán belül hozzon létre egy 'pages' nevű mappát, egy
másikat 'partials' néven, és egy utolsó, 'blocks' nevű mappát. Minden új oldalhoz, részlegeshez vagy
blokkhoz hozzon létre egy új megfelelő mappát, amely megfelel a tartalomtípus nevének a megfelelő
mappában. Ez a technika lehetővé teszi az összes az adott típushoz tartozó nézetek ugyanabban a
mappában legyenek elhelyezve.

Visszatérve a honlap példához, hozzon létre egy új mappát 'Homepage' néven az 'Pages' mappán
belül, a 'Views' mappán belül. Az új mappában hozzon létre egy új nézetet 'index.cshtml' néven. A fájl
neve azért 'index', mert megfelel a vezérlőben definiált művelet nevének. Ennek a megközelítésnek a
használata azt jelenti, hogy nem kell megadnia a nézet fájlnevét a vezérlőt, ami némi gépelést takarít
meg:
public ActionResult Index(Homepage currentPage)
{
return View(currentPage);
}

Ha ezt a megközelítést alkalmazza, a mappaszerkezet így fog kinézni:


view/
| |- Homepage/
| |- index.cshtml

Az egyik probléma ezzel a megközelítéssel az, hogy az alapértelmezett renderelőmotor nem fogja
tudni, hogy mostantól ezekben az új mappákban kell keresnie a nézeteket. Ennek kijavításához létre
kell hoznia egy és egy regisztrálni egy egyéni nézetmotor. Sok fejlesztő általában nem tudja, hogy
testre szabhatja a nézetmotort, pedig ez egy standard MVC funkció, amelyet könnyű megvalósítani.
ViewEngines - ViewEngines

Egy olyan egyéni RazorViewEngine létrehozásához, amely a fent vázolt struktúrával működik, egy
osztályt kell definiálnod a projekteden belül, például így:

public class CustomViewEngine : RazorViewEngine


{
public CustomViewEngine()
{
var viewLocations = new[]
{
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Partials/{0}.aspx",
"~/Views/Partials/{0}.ascx",
"~/Views/Partials/{0}.cshtml",
"~/Views/Pages/{1}/{0}.cshtml",
"~/Views/Blocks/{1}/{0}.cshtml"
};
PartialViewLocationFormats = viewLocations;
ViewLocationFormats = viewLocations;
}
}

A fenti kód remélhetőleg könnyen érthető. Örökölje a RazorViewEngine. A konstruktoron belül


definiáljuk a mappák listáját, amelyeket a nézetmotornak át kell vizsgálnia, hogy megtalálja a
megfelelő nézeteket. Állítsa be a PartialViewLocationFormats és a ViewLocationFormats értékeket a
lista használatához.

Végül regisztrálja az egyéni nézetmotort az alkalmazás indításakor a global.ascx fájlban, a


következőképpen:

public class EPiServerApplication : EPiServer.Global


{
protected void Application_Start()
{
ViewEngines.Engines.Insert(0, new CustomViewEngine());
}
}
HTML írása

Végül itt az ideje, hogy írjunk egy kis HTML-t. Az alábbiakban egy nagyon egyszerű példát mutatunk
arra, hogyan lehet egy CMS tulajdonságot megjeleníteni egy oldalon:
@model Homepage
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="page-heading">
<h1>
@Html.PropertyFor(x => x.PageTitle)
</h1>
</div>
</div>
</div>
</div>

Ebben a példában a Homepage oldaltípust használjuk a nézet modelljeként. Ezt a modellkötést az


első sorban definiáljuk. Ha egy modell ilyen módon van kötve, akkor használhatja a intelliSense-t a
nézeten belül, hogy megtudja, milyen tulajdonságokat biztosít a modell.

MEGJEGYZÉS Az oldal-típus közvetlen átadása egy nézetbe ilyen módon anti-mintázat, és kerülendő.
Ehelyett adjon hozzá egy absztrakciós réteget, és adjon át egy külön nézeti modellt. Én egy page-
típust használok a modellhez ebben a példában csak az egyszerűség és az áttekinthetőség kedvéért.
A nézetbe történő adatátadás különböző módjairól később lesz szó.
PropertyFor()

Egy Episerver tulajdonság megjelenítéséhez egy nézeten belül az Episerver PropertyFor()


segédprogramot használjuk. A PropertyFor() nagyon rugalmas, és bármilyen Episerver tulajdonság
megjelenítésére használható, függetlenül annak típusától. Vegyük például ezt a két tulajdonságot:

[Display(Name = "Title",
GroupName = SystemTabNames.Content,
Order = 10)]
public virtual string PageName{ get; set; }
[Display(
Name = "Main Body",
GroupName = SystemTabNames.Content,
Order = 20)]
public virtual ContentArea MainBody{ get; set; }

A nézeten belül mindkét tulajdonság átadható a PropertyFor() segédprogramnak, és mindkettő


ennek megfelelően kerül feldolgozásra, a következőképpen:
<div>
@Html.PropertyFor(x => x.PageName)
@Html.PropertyFor(x => x.MainBody)
</div>

A motorháztető alatt a PropertyFor() különböző logikát használ a különböző típusok


megjelenítéséhez. Ez azt jelenti, hogy másképp fog viselkedni attól függően, hogy milyen
tulajdonságtípust adunk át neki. A logika a primitív típus - például egy karakterlánc vagy egy szám -
megjelenítése úgy fog működni, ahogyan azt elvárnánk tőle. Az összetettebb tulajdonságok, például
egy tartalmi terület megjelenítésének logikája bonyolultabb.

Ha a PropertyFor() funkciót egy tartalmi terület kontextusában használjuk, akkor a tartalmi terület
elemgyűjteményének minden egyes elemét elemezni kell, és más munkafolyamatra lesz szükség a
következőkhöz az egyes elemek HTML-jének lekérdezése. A primitív típusok esetében a PropertyFor()
megkerülése és helyette a tulajdonság közvetlen megjelenítése lehet a megoldás, például így:
@Model.PageName

Ne tegye ezt. Ha ezt teszi, akkor a CMS-en belüli sorszerkesztési funkció nem fog működni. Feltéve,
hogy az aktuális kérelem "szerkesztési módban" van beállítva. A PropertyFor() segédprogram is
alkalmazni fogja a megfelelő Episerver attribútumokat, amelyekre a CMS-nek szüksége van a soron
belüli szerkesztéshez. Ha egy tulajdonságot közvetlenül egy nézetben jelenít meg, akkor a két inline
szerkesztési attribútum nem kerül hozzáadásra. Ennek eredményeképpen az inline szerkesztés nem
fog működni. nem fog működni.

PropertyFor() és Rich-text

Az XHtmlString tulajdonság lehetővé teszi a tartalomszerkesztő számára, hogy gazdag szöveget adjon
az oldalhoz. Nem vagyok nagy rajongója a "gazdag szöveg" kifejezésnek. A rich-text tulajdonságnak
semmi köze nincs a nettó értékéhez egy darabka adathoz. Ehelyett olyan tartalomról van szó,
amelyet egy szövegszerkesztő segítségével adunk hozzá a CMS-hez.

Az Episerver által használt szövegszerkesztő neve TinyMCE. A TinyMCE nem egy Episerver-specifikus
komponens. A TinyMCE egy harmadik féltől származó szövegszerkesztő, amelyet az Episerver licencel
és használ a saját termékét. A TinyMCE-szerkesztő - a cikk megírásának időpontjában - a legszélesebb
körben elfogadott webes szövegszerkesztő a világon. Ez egy nagyszerű termék, és jó választás az
Episerver számára.

Ne felejtse el használni a PropertyFor() funkciót, amikor egy XhtmlString tulajdonságot renderel egy
nézeten belül. Ha elfelejti, akkor a kimenet nem lesz helyesen renderelve. Például minden belső
linket oldalakra mutató linkeket az Episerver belső formátumában fogja megjeleníteni, nem pedig
egy szép, webbarát URL-ben.
PropertyFor() And Content Areas

A PropertyFor()-nak egy kicsit keményebben kell dolgoznia, amikor egy tartalmi terület
megjelenítéséről van szó. Amikor tartalmi területet definiál egy oldalon, a tartalomszerkesztők
potenciálisan többféleképpen is képesek lesznek dolgokat:

• Bármilyen alkalmazható blokkot/oldalakat ráhúzhat


• A komponensek szélességének beállítása a megjelenítési beállítások segítségével
• Látogatói csoportok alkalmazása
• A/B tesztek alkalmazása

MEGJEGYZÉS A látogatói csoportok és az A/B tesztelés később kerül tárgyalásra. A kíváncsiak számára
a látogatócsoportok lehetővé teszik a tartalomszerkesztők számára, hogy személyre szabott
tartalmat hozzanak létre. A személyre szabott tartalom egyik példája lehet csak akkor jelenítsünk
meg egy blokkot, ha a webhely látogatója hitelesített a webhelyen.

Mint korábban említettük, amikor a PropertyFor() segédprogramot használjuk egy tartalmi terület
megjelenítésére, a program végigmegy a tartalmi terület Items gyűjteményében található összes
elemen. Minden egyes elem esetében, PropertyFor() reflexiót használ az elem megfelelő
vezérlőjének meghatározásához. Az egyes elemek HTML-jének lekérdezéséhez egy következő HTTP-
kérés történik az elemekhez kapcsolódó elemekhez.

vezérlőhöz. Ezek a kérések szinkronban történnek, így a tartalmi terület összes elemét elemezni kell,
mielőtt az oldal megjeleníthető lenne.

Ha az elemnek nincs megfelelő vezérlője, akkor hibaüzenet jelenik meg. Ez a hiba akár az egész oldalt
is leállíthatja! Ennek megakadályozására az egyik módja, hogy létrehozzunk egy egyéni
IContentRenderer. Ezt a következő kóddal lehet megvalósítani:
public class ErrorHandlingContentRenderer : IContentRenderer
{
private readonly MvcContentRenderer _mvcRenderer;
public CustomContentRenderer(MvcContentRenderer mvcRenderer)
{
_mvcRenderer = mvcRenderer;
}
public void Render(
HtmlHelper helper,
PartialRequest partialRequestHandler,
IContentData contentData,
TemplateModel templateModel)
{
try
{
mvcRenderer.Render(helper, partialRequestHandler, contentData, templateModel);
}
catch (Exception ex)
{
// Deal With It
}
}
}

Ezt a kódot ezután regisztrálni kell a StructureMap segítségével (szintén később), így:
container.For<IContentRenderer>().Use<CustomContentRenderer>();

Az Episerverben nem kell használni a szokásos .NET segédprogramot HTML.Render(). Ehelyett mindig
emlékezzen a PropertyFor() használatára. A PropertyFor() sokkal egyszerűbbé teszi a fejlesztést. Mint
fejlesztő, a tiszta HTML megírására koncentrálhat. A PropertyFor()-ba bármilyen típust átadhat, és
bízhat abban, hogy az Episerver elvégzi a nehéz munkát Ön helyett.

View Model Patterns


Ez a szakasz a különböző megközelítéseket tárgyalja, amelyeket akkor alkalmazhatunk, amikor egy
modellt egy vezérlőből egy nézetbe adunk át. A legegyszerűbb lehetőséggel kezdünk, ami az oldal-
típus(page-type) közvetlen átadása a nézetbe.

@model Homepage
<div>
@Html.PropertyFor(x => x.PageName)
</div>

Bár ez a legegyszerűbb megközelítés, nem ajánlom, hogy ezt az utat kövesse. Ha az oldaltípusú
modellt közvetlenül egy nézetbe adja át, akkor ezekkel a problémákkal fog szembesülni:

• A nézet végül renderelési logikát fog tartalmazni


• A nézeteken belüli logika nem egységtesztelhető.
• Ha megjelenítési opciókat használsz, akkor megsérted a DRY elvet, mivel a logikát minden
egyes nézet között másolni kell majd

Ezt a kód-halmazt kiküszöbölheti egy nézeti modell használatával. A nézetmodell egyszerűen egy
objektum, amely közvetítőként működik az Episerver vezérlő és a nézetfájl között. Amikor a a nézeti
modellek használatához három fő megközelítés létezik, amelyeket az évek során projektekben láttam
használni. Ezek a következők:

• Hibrid nézetmodell minta: Egy modell, amely tartalmazza az Episerver oldalobjektumot és a


nézeten belül szükséges további tulajdonságokat.
• Dedikált nézetmodell minta: Olyan modell, amely csak a nézet által igényelt tulajdonságokat
tartalmazza.
• Összetett nézeti modellminta A nézet két objektumot kap vissza, az Episerver oldal/blokk
objektumot és egy POCO nézeti modellt, amely a nézet számára szükséges további
tulajdonságokat tartalmazza, helyesen megjelenítse

Mindegyik megközelítésnek vannak előnyei és hátrányai, amelyeket az alábbiakban részletesebben


tárgyalunk.
Hybrid View Model
A hibrid nézetmodell-mintában az Episerver objektum a nézetmodell tulajdonságaként kerül
visszaadásra. A nézetmodell minden olyan további tulajdonságot is feltár, amely az adatok
megjelenítéséhez szükséges a nézetben. fájlhoz. Az alábbiakban egy egyszerű példa látható arra,
hogyan kell a kódot úgy strukturálni, hogy az megfeleljen ennek a mintának:

public class PageViewModel


{
public Homepage CurrentPage { get; set; }
public string AdditionalPropertyOne { get; set; }
}

Ha ezt a mintát alkalmazza az egész webhelyen, akkor valószínűleg észre fogja venni, hogy sok
hasonló kódot kell írnia, amikor egy új nézeti modellt kell létrehoznia. Ennek a bojlerplate-nek a
kiküszöbölése érdekében kódot, a legtöbb fejlesztő egy alaposztály bevezetésével bővíti ezt a mintát.
Kódmegtakarítás érhető el a nézetmodellek közötti közös konstruktor használatával. Ez a megosztott
konstruktor minden egyes nézetmodellt úgy állíthat be, ahogyan az szükséges. Ebben a mintában az
alaposztály az alábbi részlethez hasonlóan fog kinézni:

public class PageViewModel<T> : IPageViewModel<T> where T : PageData


{
public PageViewModel(T currentPage)
{
CurrentPage = currentPage;
}
public T CurrentPage { get; }
}

Az alap-osztály generikákat használ annak biztosítására, hogy az alosztályok PageData típusúak


legyenek. Az alaposztályból való örökléskor a nézetmodellt társítani kívánt oldaltípust T-ként
használjuk. Ha egy blokkos alaposztályt szeretnénk létrehozni, akkor egy új osztályt kell létrehoznunk,
és a típust meg kell változtatnunk, például így:
public class BlockViewModel<T> : BlockViewModel<T> where T : BlockData
{
public BlockViewModel(T currentBlock)
{
if (currentBlock == null)
throw new ArgumentNullException(nameof(currentBlock));
CurrentBlock = currentBlock;
}
public T CurrentBlock { get; private set; }
}
Visszatérve a kezdőlap példájához, az oldal nézeti modelljének megvalósítása így nézhet ki:
public class HomepageViewModel : PageViewModel<Homepage>
{
public HomepageViewModel(Homepage currentPage)
{
}
}

A nézeti modell ezután a következőképpen kapcsolódik a nézethez:


@model PageViewModel<Homepage>
// Remember to add a parent HTML element
// Otherwise you will encounter an error
<div>
Html.PropertyFor(m => m.CurrentPage.PageTitle)
</div>

A nézetmodell a CurrentPage tulajdonságon keresztül mutatja ki az oldal típusát. Ez azt jelenti, hogy a
nézetben könnyen elérheti az oldal-típus bármelyik tulajdonságát. Ha egy nézetnek további
tulajdonságokra van szükség, amelyeket az oldaltípus objektum nem biztosít, akkor ezeket nyilvános
tulajdonságokként adjuk hozzá a nézet-modellhez. Képzeljük el, hogy csak akkor szeretnénk
megjeleníteni a címet, ha az létezik. Ahelyett, hogy a logikát a nézetbe, ami az alábbiakban
bemutatott anti-mintázat:
<div>
@if (!string.IsNullOrEmpty(Model.PageTitle)) {
// Render text
}
</div>

A nézeti modell egyik tulajdonságaként is megjelenítheted, például így:


public class HomepageViewModel : PageViewModel<Homepage>
{
public HomepageViewModel(Homepage currentPage)
{
}
public bool ShowTitle => !string.IsNullOrEmpty(CurrentPage.PageTitle)
? false
: true;
}

Az oldalon ezután így érheti el:


@model PageViewModel<Homepage>
<div>
@if (Model.ShowTitle) {
Html.PropertyFor(m => m.CurrentPage.PageTitle)
}
</div>

A nézetmodell használata azt jelenti, hogy a nézeteken belül nem kell logikát írni. A ShowTitle
megjelenítéséhez szükséges logikának most már van egy logikus helye. Nézet használata nélkül
modell nélkül kénytelen lenne a ShowTitle megjelenítési logikáját a nézeten belül hozzáadni. Ez rossz.
Hogyan tesztelné ezt a kódot?

A legnagyobb kódszag, ami ennek a mintának az elfogadásából adódhat, az, amikor az összes további
logikát közvetlenül magában a nézetmodell osztályban adjuk hozzá. Ha az oldal összetett - mint
például egy pénztárgép oldal - ez egy nehezen tesztelhető spagettikódot eredményezhet. Egy
egyszerűbb architektúra az lenne, ha a nézetmodell egy POCO lenne. Ez azt jelenti, hogy a
nézetmodellnek ekkor egyáltalán nem szabad logikát tartalmaznia.

Dedicated View Model And A Service


Ha a nézeti modellt a lehető legtisztábbnak szeretné tartani, akkor kerülje az Episerver oldaltípusának
a nézeti modell nyilvános tulajdonságaként való megjelenítését. Ebben a mintában az összes
tulajdonság nézeten belül szükséges tulajdonságok a nézeti modellben kerülnek leképezésre. Az
egyéni logika teljesen kiköltözik magából a nézeti modellből, vagyis a modellnek sincs bázisosztálya.
Ebben a mintában a nézet modell nagyon egyszerű:
public class HomepageViewModel
{
public bool ShowTitle { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}

A nézeti modell feltöltésére szolgáló kódot a honlap Index metódusán belül lehet hozzáadni, például
így:
public class HomepageController
{
public ActionResult Index(Homepage currentPage)
{
var viewModel = new HomepageViewModel()
{
ShowTitle => !string.IsNullOrEmpty(currentPage.PageTitle)
? false : true,
Name = currentPage.Name
Title - currentPage.Title
}
return View("Index", viewModel);
}
}

Ez a megközelítés tisztább, mint az első. A kódot szétválasztjuk, és oda helyezzük, ahová az MVC
paradigma szánja. A probléma ezzel a mintával az, hogy mivel az Episerver objektumot nem teszi
közzé, mint a nézeti modell nyilvános tulajdonságaként, sok leképező kódra lesz szükség. Ezt a kódot
általában nagyon törékeny és fárasztó megírni, és mindenképpen macerásnak fog tűnni. Sok fejlesztő
úgy véli, hogy a leképezési kód hozzáadását a vezérlőhöz szintén anti-mintának tartják. Jobb
megközelítés egy szolgáltatás/gyár használata a nézeti modell feltöltéséhez.
A nézet-modell szolgáltatás/gyár létrehozásához a következőket kell tennie írhatsz ehhez hasonló
kódot:
public class HomepageService : IHomepageService
{
public HomepageViewModel GetHomepageViewModel(Homepage page)
{
return new HomepageViewModel()
{
ShowTitle => !string.IsNullOrEmpty(currentPage.PageTitle)
? false : true
};
}
}

With the interface:


public interface IHomepageService
{
HomepageViewModel GetHomepageViewModel(Homepage page);
}

A függőségi injektálás segítségével a szolgáltatást az IoC konténer be tudja injektálni a kezdőlapok


konstruktorába, például így:
public class HomepageController
{
private IHomepageService _homepageService;
public HomepageController(IHomepageService homepageService)
{
_homepageService = homepageService;
}
public ActionResult Index(Homepage currentPage)
{
var viewModel = _homepageService.GetHomepageViewModel(currentPage);
return View("Index", viewModel);
}
}

Egy ilyen szolgáltatás használata nem csak azt eredményezi, hogy a vezérlőn belüli kód nagyon tiszta
lesz, hanem segít a kód újrafelhasználásában is. Ennél az egyszerű példánál ez túlzásnak tűnhet.
Ahogy a projekt egyre összetettebbé válik, nagy valószínűséggel a kódbázisban más, a honlaphoz
kapcsolódó tevékenységeket is el kell majd végeznie. Egy szolgáltatás használata azt jelenti, hogy ezt
könnyen megoszthatja és újra felhasználhatja a funkciót.

TIPP: Amikor helyi blokkokat használ, mindig egy szolgáltatáson keresztül generált nézeti modellt kell
használnia.
Composed Page ViewModel - Összetett oldal ViewModel
A legtöbb szoftverkönyv azt javasolja, hogy az öröklés helyett a kompozíciót részesítsük előnyben.
Ennek a mantrának az az oka, hogy elősegíti a kódbázisunk szétválasztását. Ha megpróbáljuk követni
a ezt a tanácsot egy Episerver projektben, akkor az alap nézetmodell mintát kerülni kell. Az öröklődés
használatának problémája egy nézetmodellben az, hogy feltételezi, hogy az oldalon minden egy
Episerver oldal. Hogyan hoznánk létre egy nézetmodellt egy blokkhoz? Mi a helyzet akkor, ha egy
tartalomtípus nem létezik, mint egy normál MVC vezérlőben? Ha Episerver commerce-t használsz,
akkor ez a view modell nem működne a termékekkel. Ilyen körülmények között további alap
nézetmodelleket kell elkezdenie létrehozni, hogy kezelni tudja ezeket a különböző forgatókönyveket.

Jobb lenne az a kialakítás, ahol a nézetmodell felépítése ettől függetlenül ugyanúgy működne. Nem
kellene számítania, hogy egy oldalt, egy kereskedelmi objektumot vagy egy vanília MVC vezérlőt
használunk. Ön nem kellene létrehozni ezeket a további alaposztályokat. Ennek elérése lehetséges.
Ahelyett, hogy egy modellt adnánk át a nézetnek, kettőt adunk át. Az oldal-típust és egy nézeti
modellt, amely tartalmazza a minden további tulajdonságot, amire a nézetnek szüksége lehet. Ezt
egyetlen nézetmodell segítségével tesszük, így:
public class ComposedPageViewModel<TCurrentItem, TAdditionalProperties>
{
public TCurrentItem CurrentItem { get; set; }
public TAdditionalProperties AdditionalProperties { get; set; }
}

A ComposedPageViewModel két tulajdonságot tartalmaz, egyet az Episerver elem tárolására, egyet


pedig a további tulajdonságok tárolására. Ezután létrehoz egy egyszerű POCO-t a nézetmodellhez. A
cél a ennek a nézetmodellnek az a célja, hogy kezelje a nézetnek esetleg szükséges további adatokat,
amelyek nem állnak rendelkezésre az Episerver-elemben.
public class HomepageViewModel
{
public bool ShowTitle { get; set; }
}

A vezérlőn belül a nézeti modellt vagy a vezérlő, vagy egy szolgáltatás/gyár tölti fel, például így:
public class HomepageController : PageController<Homepage>
{
public ActionResult Index(Homepage currentPage)
{
var homepageService = new HomepageService();
var model = new ComposedPageViewModel<Homepage, HomepageViewModel>
{
CurrentItem = currentPage,
AdditionalProperties = homepageService.GetAdditionalPropertiesViewModel(currentPage)
};
return View("Index", viewModel);
}
}
Az Ön nézetében a modellt így definiálná:
@model ComposedPageViewModel<StartPage, StartPageViewModel>
@if (Model.AdditionalProperties.ShowTitle) {
@Model.CurrentItem.PageTitle
}

Ebben a nézetben most már két nyilvánvaló és különálló módja van az adatok elérésének. A
CurrentItem a fő Episerver objektum elérésére szolgál, ez lehet egy oldal vagy egy blokk. Az
AdditionalProperties-t a a nézetben szükséges egyéb egyéni tulajdonságok eléréséhez.

A kód olvasása és megértése a frissítéshez nagyon intuitívnak kell lennie a projekt új fejlesztői
számára. Egy gyors pillantásból könnyen megérthető, hogy milyen adatok találhatók az Episerverben
és milyen adatokat adunk hozzá egy szolgáltatáson keresztül.

Végül, ha a ComposedPageViewModel-en belül egy további Episerver-érvényesítési réteget szeretne


hozzáadni, akkor hozzáadhat egy where záradékot annak ellenőrzésére, hogy a TCurrentItem
PageData típusú-e, például így:
public class ComposedPageViewModel<TCurrentItem, TAdditionalProperties>
where TCurrentItem : PageData
{
public TCurrentItem CurrentItem { get; set; }
public TAdditionalProperties AdditionalProperties { get; set; }
}

Ha kíváncsi vagy, hogyan használhatod ezt a mintát egy normál MVC vezérlőben, ha nem létezik
Episerver típus, akkor a null objektum mintát követheted a következőképpen:
public class EmptyViewModel
{}

Így adja vissza:


var viewModel = new ComposedPageViewModel<EmptyViewModel, AdditionalPropertiesViewModel>();
return View("Index", viewModel);

A ComposedPageViewModel használata határozottan az általam preferált megközelítés. Ez biztosítja


a legnagyobb rugalmasságot, és könnyen érthető kódot eredményez. Azokat a megközelítéseket
részesítem előnyben, amelyek megkönnyítik az életemet. Az Episerver-adatok és a nézeti adatok
szétválasztása általában ezt biztosítja.
Layouts - Alaprajzok
Az oldal megjelenítéséhez szükséges összes HTML megkettőzése minden egyes nézeten belül
ostobaság lenne. Itt jönnek a képi elrendezések. Az MVC-n belül az elrendezéseket arra használják,
hogy egységes megjelenést biztosítsanak több oldalon keresztül anélkül, hogy a HTML-t duplikálni
kellene. A webhely HTML vázkódja, az oldalak `` szekciója, a fejléc és a lábléc tökéletes jelöltek az
elrendezésbe való beillesztésre. A fejezet utolsó része egy nagyon egyszerű elrendezés létrehozására
fog összpontosítani. A fejezet célja, hogy egy egyszerű oldalt egy alapvető elrendezéssel
rendereljünk. Az elrendezés integrálása az Episerverben bemutatja néhány érdekes kérdést, amelyek
mélyebb elmélyülést igényelnek. Erre a 7. fejezetben kerül sor. Egyelőre csak győződjön meg róla,
hogy az oldala üres elrendezést használ.

_viewStart.cshtml
Ahelyett, hogy minden egyes nézeten belül meg kellene adnia, hogy az Episerver melyik elrendezést
használja, hozzáadhat egy _viewStart.cshtml fájlt. Bármelyik oldal kérése esetén a _viewStart.cshtml
segítségével automatikusan beállítja az alapértelmezett elrendezést. Ennek engedélyezéséhez a
'Views' mappában létre kell hoznia egy _ViewStart.cshtml nevű fájlt. Az Alloy webhely telepítésekor
ez a fájl már létezni fog. Ha az üres mintaoldalt használta, akkor magának kell létrehoznia. A
_ViewStart.cshtml fájlban csak egyetlen kódsorra van szükség. konfigurálni. Ennek a sornak kell
megmondania az MVC-nek, hogy hol találja meg az alapértelmezett elrendezést. Valahogy így kell
kinéznie:
@{
Layout = "~/Views/_Layout.cshtml";
}

Ebben a példában az alapértelmezett elrendezés - más néven a mester elrendezés - nevét


_Layout.cshtml néven határozzuk meg. Ezt a _Layout.cshtml fájlt szintén a nézet mappában kell
létrehozni. Az alapértelmezett elrendezés is csak egy nézet és némi HTML, semmi különös. Az
egyszerű elrendezés létrehozásához szükséges kód az alábbiakban látható:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
@RenderBody()
</body>
</html>

A RenderBody() utasítja az MVC-t, hogy a megfelelő oldalvezérlő által visszaküldött HTML-t jelenítse
meg. A HTML többi része olyan kód, amelyet úgy írhatsz meg, ahogyan csak akarsz. A _viewStart és
_layout fájlokat létrehozta, most már egy teljes oldal megjelenítésével kell rendelkeznie!
Querying Content From The CMS - Tartalom lekérdezése a CMS-ből
Az Episerver számos olyan szolgáltatással és segédmódszerrel rendelkezik, amelyekkel interakcióba
léphetünk a CMS-szel. Ezek a szolgáltatások és segédmódszerek nagyon széleskörűek, és nagyjából
megfelelnek a következőknek minden olyan igényt, amellyel a fejlesztés során találkozhat. A
szolgáltatások és segédmódszerek közül azokat fogja a legtöbbször használni, amelyek lehetővé
teszik a CMS tartalom lekérdezését.

leggyakrabban. Ebben a fejezetben a CMS-tartalom lekérdezése lesz a középpontban. Ebben a


fejezetben az API-k, szolgáltatások, segédmódszerek és segédmódszerek kifejezéseket felváltva
használhatom. Ebben az összefüggésben, ezek a különböző kifejezések mind ugyanazt a dolgot
jelentik. Egy Episerver kódkönyvtár, amely a CMS-ből való tartalom lekérdezéséhez használható.

Meglepően sokféle módon lehet lekérdezni tartalmat a CMS-en belül. Az API-k némelyike egy adott
oldalra vonatkozó adatok lekérdezésére irányul, míg más API-k jobban megfelelnek hogy bizonyos
kritériumok alapján oldalak egy sorát keressük. Ez a fejezet ezeket a különböző forgatókönyveket
tárgyalja. A fejezet végére képesnek kell lennie arra, hogy speciálisabb komponenseket, mint például
egy webhelykereső vagy egy menü. Olyan komponensek, amelyeknek kölcsönhatásba kell lépniük
más oldalakkal. Ez a fejezet az Episerverben leggyakrabban használt négy API megvitatásával
kezdődik, amelyek a következők PageReference IContentLoader, IContentRepository,
IPageCriteriaQueryService és IContentEvents.

PageReference
Ahhoz, hogy lekérdezzen egy adott tartalmat az Episerverről, létre kell hoznia egy tartalmi
hivatkozást, a megfelelő azonosítót megadva. A PageReference segédprogrammal lekérdezhet egy
tartalmat. referenciát néhány kiválasztott rendszeroldalhoz. A gyökéroldal az első elem a hierarchia
tetején. Ez a fő rendszercsomópont, amely alatt az összes oldal elhelyezkedik az oldalfán belül. A
gyökéroldal lesz a kezdőlap/kezdőoldal szülő csomópontja. A gyökéroldalra való tartalmi hivatkozás
megszerzéséhez a következőt teheti:
PageReference.RootPage

A kezdőlap/kezdőoldal PageReference használatával is elérhető Ez a StartPage tulajdonságon


keresztül történhet, például így:
PageReference.StartPage

A PageReference használható a globális blokkok mappa azonosítójának megadására is, például így:
PageReference.SiteBlockFolder

Végül, a PageReference segítségével megkaphatja az aktuális oldal azonosítóját is:


PageReference.SelfReference
Querying For Content - Tartalom lekérdezése
A CMS-ből származó tartalom lekérdezésére és módosítására két fő API létezik: az IContentLoader és
az IContentRepository API-k. Az IContentLoader a funkciók egy részhalmazát nyújtja.

IContentRepository által biztosított funkciókat. Az IContentLoader egy csak olvasható API, ami azt
jelenti, hogy csak olyan metódusokat tesz közzé, amelyek lehetővé teszik a tartalom lekérését a CMS-
ből. Az IContentLoader lehetővé teszi a következők lekérdezését CMS-en belüli tartalmat a Get<T>,
GetChildren<T> és GetDescendants<T> metódusok segítségével.

Az IContentRepository pontosan ugyanazokat a metódusokat biztosítja, mint az IContentLoader,


valamint számos írási-olvasási műveletet is. Ezek közé tartoznak az olyan metódusok, mint a Save(),
ami nagyon hasznos, ha a ha a tartalmat kódban kell frissíteni.

Ha az IContentRepository-ra reflectiont használunk, láthatjuk, hogy az IContentLoader interfészt


valósítja meg. Bármit, amit az IContentLoader-ben megtehetünk, azt az IContentRepository-ban is
megtehetjük. A oldalon projektjeimben általában csak az IContentRepository-t használom, mivel úgy
találom, hogy ez megkönnyíti a kód írását, és általában kevesebb későbbi refaktorálást eredményez.
Ebben a könyvben is előnyben fogom részesíteni a IContentRepository-t, azonban ne feledjük, hogy
ez általában IContentLoader-re cserélhető. Amikor a projektjeidről van szó, válaszd azt a
megközelítést, amelyik boldoggá tesz.

Ahhoz, hogy az Episerverről adatokat kapjunk a honlapról, ezt a kódot használnánk:


var contentReference = PageReference.StartPage;
var contentRepository = ServiceLocator.Current.GetInstance<IContentLoader>();
var page = contentRepository.Get<PageData>(contentReference);

A fenti példában a PageReference.StartPage segítségével kapunk egy olyan tartalmi hivatkozást,


amely a kezdőlapra mutat. Ezt a tartalomreferenciát ezután a Get<T> híváson keresztül. A kód
végrehajtásakor az Episerver lekérdezi az adatbázist a kezdőlapra vonatkozóan, és visszaadja az
oldalhoz kapcsolódó összes adatot. A visszaküldött típus egy általános PageData objektum lesz.

A Get<T> metódus generikát használ. A fenti példában a PageData típust T-ként adom át. A Get<T>
hívás az összes PageData típusúnak kasztolt elemet fogja visszaadni. Ha egy adott oldaltípust adunk
át, például HomePage T-ként, az API helyesen fogja tipizálni a visszaadott objektumot:
var contentRepository = ServiceLocator.Current.GetInstance<IContentLoader>();
var contentReference = PageReference.StartPage;
var page = contentRepository.Get<HomePage>(contentReference);

Egy ilyen típus megadásával megkímélhetjük magunkat attól, hogy manuálisan öntsük le az
objektumot. A CMS-ből származó adatok visszaküldésekor mindig legyen pontos. Az alábbi kód
pontosan ugyanazt teszi, mint a mint a fenti, csak kevésbé tiszta:
var contentRepository = ServiceLocator.Current.GetInstance<IContentLoader>();
var contentReference = PageReference.StartPage;
var content = contentRepository.Get(contentReference);
Var homepage = content as Homepage ?? null;

Ha nem ismeri egy oldal (vagy blokk) tartalomazonosítóját, akkor jelentkezzen be a CMS-be, és
navigáljon az átnézni kívánt oldalra. Amikor az elem betöltődik a CMS-ben, nézze meg az URL-t. Úgy
kell kinéznie valahogy így néz ki:
http://www.website.com/episerver/cms/#context=epi.cms.contentdata:///18

Az azonosító ebben a példában 18. Ha kódban szeretné lekérdezni a CMS-t ehhez az oldalhoz, hozzon
létre egy új tartalomreferencia-objektumot, és adja hozzá a 18-as számot a konstruktorhoz, így:
var contentRepository = ServiceLocator.Current.GetInstance<IContentLoader>();
var contentReference = new ContentReference(18);
var content = contentRepository.Get(contentReference);

A Get<T> módszer csak egy tartalmi hivatkozást fogad el konstruktor argumentumként. Nem
adhatod át egyszerűen egy azonosítót számként közvetlenül. Ennek a furcsaságnak az okát rövidesen
tárgyaljuk. Egy másik dolog, amit a fenti kóddal kapcsolatban meg kell jegyeznünk, az a
ServiceLocator használata. A ServiceLocator egy vanilla .NET segédprogram, amely a függőségek
eléréséhez használható, amelyeket a webhely függőségi injektálási keretrendszerével. Amikor először
kezdtem tanulni az Episerverről, az egyik dolog, amit zavarónak találtam, hogy minden online
Episerver oktatóanyag a ServiceLocator-t használja.

A .NET világán belül a service locator használata általában anti-mintának számít, amit kerülni kell. Az
ok, amiért a ServiceLocator használatát látja a legtöbb online oktatóanyagban azért van, mert így
könnyebben érthetővé válik az oktatóanyag. Csak azért, mert a ServiceLocator használata az
olvashatóságot segíti az interneten, nem jelenti azt, hogy az adott webhely ezt a szolgáltatást mint
egy jó tervezési megközelítésként. Több oka is van annak, hogy a service locator antimintának számít,
ezek a következők:

• A ServiceLocator eredmények elrejtik az osztályban használt függőségeket.


• A ServiceLocator megnehezíti a kód tesztelését
• A ServiceLocator egy további hivatkozást ad hozzá az osztályodhoz
• A ServiceLocator megnehezíti a kód olvashatóságát

Az Episerver API-k eléréséhez - és általában a függőségi injektáláshoz - jobb megközelítés a


konstruktor injektálás használata.

MEGJEGYZÉS Ez a könyv nem a függőségi injektálásról szól. Ha új vagy a témában, akkor Mark
Seemann Dependency Injection.Net című könyvét ajánlom egy alapos áttekintésért.

Az Episerver által használt függőségi injektálási keretrendszer neve Structure-map. Az Episerver


telepítésekor a Structure-map is telepítve lesz, némi előzetes konfigurációval. Ez azt jelenti, hogy az
Episerver alapból az API-k elérésének ezzel a klassz módjával van ellátva, és nem kell semmit sem
tennie ahhoz, hogy kihasználhassa az előnyeit.

Bármely vezérlő osztályon belül egyszerűen átadhatja a konstruktor paramétereként azt az API-t,
amellyel dolgozni szeretne. A kód végrehajtásakor a paraméter automatikusan be lesz injektálva, és a
varázslatos módon instanciálódik.

MEGJEGYZÉS: Nem minden Episerver komponens hozható létre nyilvános konstruktorral, erről
később!
Az IContentLoader eléréséhez egy vezérlőben a következő kódot írhatja:
public class HomepageController
{
private IContentLoader _contentLoader;
public HomepageController(IContentLoader contentLoader)
{
_contentLoader = contentLoader;
}
}

Amikor a fenti vezérlőt kérik, a contentLoader paraméter automatikusan instanciálódik. Ezzel a


mintával kell elérnie az összes Episerver API-t a kódjában.

Pages Are Immutable - Az oldalak megváltoztathatatlanok


Az IContentLoader vagy IContentRepository által visszaadott összes objektum megváltoztathatatlan.
Ez azt jelenti, hogy az API-t használhatja a tartalom megszerzésére, de nem tudja frissíteni a
tartalmat. közvetlenül. Ezt bebizonyíthatja, ha megpróbálja bármely, az API-tól visszakapott elemet
közvetlenül átadni az IContentRepository.Save() metódusnak, és megnézi, mi történik.

Egy olyan API, amely megváltoztathatatlan tartalmat ad vissza, nagyon megnyugtató. Egy CMS
rendszerben a tartalom elvesztése rossz. Ha az Episerver API-val dolgozik, biztos lehet benne, hogy ez
nem fog megtörténni. Ha a véletlenül megpróbálna módosítani egy, az API által visszaadott
objektumot, az Episerver egy System.NotSupportedException kivételt fog dobni. Az Episerver nagyon
világossá fogja tenni, hogy hogyan szegte meg a szabályokat. A stack-trace-en belül megjelenik a
konkrét tulajdonság, amelyet megsértett.

Két jó oka van annak, hogy az API által visszaküldött elemek megváltoztathatatlanok. Először is, a
biztonság. Az ASP.NET alkalmazások többszálúak. Egy webhelyet több egyidejű felhasználó fog elérni.

következetesen. Ugyanazon CMS-erőforrások egyidejű használatára irányuló kérések fordulnak elő.


Egy adott időpontban egy oldalra vonatkozó adatok több szálban is létezhetnek. Ha az API lehetővé
tenné, hogy mindkét elemet egyidejűleg frissüljenek, akkor ez problémát jelentene. Hogyan tartaná
szinkronban a frissítéseket? Azzal, hogy az API megváltoztathatatlan elemeket ad vissza, megelőzhető
ez a helyzet.

A megváltoztathatatlan objektumok második előnye az Episerver API belső teljesítményével és a


gyorsítótárazással kapcsolatos. Az IContentLoader és az IContentRepository
teljesítményoptimalizálással rendelkezik az alábbiakban leírtak szerint. hood. Ha egy elem csak
olvasható, az Episerver hosszabb ideig képes az objektumot gyorsítótárba helyezni. Amikor egy oldal
új verziója jön létre, a gyorsítótárat érvényteleníteni lehet, és egy új verzió léphet a helyébe. Ha a

API-elemek akarva-akaratlanul frissíthetők, akkor az állapot és a gyorsítótár kezelése sokkal


nehezebbé válik. Hogy demisztifikáljuk, hogyan működik ez az EPiserver varázslat, ássuk bele
magunkat a kódba. A PageData osztály az Episerver.Core assemblyben található. Ha a PageData
típuson reflexiót használunk, akkor azt fogja látni, hogy az IReadOnly interfészt valósítja meg.

Az IContentRepository.Get() első hívásakor több dolog is történik. Először is egy SQL-hívás történik az
adatok adatbázisból történő lekérdezésére. Ezután az Episerver létrehoz egy üres, írható PageData

objektumot. Az SQL-ből visszakapott adatokat az objektum feltöltésére használja. Ezután az


IReadOnly.MakeReadOnly() hívás következik, ami viszont megváltoztathatatlanná teszi az
oldalak/blokkok tulajdonságait. A verzió, a nyelv és a tartalmi hivatkozás alapján az objektumot az
Episerver belső gyorsítótárába helyezzük. Az oldal minden későbbi hívása ezután a gyorsítótárból fog
érkezni.

Creating Content In Code - Tartalom létrehozása kódban


Csak azért, mert az API mindent csak olvashatóként ad vissza, ez nem jelenti azt, hogy nem lehet a
tartalmat kódban frissíteni. A tartalom módosítása kódban mindenképpen lehetséges. Valójában
nagyon egyszerű. Az Episerverrel újonnan ismerkedő fejlesztők gyakran követik el azt a hibát, hogy
megpróbálnak új tartalmat létrehozni kódban egy oldal vagy blokk típus közvetlen példányosításával,
például így:

var newPage = new MyPageType();

Ha megpróbálja futtatni ezt a kódot, egy kivétel fog előjönni. Az Episerverrel való munka során
mindig az IContentLoader vagy az IContentRepository használatát kell használnia ahhoz, hogy
hozzáférjen bármelyik tartalomhoz. Egy új oldal létrehozásához az
IContentRepository.GetDefault<T>() metódust kell használnia. Ahogyan azt a metódus
szignatúrájában szereplő T-ből kitalálhatjuk, hogy a generikusok generikusokat használnak. Ez azt
jelenti, hogy meg kell adnia a létrehozni kívánt tartalomtípust is.

A létrehozni kívánt tartalom típusának ismerete mellett azt is tudnia kell, hogy azt hol szeretné
tárolni az oldalfán belül. A parent tulajdonság a IContentRepository.GetDefault<T>() függvényében.
Egy új oldal létrehozásához ezt tehetjük:
var parent - PageReference.StartPage;
var newPage = contentRepository.GetDefault<MyPageType>(parent);

Ez a kód létrehoz egy oldalt, amely a kezdőlap alatt jön létre. Ha többnyelvű környezetben dolgozik,
akkor lehet, hogy egy adott nyelvi változatot is szeretne létrehozni a oldal létrehozásához. Ezt egy
második paraméter átadásával érheti el:
var parent - PageReference.StartPage;
var enSE = new CultureInfo("en-SE");
var newPage = contentRepository.GetDefault<MyPageType>(parent, enSE);

Miután egy új írható/olvasható objektumot létrehoztál, szükség szerint frissítheted a tartalmát. Az


adatfrissítések tárolásához ezután az IContentRepository.Save() metódust kell használnia. A legtöbb
esetben elegendő, ha csak a tartalmi elemet adja át a Save metódusnak.
contentRepository.Save(content);

Ha jobban szeretné ellenőrizni a tartalom mentésének módját, akkor egy második argumentumot is
megadhat. Ezzel a további paraméterrel megadható a végrehajtandó mentési művelet. Ezek a
további mentési műveletek hasznosabbak, ha meglévő tartalmat frissítünk, mintha újat hoznánk
létre. A mentési műveletek nagyobb részletességet biztosítanak a tartalom mentésének módját
illetően.

Az alapértelmezett mentési művelet viselkedése a tartalom állapotától függően változik. Ha a


tartalom nem új, és az aktuális állapota a Megjelent vagy a Korábban megjelent, akkor a tartalom
frissül és új verziószámot kap. Ha a tartalom nem új, és nem publikált, akkor nem verziószámozásra,
hanem frissítésre kerül. Ha viszont új, akkor mentésre kerül.

Az alábbi részlet mutatja, hogyan adhatja meg a második paramétert.


contentRepository.Save(myPage, EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);

További hasznos beállítások a ForceNewVersion és a ForceCurrentVersion, amelyek mindkettő arra


kényszerítheti a CMS-t, hogy új verziót hozzon létre, függetlenül az oldal aktuális állapotától. A javítás
egy másik lehetőség, amely szintén egy kicsit veszélyesebb. Ez a ForceCurrentVersiont a
SkipValidationnel kombinálja. Ez azt jelenti, hogy a tartalom frissül, és az egyéni érvényesítések nem
kerülnek ellenőrzésre.

Updating Existing Pages Programmatically - Meglévő oldalak programozott frissítése


A fent leírt eljárással új oldal hozható létre. Egy meglévő oldal módosításának folyamata némileg
eltérő. A meglévő tartalom módosításához először is le kell kérdeznie a CMS-t, és a szokásos módon
megkapjuk az elem megváltoztathatatlan másolatát. Ezzel a másolattal létrehozható egy
szerkeszthető klón. A klón ezután frissíthető anélkül, hogy az Episerver hibát jelezne. Az ehhez
szükséges kód mindezt az alábbiakban mutatjuk be:
var myPage = contentRepository.Get<Homepage>(new ContentReference(1));
var clone = myPage.CreateWritableClone<Homepage>();
var clone.PageName = "Update Page Name";

contentRepository.Save(clone, EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.Read);

A fenti részletben az IContentRepository.Get<T> segítségével lekérdezzük a kezdőlap egy példányát,


és egy {myPage} nevű helyi változóban tároljuk. A {myPage}-ben tárolt elem csak olvasható és
megváltoztathatatlan. Az IContentRepository.CreateWritableClone() metódus elérhető a {myPage}
oldalon. A CreateWritableClone() használatával létrehozza az oldal írható változatát. Ennek a
kimenete művelet eredményét a {clone} tárolja. A {clone} ezután átadható az
IContentRepository.Save() metódusnak, hogy visszakerüljön az adatbázisba.

Accessing Existing Versions Of A Page - Egy oldal meglévő verzióinak elérése


Amikor egy oldalt a Save() metódus segítségével frissít, az adatok soha nem vesznek el. A Save()
metódus használatával soha nem kell aggódnia a tartalom elvesztése miatt. Mint minden jó CMS
rendszerben, az Episerver verziók tartalom. Amikor egy tartalomszerkesztő a közzététel gombra
kattint, az oldal egy inkrementális verziója jön létre az adatbázisban. Ez a verzió lesz azután a
legfrissebb verzió A tartalomtár mindig a tartalom legfrissebb verzióját adja vissza. A felhasználási
esetek 99%-ában ez megfelel az Ön igényeinek. Néhány nagyon ritka esetben előfordulhat, hogy nem
ezt szeretné. A oldalon bizonyos esetekben az oldal egy régebbi verzióját szeretné elérni. Az oldal
régebbi verziójának elérése lehetséges, azonban ehhez egy másik API-t kell használnia, a
IContentVersionRepository.

Ahogy a neve is mutatja, az IContentVersionRepository egy sor függvényt biztosít az oldal vagy blokk
különböző revízióinak eléréséhez. Az API használata meglehetősen egyszerű. Átad egy tartalmi
hivatkozást és megkapjuk az összes különböző verzióját. Az IContentVersionRepository használatakor
egy óvatosságra intünk. Az Episerver nem biztosít gyorsítótárazást ezen API körül. Ez azt jelenti, hogy
túlzott használat esetén teljesítményproblémákat tapasztalhat a webhelyén.

A jó hír az, hogy nagyon valószínűtlen, hogy az IContentVersionRepository-t kell használnia egy oldal
megjelenítéséhez a frontendben. Általánosságban elmondható, hogy erre valószínűleg soha nem lesz
szüksége. aggódnia. Nekem például csak a CMS-érvényesítések vagy az adminisztrátori bővítmények
létrehozásához volt szükségem az IContentVersionRepository használatára. Mivel az ilyen típusú
funkciókat/oldalakat csak a ritkán, a teljesítmény soha nem jelentett nagy gondot. Az oldal különböző
verzióinak eléréséhez szükséges kód az alábbiakban található:
public Method(IContentVersionRepository contentVersionRepository)
{
var contentReference = // Get a page
var versions = contentVersionRepository.List(contentReference);
var pageVersions = versions.OrderByDescending(x => x.Saved).FirstOrDefault(version =>
version.IsMasterLanguageBranch);
}

A fenti kód az IContentVersionRepository.List() metódust használja. Ez a módszer visszaadja az adott


elem összes verzióját. Szűrés az OrderDescending() segítségével módszerrel a Saved tulajdonságon a
legújabbtól a legrégebbi felé rendezi a verziókat. Ha egynyelvű webhelyen dolgozik, akkor figyelmen
kívül hagyhatja az IsMasterLanguageBranch jelzőt. Többnyelvű környezetben ez a flag használható az
alapértelmezett nyelv megkeresésére. Ha több nyelvvel dolgozik, akkor tisztában kell lennie azzal,
hogy szükség lehet további szűrésre a kívánt nyelv alapján.

Querying Episerver Content - Az Episerver tartalom lekérdezése


Míg a CMS egyetlen oldalra történő lekérdezése hasznos, sok helyzetben inkább egy sor oldalra van
szükség. A menük, a listázó oldalak és a keresőoldalak mind ilyenek. komponensek típusai. Ahogy az
várható volt, az Episerver számos API-t biztosít az ilyen típusú műveletek elvégzéséhez. A legtöbb
helyzetben a CMS alapszolgáltatásai kiválóan működnek a lekérdezés során. oldalakra. A lekérdezés
hasznos a tartalomfán való áthaladáshoz, és nagyszerű az egyszerű komponensekhez.

Bármilyen adathalmazzal való munka során, ha a dolgok túl nagyra nőnek, akkor egy egyszerű
lekérdezés túl lassúvá és nehézkessé válhat. Például egy weboldal gyökércsomópontja alatt található
összes gyermekoldal lekérdezése amely több millió oldalt tartalmaz, nem lenne jó ötlet. Ilyen
helyzetekben jobb, ha a CMS közvetlen lekérdezése helyett inkább egy keresési indexet használunk.
Például egy terméklistázó oldal létrehozása egy webáruházon belül. áruházban, amely szűrést,
fakultációkat és intelligens keresési javaslatokat tartalmaz, mindenképpen átlépné annak határait,
amire az alapvető lekérdező szolgáltatás képes. Ha sok keresést kell végeznie oldalak között, akkor
egy harmadik féltől származó keresőszolgáltató, például az EpiFind jobb eszköz lesz.

A teljesítményt is figyelembe kell vennie, amikor a CMS-en belüli tartalomra vonatkozó


lekérdezéseket hajt végre. Nyilvánvaló, hogy minél nagyobb a keresendő adathalmaz, annál hosszabb
lesz a lekérdezés. és annál erőforrás-igényesebb lesz a végrehajtása. Határozottan lehetséges olyan
lekérdezéseket létrehozni, amelyek túl gyakori futtatása hatással lesz a webhely teljesítményére. Egy
jó tanács az, hogy mindig az összetett keresési követelményeket támasztó oldalakat indítás előtt
teszteljük!

GetChildren()
A GetChildren<T>(), ahogy a neve is mutatja, egy csomópont közvetlen gyermekeinek listáját adja
vissza. A GetChildren<T>() definíciója így néz ki:
IContentLoader.GetChildren<T>(ContentReference) : IEnumerable<T>

A GetChildren<T>()-be egy tartalmi hivatkozást adunk át. Az API lekérdezi és visszaadja a szülőhöz
viszonyított összes gyermekét. A GetChildren<T>() használható generikusokkal, ahol a T lehet a
visszaadott elemek szűrésére és formázására. A GetChildren() funkciónak van egy általánosabb
változata is, amely az összes oldalt PageData elemként adja vissza. Az alábbiakban a GetChildren<T>()
használatát mutatjuk be:
var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var landingPages = contentLoader.GetChildren<LandingPage>(ContentReference.StartPage)

Generikusok használata nélkül:


var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var pageData = contentLoader.GetChildren(ContentReference.StartPage)

A GetChildren<T>() használatával az a jó, hogy elég gyorsan működik. Az Episerver a lekérdezés


eredményeit gyorsítótárba teszi a memóriában. Alapértelmezés szerint a CMS által végrehajtott
minden lekérdezés a gyorsítótárba kerül a körülbelül 12 órán keresztül. Az Episerver által használt
gyorsítótárazási módszer elég okos, és érdemes megemlíteni. Az Episerver nem a teljes oldalfát
tárolja a gyorsítótárban egyetlen hatalmas egységként. Ehelyett, Az Episerver az oldalakat és a
navigációs struktúrát külön-külön gyorsítótárba helyezi.

A GetChildren<T>() hívásakor az Episerver először egy keresést végez a tartalomfa gyorsítótárában. A


tartalomfa gyorsítótár csak az elemek tartalmi hivatkozásainak listáját tárolja a page-tree. Magukról
az oldalakról nem tárol adatokat.

A listában szereplő minden egyes hivatkozásra egy ellenőrzés végezhető az oldal gyorsítótárban. Ha
az oldal szerepel a gyorsítótárban, akkor visszakerül. Ha az oldal nincs a gyorsítótárban, akkor az
adatbázisba történik egy kérés. Ez a A gyorsítótár két részre osztása hasznos. Ha egy
tartalomszerkesztő frissít egy oldalt, csak az elemtárat kell frissíteni. Ha egy szerkesztő töröl egy
oldalt a CMS-en belül, akkor az oldalfa gyorsítótárat frissíthető anélkül, hogy az elem-cache-t ki
kellene tisztítani. Ez azt jelenti, hogy a teljes gyorsítótárat soha nem kell egyszerre érvényteleníteni.

GetAncestors()
Az oldalhoz viszonyított tartalom lekérdezésének következő módja a GetAncestors(). A
GetAncestors() az oldalak listáját adja vissza az aktuális oldaltól a kezdőoldalig. A GetAncestors() egy
hasznos lekérdezés, hogy ha a webhelyen morzsát kell építenie. A GetAncestors() definíciója így néz
ki:
IContentLoader.GetAncestors(ContentReference) : IEnumerable<IContent>

A kenyérmorzsa létrehozásához szükséges kód így nézhet ki (The code to create a breadcrumb could
then look like this):
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var breadcrumb = contentRepository.GetAncestors(contentReference);
GetDescendants() ( Szerezd meg a leszármazottakat)
A GetDescendants() az oldal alatti összes csomópontot visszaadja. A GetDescendants() visszaadja az
aktuális elem gyermekeit, majd folytatja a fán való visszalépést, és visszaadja az összes gyermekét.
gyermekeit, amíg az összes csomópontot ki nem elemzi. Mint sejthető, az oldalfán való iterálás
teljesítményproblémákat okozhat a nagy weboldalakon, ezért óvatosan használja. Egy példa a
GetDescendants() használata az alábbiakban látható:

var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();


var pages = contentRepository.GetDescendants(contentReference);

GetBySegment()

A GetBySegment() az oldalak listáját adja vissza az URL alapján. Ha lenne egy weboldalunk, amely
számos blogbejegyzést tartalmazna ezen URL alatt:
www.website.com/blog/

A GetBySegment() paramétereként átadhatná a 'blog' szegmenst, hogy megkapja az összes oldal


listáját. A GetBySegment() használatához szükséges kód így néz ki:
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var pages = contentRepository.GetBySegment(PageReference.StartPage, "blog", LanguageManager.AutoDetect());

Egy másik hasznos tény, hogy a GetBySegment() sokkal gyorsabb, mint a GetChildren() használata.

Filter By Page Type - Oldaltípus szerinti szűrés


Egy adott oldal lekérdezése helyett használhatja az IContentTypeRepository-t, hogy a tartalmat a
tartalom típusa alapján kérje le. Ez a következőképpen érhető el:
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var landingPageContentType = contentTypeRepository.Load<LandingPage>();
var landingPageTypeId = landingPageType.ID;

Vagy néhány alternatív megközelítés:


var landingPages = contentTypeRepository.List().OfType<LandingPage>();

Vagy:
var landingPages = contentTypeRepository.List().Where(x => typeof(LandingPage).IsAssignableFrom(x.ModelType));

A tartalomtípus használatával ezután az IContentModelUsage segítségével lekérdezheti a CMS-t,


hogy a tartalomtípus azonosítója alapján megkapja a tartalomhoz kapcsolódó tartalmakat. Ez a
következőképpen történik:
var modelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var landingPageContentType = contentTypeRepository.Load<LandingPage>();
var landingPages = contentModelUsage.ListContentOfContentType(landingPageContentType);
FindPagesWithCriteria() - Oldalak keresése kritériumok alapján
A FindPagesWithCriteria() egy alapvető keresési API, amely az Episerverrel együtt jár. Míg az előző
módszerek lekérdezéseket használtak a tartalom megszerzéséhez, a FindPagesWithCriteria()
adatbázis-keresést végez. A FindPagesWithCriteria() az IPageCriteriaQueryService szolgáltatáson
keresztül érhető el. A FindPagesWithCriteria() elég erős és rugalmas. Ez azért van így, mert lehetővé
teszi, hogy összetett keresési lekérdezéseket. A FindPagesWithCriteria() használatára az alábbi példa
látható:

var repository = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();


var criteria = new PropertyCriteriaCollection();
var pages = repository.FindPagesWithCriteria(
PageReference.StartPage,
criteria);

Mielőtt elkezdenéd használni a FindPagesWithCriteria() funkciót, tudnod kell, hogy nincs


gyorsítótárazása. Minden alkalommal, amikor a FindPagesWithCriteria() segítségével keresést hajt
végre, egy adatbázis-lekérdezés történik. Ez a azt jelenti, hogy a FindPagesWithCriteria() időnkénti
meghívása elfogadható. Ha a FindPagesWithCriteria() funkciót gyakran kell hívnia, akkor a webhely
teljesítménye csökkenhet. Ha a webhely lassulását tapasztalja az ezt a szolgáltatást használó
oldalakon, akkor lehet, hogy meg kell fontolnia saját gyorsítótár vagy egy alternatív megközelítés
megvalósítását. A FindPagesWithCriteria() bemenetként egyetlen PropertyCriteria-val, vagy több
PropertyCriteria összekapcsolásával használható. Ehhez egy PropertyCriteriaCollection segítségével.
A PropertyCriteria célja a keresési eredmények szűrése. Az eredmények szűrhetők olyan
tulajdonságok alapján, mint az oldal neve, a közzététel dátuma és az oldal típusa.

Az alábbiakban egy olyan példát mutatunk, ahol a ContentTypeRepository-t egy landing page
oldaltípus azonosítójának lekérdezésére használjuk. Az oldaltípus-azonosítót egy PropertyCriteria-ban
használjuk az eredmények szűrésére. oldaltípus alapján:
var pageTypeId = ServiceLocator.Current.GetInstance<ContentTypeRepository>()
.Load<LandingPage>()
.First()
.ID;
var criteria = new PropertyCriteria
{
Condition = CompareCondition.Equal,
Name = "PageTypeID",
Type = PropertyDataType.PageType,
Value = pageTypeId,
Required = true
};
var filteredPages = repository.FindPagesWithCriteria(
PageReference.StartPage,
criteria);
A PropertyCriteria() osztály a következő tulajdonságokból áll:

• Condition: a szűrő típusát határozza meg. Az opciók a következők: NemEgyenlő, StartsWith,


EndsWith, Contained.
• Name: A PageData objektum azon mezője, amely alapján szűrni kell.
• Required - Kötelező: Egy bólusú tulajdonság, amely meghatározza, hogy a keresés feltételes
VAGY vagy feltételes ÉS kapcsolóként alkalmazza-e a feltételeket. Ha a Required értéke true,
akkor az AND operátor kerül alkalmazásra. Ellenkező esetben az OR operátor kerül
alkalmazásra.
• Type - Típus: Ez lehet Boolean, Number, FloatNumber, PageType, PageReference, Date,
String, LongString, Category vagy LinkCollection.
• Value - Érték: A keresési érték

Ha az oldal neve alapján kell szűrni, akkor egy ilyen kritériumot hozhat létre:
new PropertyCriteria()
{
Name = "PageName",
Type = PropertyDataType.String,
Condition = EPiServer.Filters.CompareCondition.Equal,
Value = "Search Term"
}

Az elmúlt hónapban létrehozott oldalak kereséséhez használhatja ezt:


var criteria = new PropertyCriteria
{
Condition = EPiServer.Filters.CompareCondition.GreaterThan,
Name = "PageCreated",
Type = PropertyDataType.Date,
Value = DateTime.Now.AddMonths(-30).ToString(),
Required = true,
};
A tulajdonságkritériumok összetett lekérdezések létrehozásához is láncolhatók, például így:
var criteriaCollection = new PropertyCriteriaCollection
{
new PropertyCriteria()
{
Name = "PageName",
Type = PropertyDataType.String,
Condition = EPiServer.Filters.CompareCondition.Equal,
Value = "search term"
},
new PropertyCriteria
{
Condition = CompareCondition.Equal,
Name = "PageTypeID",
Type = PropertyDataType.PageType,
Value = pageTypeId,
Required = true
}
};
var repository = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();
var pages = repository.FindPagesWithCriteria(
PageReference.StartPage,
criteriaCollection);

FindAllPagesWithCriteria() - Minden oldal keresése a kritériumok alapján


A FindPagesWithCriteria() csak nyilvános oldalak keresésére használható. A
FindAllPagesWithCriteria() mindenre használható, beleértve a publikált és nem publikált elemeket is.
Ez a hasznos lehet, ha egy backend adminisztrátori plugint kell létrehozni. A
FindAllPagesWithCriteria() funkciót soha nem szabad a nyilvános oldalon használni, mivel
potenciálisan érzékeny adatokat fedhet fel, nem közzétett adatokat vagy csak tagoknak szóló
oldalakat. A FindAllPagesWithCriteria használata nagyon hasonló a FindPagesWithCriteria
funkcióhoz. Az IPageCriteriaQueryService szolgáltatáson keresztül érhető el. A
FindAllPagesWithCriteria() szintén hajlamos a teljesítményproblémákra, ezért óvatosan. Az
IPageCriteriaQueryService használatának példája az alábbiakban látható:
var criteria = new PropertyCriteriaCollection
{
new PropertyCriteria();
};
var repository = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();
var pages = repository.FindAllPagesWithCriteria(
PageReference.StartPage,
criteria);

Ha összetett kereséseket kell végrehajtania a front-endről, akkor a tartalom keresését nem


közvetlenül az adatbázisban, hanem egy keresőindex segítségével kell elvégeznie. A következő
részben a a CMS-szel kompatibilis két indexalapú keresési megoldással.
Az Episerver két index-alapú keresőszolgáltatót biztosít, amelyeket használhat a webhelyén belül. Egy
ingyenes és egy fizetős szolgáltatást. Az ingyenes out-of-the-box szolgáltató neve EPiServer.Search. A
nem ingyenes termék egy szolgáltatásként nyújtott szoftveres termék, az Episerver Find.
EPiServer.Search
Az EpiServer.Search nagyon hasznos, ha egy meglehetősen szabványos, csak néhány ezer oldalt
tartalmazó webhelykeresést kell létrehoznia. Az EpiServer.Search szükség esetén eléri a határait:

• Könnyen pókhálózza a harmadik féltől származó adattárolókban tárolt adatokat.


• Intelligens keresés biztosítása mesterséges intelligencia segítségével
• A keresési fakciókat a dobozból történő kereséskorlátozás biztosítása
• Episerver kereskedelmi elemeket tartalmazzon
• terhelés-kiegyenlített környezetben dolgozni
• Keresési API biztosítása harmadik fél webhelyei számára

Ha a fenti tevékenységek bármelyikére szüksége van, akkor érdemes megfontolni a fejlettebb és


drágább EpiFind megvásárlását. Az Episerver.Search ingyenesen használható, és integrálható a
következőkbe bármely Nugetet használó webhelyre:
https://nuget.episerver.com/package?id=EpiServer.Search

Az Episerver.Search a Lucene nevű keresési technológián alapul. A Lucene a legtöbb nagy CMS-
rendszerben használt szabványos keresési szolgáltató. Out-of-the-box, amikor Episerver.Search
telepítése során egy Lucene index jön létre az App_Data mappában. Egy ütemezett feladat
segítségével az Episerver pókhálózza a weboldalt a tartalomszerkesztők által végzett
tartalomfrissítésekre. majd ezeket a változtatásokat a Lucene-indexbe teszi. Amíg az ütemezett
feladat fut, az indexnek mindig naprakésznek kell lennie.

Amint azt már előre láthatta, a fájlok tárolása a fájlrendszerben problémákat okozhat. Ha a
webhelyét több szerveren tárolja, akkor az egyes szerverek helyi indexei közötti különbségek a
következők lehetnek előfordulhatnak. Ugyanezek a problémák az Azure-on belül is előfordulhatnak,
ha engedélyezve van a webes skálázás. Az alábbiakban felsorolunk néhány kulcsfontosságú
szempontot, amelyek segíthetnek kiválasztani, hogy mikor válassza az Episerver.Search-et:

• Lucene széles körben használatos, így sok oktatóanyag van hozzá.


• Jobban testreszabható, mint néhány más ajánlat (például a Google Site Search).

Ezután következzenek az EpiServer.Search hátrányai:

• A terheléselosztás nem ideális, a különböző csomópontokon lévő külön indexek problémákat


okozhatnak
• Az index zárolódhat, ami tönkreteheti a dolgokat/nehezíti az index törlését.

Ha úgy döntesz, hogy az egyszerű keresés megfelel az igényeidnek, akkor a jó hír az, hogy az index
lekérdezéséhez szükséges kód is nagyon egyszerű. A keresési funkció használatához adja hozzá a
NuGet csomagokat EpiServer.Search.Cms és EpiServer.Search csomagokat a megoldásába.

Ha többet szeretne megtudni a keresés telepítéséről, akkor olvassa el ezt az útmutatót: A keresési
szolgáltatás telepítése és telepítése. Az Episerver.Search fájlból történő tartalomlekérdezéshez
szükséges kód az alábbiakban látható:
var repository = ServiceLocator.Current.GetInstance<SearchClient>();
var search = repository.UnifiedSearchFor("search term");

A Lucene-nel való munka során egy másik hasznos eszköz, amit érdemes ismernie, a Luke For Lucene.
Ez az ingyenes Java-alapú eszköz lehetővé teszi, hogy lekérdezze az indexek tartalmát.
EpiFind
A Lucene-nel való munka során egy másik hasznos eszköz, amelyet érdemes ismernie, a Luke For
Lucene. Ez az ingyenes Java-alapú eszköz lehetővé teszi az indexek tartalmának lekérdezését.

Fejléc és lábléc létrehozása


Ebben a részben az oldal bútorzatát fogjuk felépíteni. Először is a terminológia összehangolása
érdekében, amikor a "webhelybútor" kifejezést használom, akkor a webhely fejlécére és láblécére
utalok. A fejléc a az első dolog, amit az emberek látni fognak, amikor a webhelyre érkeznek. A fejléc
kialakításának arra kell ösztönöznie az ügyfeleket, hogy tovább kutassák az oldalát. A fejléc más
fontos oldalakra mutató linkeket tartalmaz a webhelyén, amelyeket a látogató érdekesnek találhat. A
fejlécnek extra információkat is kell nyújtania a felhasználó számára. Az olyan funkciók, mint a mini-
keresés, a kosár vagy a taginformációk AJAX-ot igényelhetnek. az oldal dinamikus frissítéséhez. Egyes
webhelyek webhelybútorainak felépítése nagyon összetett lehet. A komplexitás meghatározásához
vegye figyelembe ezeket a kérdéseket:

• Szükség van-e a fejlécnek saját tartalomra?


• Hol fogják tárolni a fejléc megjelenítéséhez szükséges adatokat?
• Szüksége van-e a láblécnek saját tartalomra?
• Hol fogják tárolni a fejléc láblécének megjelenítéséhez szükséges adatokat?
• Hogyan kezeli a globális beállításokat?
• A webhelyen többféle fejléc van?
• Öröklést vagy kompozíciót használjon a fejléc és a lábléc felépítéséhez?
• Hogyan tudja kihasználni a gyorsítótárazást a teljesítmény javítása érdekében?
• Milyen menükre van szükség?
• Hogyan hozzon létre kenyérmorzsát?
• Szükség van nyelvváltóra?
• Befolyásolja-e a menüt a személyre szabás bármilyen formája, pl. egy tagok területe?
• Van gyorskereső?
• Szükség van mega menüre?
• Mennyire kell összetettnek lennie a gyorskeresésnek?
• Szükség lesz-e API-k létrehozására bármely AJA-összetevőhöz?
• Hogyan változik mobil nézetben?

A helyszíni bútorok építésénél nincs minden projektnél működő, egyféle megközelítés. Eddig a pontig
kevés befolyása volt arra, hogy hogyan épüljenek fel a dolgok a következőkben a CMS-ben. Minden
egyes létrehozott oldalnak volt egy logikus helye a CMS-en belül. A dolgok most kissé megváltoznak.
El kell döntenie, hogy az oldal felépítéséhez szükséges adatok hol legyenek. a CMS-en belül. Annak
érdekében, hogy mindenki azt kapja ebből a fejezetből, amire szüksége van, minden lépésnél
részletezni fogom a különböző lehetőségeket, amelyek az Ön rendelkezésére állnak. Bemutatom
Önnek az egyes lehetőségek előnyeit és hátrányait, hogy eldönthesse, melyik opció a megfelelő az Ön
számára.

A megrögzött CMS-veteránoknak nagyon is határozott elképzeléseik lehetnek arról, hogyan kell


felépíteni egy Episerver weboldalt. Az ebben a részben felsorolt néhány megközelítés akár ellentétes
is lehet azzal, ahogyan ők szeretik csinálni a dolgokat. I határozottan a helyükben találtam magam.
Valójában néhány általam választott minta egyszerűen azért jött létre, mert az emberek nem tudtak
megegyezni egy megközelítésben. Azt tanácsolom mindenkinek, aki szembesül egy új típusú
problémával szembesül, hogy elsőre a legkisebb ellenállás útját válassza. Miután már van néhány
projekt az öved alatt, jobb alkalom a kísérletezésre.

Settings - Beállítások
Az első fontos döntés, amit meg kell hoznia, hogy hol tárolja a globális beállításokat. A globális
beállítások minden projekt alapvető szempontja. A fejléc és a lábléc által megkövetelt adatok valahol
tárolni kell. A webhelybútorokon kívül azt is meg kell fontolnia, hogy hol tárolja az összes általános,
az egész webhelyre kiterjedő metaadatot, a funkciójelzőket, valamint minden egyéb, különféle
beállításokat. A nehéz kérdés az, hogy hol?

1. lehetőség - Web.config: A legegyszerűbb lehetőség az alkalmazáson belüli konfigurálható


beállítások megadására, ha azokat alkalmazásbeállításokként adjuk hozzá a web.config fájlban. A
fejlesztési erőfeszítés szempontjából az app beállítások könnyen beállíthatók és megvalósíthatók. Ha
olyan projekten dolgozik, ahol egyszerű és alacsony kockázatú a kód kiadása, ez elfogadható
megközelítés lehet. Ha Ci/Cd eszközt használ, mint például az Octopus, akkor a beállítások
módosításának lehetősége a build eszközön belül is segíthet a beállítások gyors és alacsony kockázatú
frissítésében.

Az alkalmazásbeállítások használatának számos hátulütője van. Az első nyilvánvaló hátránya, hogy


valahányszor meg kell változtatnia egy beállítást, a frissítéseket be kell tolnia a termelésbe. Ha egy
nagy forgalmú webhelyen, például egy nagyon forgalmas e-kereskedelmi áruházban, akkor a
szükségtelen telepítések gyártásba történő bevezetése valószínűleg elfogadhatatlan megoldás lesz.

Ennek a megközelítésnek a másik hátránya, hogy a tartalomszerkesztők nem lesznek képesek saját
maguk számára módosítani a beállításokat. Az alkalmazásspecifikus beállítások esetében ennek lehet
értelme, nem szeretnénk, ha egy tartalomszerkesztő frissítse a webhely SQL-kapcsolati
karakterláncát. A webhely funkcionalitásával kapcsolatos beállítások esetében ennek már kevésbé
van értelme. Egyes vállalatok például frissíthetik a webhely logóját.

Az évszaktól függően előfordulhat, hogy karácsonyi vagy halloweeni témájú logót szeretnének
alkalmazni. Nem lenne értelme a logó URL-címét a web.config fájlban tárolni. Ahogy a projekt fejlődik

a tartalomszerkeszthető beállítások iránti igény növekedni fog. Ez felveti a következő kérdést, hogy
hova kerüljenek a tartalom szerkeszthető beállítások?

2. lehetőség - A StartPage: Az Episerver nem biztosít külön területet a globális beállítások kezelésére
a CMS-en belül. Ez azt jelenti, hogy Önön múlik, hogy hol szeretné tárolni a webhelybeállításokat. A
leglogikusabb hely a globális beállítások tárolására az Episerver-en belül egy oldal, valahol a fő
tartalomfán belül. Néhány fejlesztőnek határozott véleménye van ezzel a megközelítéssel szemben.

Ennek az álláspontnak az az indoklása, hogy a tartalom és a webhelybeállítások ugyanazon a


területen belüli keveredése még zavarosabbá teszi a platform használatát.

Ha nagyon határozottan úgy éreznéd, hogy nem egy oldalt használsz a beállítások tárolására, akkor
bevezethetsz egy extra technológiát, például egy egyéni SQL adatbázist, vagy egy NoSql szolgáltatást,
például Mongo-t a beállítások kezelésére.

Ha úgy dönt, hogy ezt az utat választja, akkor ne feledje, hogy valószínűleg egy egyéni admin panelt
kell létrehoznia, hogy az emberek ezeket a beállításokat is kezelni tudják. Ez a megközelítés
életképes, de én nem hogy a fejlesztési erőfeszítés és az infrastruktúra költségei csak a beállítások
miatt indokoltak.
Az egyszerűség kedvéért a beállításokat célszerűbb a tartalomfán belül tárolni. Ha ezt az utat
választjuk, akkor a nehezebb rész annak eldöntése, hogy a beállítások pontosan hol legyenek a
tartalomfán belül. Éljenek. Sok fejlesztő arra a következtetésre jut, hogy a leglogikusabb hely a
beállítások tárolására a kezdőlap. A szokásos megközelítés az, hogy létrehoznak egy "beállítások"
vagy valami hasonló nevű lapot. Ez a ez a lap lesz a globális beállítások lerakóhelye. A kód
szempontjából a beállítások elérése a kezdőlapon egyszerű. A PageReference.Start segédprogram és
az IContentRepository.Get it segítségével. segítségével egyszerűen hozzáférhetünk a beállításokhoz.
Ideálisnak hangzik, igaz?

A projekt kezdetén nem valószínű, hogy tudni fogja, hány beállításra lesz szüksége. Ahogy egyre több
oldalt és blokkot kezd el építeni, az új beállítások iránti igény növekedni fog. A projekt kezdetén
projekt elején nagyon könnyű megérteni az egyes beállítások célját. Az idő előrehaladtával és a
projekt fejlődésével ez nem mindig lesz így. Nem ritka, hogy egy projekt a következővel végződik
beállítások százai. Sok olyan beállítás, amelynek egykor világos célja volt, kezdhet tisztázatlannak
tűnni. Amikor ezek a kódszagok elkezdenek belopódzni a megoldásba, a problémát általában
túlságosan is magas kockázatúnak és kezelhetetlennek tartják ahhoz, hogy megpróbálkozzanak a
refaktorálással.

Ahogy a beállítások mennyisége növekszik, a honlap egy isteni osztállyá válhat. Amikor a honlapnak
túl sok felelőssége lesz, a rendszer egyetlen hibapontjává válik. A probléma az isten-osztállyal az,
hogy ha ez meghibásodik, akkor az egész rendszer meghibásodik. A kérdés tehát továbbra is az, hogy
hol tároljuk a beállításokat?

Avoid Refactoring Existing Properties - A meglévő tulajdonságok átdolgozásának


elkerülése

Mielőtt rátérnénk a beállítások kezelésének alternatív módjaira, érdemes tisztázni, hogy miért
érdemes elkerülni a tulajdonságok refaktorálását a kezdőlapon. A meglévő tulajdonságok
újragondolása az Episerverben óvatosan kell elvégezni.

Ha megpróbálja megváltoztatni egy olyan tulajdonság típusát egy olyan oldalon vagy blokkban a
CMS-en belül, amelyhez már létező adatok kapcsolódnak, az Episerver adatbázis-romlással
szembesülhet. Amikor ez megtörténik Az Episerver kivételt dob. Mivel az Episerver kód-első
megközelítést használ, egy meglévő tulajdonság refaktorálásához azt a kódban kell elvégezni.
Képzeljük el, hogy refaktorálunk egy 'Title' nevű tulajdonságot, amely egy string volt, boolean
értékűvé alakítjuk. A kódban semmi sem akadályozza meg, hogy ezt megtegye. Amikor újrafordítod
és újratöltöd a webhelyet, az Episerver egy kivételt generálhat az eltérés miatt. Mivel a tartalom
eltérhet a helyi adatbázis és a termelési adatbázis között. Egy refactor, ami az egyik adatbázisban
működött, nem garantálja, hogy egy másik adatbázisban nem okoz adatbázis-romlást.

Képzelje el, hogy refaktorált egy beállítást a kezdőlapon, és sikeresen tesztelte a változtatást a pre-
production szerveren. Amikor a kódot átviszi a termelésbe, az adatbázis sérülése következik be. A
honlap a termelésben megszakad, az adatok a pre-prodban mások voltak, mint a termelésben. A
helyzetet tovább rontja, hogy a fejléc néhány globális beállításra támaszkodik a helyes működéshez.
Ha a a kezdőlapot használják az összes oldalbeállítás tárolására, az egész oldal tönkremegy.

Az Episerver lényegében egyfajta megváltoztathatatlan főkönyv. Amikor egy oldal vagy egy blokk
frissül, az előzményei soha nem törlődnek. Csak azért, mert egy oldal aktuális verziója működik,
miután egy tulajdonságot átdolgozás után, ez nem jelenti azt, hogy az összes múltbeli adat továbbra
is működni fog.

TIPP: Ha valaha is találkozik ezzel a problémával a termelésben, akkor a változtatás visszaállításának


leggyorsabb módja a kód visszaállítása. A kód visszaállítása után, ha szerencséje van, az oldal újra be
fog töltődni. Ha nincs szerencséje, és az adatbázis megsérül, a webhely helyreállításának leggyorsabb
módja az SQL visszaállítása lehet.

Amikor a honlap isteni osztállyá válik, és túl kockázatossá válik a refaktorálás, kódszagok jelennek
meg. Visszatérve Bob Martin Clean Architecture című könyvére, a jó architektúrális döntésnek a
következőnek kell lennie ami olcsóbbá teszi a rendszer karbantartását és gyorsabbá a változtatást. E
definíció alapján a honlap globális szemétlerakóként való használata sérti ezt az elvet. Ezért javaslom,
hogy hogy más megközelítést válasszon.
Storing Global Data Within A Block - Globális adatok tárolása egy blokkban
Ahelyett, hogy a globális beállításokat a kezdőlapon tárolnánk, jobb és biztonságosabb alternatíva, ha
létrehozunk egy beállítási blokkot. Ebben a mintában azonban a kezdőlap továbbra is használható a
beállítások tárolására, a beállítások eltávolításra kerülnek az oldalról, és egy blokkba kerülnek. A
kezdőlap meghatározhat egy "beállítások" nevű tartalmi terület tulajdonságot, vagy valami
hasonlóan kreatívat. A beállítási blokk lehet a CMS-en keresztül az oldalhoz társítható. A globális
beállítások blokkjának soha nem lesz vezérlője vagy nézete. Egyetlen célja az összes globális beállítás
tárolása. Blokkok használata a beállítások tárolására egyszerűbbé teszi az életet, mintha a
beállításokat közvetlenül az oldalon mentenénk el. Először is, továbbra is könnyen elérhető a
kezdőlap a kódban. Másodszor, a refaktorálás kockázatmentes. Biztonságosabb egy blokkot
refaktorálni. Mintha a tulajdonságokat közvetlenül a kezdőlapon változtatnánk meg. Végül, ha egy
tartalmi területet használ a beállítások tárolására, nem korlátozódik arra, hogy csak egyetlen
egységet használjon.

Csoportosíthatja a kapcsolódó típusokat beállításokat különböző blokkokba. Így létrehozhat ilyen


beállítási blokkokat:

• Fejlécbeállítások
• Lábléc beállításai
• SEO beállítások
• Menü beállítások

A másik jó dolog a beállítási blokkok használatával kapcsolatban, hogy nagyon egyszerű a kezelése.
Ha a beállítások egy csoportjára már nincs szükség, a blokk nagyon könnyen eltávolítható a CMS-en
belül. Gyorsan demonstráljuk ezt a megközelítést. A beállítások tárolásához meghatározhat egy
tartalmi területet beállítási típusonként, például így:
public class StartPage : PageData
{
[Display(
Name = "Header Settings",
Description = "Header.",
GroupName = "Settings",
Order = 10)]
public virtual ContentArea HeaderSettings { get; set; }
[Display(
Name = "Footer Settings",
Description = "Footer.",
GroupName = "Settings",
Order = 20)]
public virtual ContentArea FooterSettings { get; set; }
}
Ez rendben van, de ez még mindig több lehetséges honlapváltozást jelent a későbbiekben. Egy még
egyszerűbb lehetőség, ha létrehoz egy beállítási területet, például így:
public class StartPage : PageData
{
[Display(
Name = "Global Settings",
Description = "Settings.",
GroupName = "Settings",
Order = 10)]
public virtual ContentArea GlobalSettings { get; set; }
}

A beállítási blokkdefiníció pontosan úgy néz ki, mint bármely más blokk típusú definíció:
/// attributes go here
public class HeaderSettings : BlockData
{
[Display(
Name = "SomeProperty",
Order = 10)]
public virtual string SomeProperty { get; set; }
}

Storing Global Data Within A Settings Page - Globális adatok tárolása egy beállítási oldalon belül
Ha a beállítások számára külön blokkok létrehozása nem felel meg Önnek, akkor a beállítások
kezelésének egy másik gyakori megközelítése egy beállítási oldal-típus létrehozása. Ekkor a
webhelyek összes globális beállítása hozzáadhatók a beállítások oldalához. Ebben a megközelítésben
a beállítások oldal-típus és annak minden tulajdonsága a szokásos módon jön létre. Célszerű, hogy a
beállítási oldal a webhely fastruktúráján kívül éljen.

Azt tanácsolom, hogy a gyökér gyermekeként hozza létre. Ha a beállítások oldala a kezdőlap alatt él,
az kevésbé biztonságos. Ebben a konfigurációban az oldal vagy annak adatai potenciálisan a
következő módon kerülhetnek nyilvánosan hozzáférhetővé válhat, például indexelhetővé válhat a
keresőben!

Ahhoz, hogy a beállítások oldalához kódban hozzáférhessen, több lehetősége is van:

Hardcore Az id(Hardcore The Id): A beállítás, az oldal létrehozása után tudni fogja az oldal
azonosítóját. Ezt az értéket aztán a web.config alkalmazásbeállításokban hardcore-olhatod. Mivel a
beállítások oldala soha nem lesz törlődik, az ID ilyen módon történő kemény kódolása nem túl
kockázatos, mivel az ID soha nem fog változni.

Page-Picker: Definiáljon egy oldalválasztót a kezdőlapon, így a beállítások oldala a CMS-en keresztül
állítható be. Ez a megközelítés két lekérdezést igényel a beállítási oldal eléréséhez. Az egyik, hogy
megkapjuk a beállítási oldal azonosítóját a kezdőlapról, majd egy másikat a beállítási oldal
lekérdezéséhez.
Beállítások gyára ( Settings Factory): Hozzon létre egy beállítási oldal gyárat, és keresse meg az oldalt
az oldal típusa alapján, az IContentTypeRepository segítségével. Feltételezve, hogy csak egyetlen
beállítások-oldal típusú oldal lesz, akkor ez egyszerű.

Setting Page Combined With Settings Blocks - Beállítási oldal kombinálva a beállítási blokkokkal
Végül, a beállítások oldalon blokkokon belül is csoportosíthatja a kapcsolódó beállításokat. Így
mindkét világból a legjobbat kapja. Ebben a szakaszban már érti a lényeget. Hozzon létre egy
beállítási oldal-típust egy content-area-t, és adjon hozzá minden kapcsolódó beállítást blokkként.
Which Approach Should I Take - Melyik megközelítést válasszam
Egy általánosan elfogadott tervezési elv szerint a laza csatolást és a nagyfokú kohéziót kell előnyben
részesíteni. A nagyfokú kohézió azt jelenti, hogy az osztályon belüli elemeknek funkcionálisan
összetartozniuk kell, és nem szabad egy bizonyos dolgot. A laza csatolás definíciója az, hogy az
osztályok között minimális függőségnek kell lennie.

Az Episerver-en belüli beállítások tárolásakor a beállítások lapja a beállítási blokk mintával az a


megközelítés, amely leginkább hasonlít erre a definícióra. A blokk használata lehetővé teszi a
csoportosítást a beállítások csoportosítását, amelyek logikailag összetartoznak. Végül, a beállítások
tartalmi területen belüli hozzáadása megkönnyíti a tartalom kezelését. Tapasztalataim alapján ezt a
megközelítést javaslom. A továbbiakban feltételezem, hogy a beállítási blokkminta mellett döntött.
Most már van módja a beállítások tárolására. A következő szempont az, hogy hogyan lehet a
beállításokhoz hozzáférni a következő részből a mester elrendezésből.

The Master Layout - A mester elrendezés


Ez a szakasz a beállítások elérésének különböző módjait mutatja be a mester elrendezésen belül. Az
előző fejezetben a nézetmodellek használatának előnyeit tárgyaltam. Ugyanez a tervezés elv
érvényes a mester elrendezéssel való munka során is. A jó tervezési elv követése érdekében kerülni
kell a logika hozzáadását és a kódok közvetlen elérését az elrendezés HTML-jén belül. Mivel a mester
elrendezés az oldal renderelési folyamatának tetején helyezkedik el, az elrendezésen belüli adatok
eléréséhez más mechanizmusra lesz szükség. Sajnos ez nem olyan egyszerű, mint az adatok átadása
közvetlenül egy vezérlőből egy nézetbe. Először is, foglaljuk össze gyorsan, hogyan lehetne felépíteni
egy nagyon egyszerű globális elrendezésfájlt:
<!DOCTYPE html>
<html>
<head>
// Render SEO Stuff
</head>
<body>
@Html.RenderEPiServerQuickNavigator()
@Html.FullRefreshPropertiesMetaData()
// Render Header
@RenderBody()
// Render Footer
</body>
</html>

Foglaljuk össze, hogy mi történik itt:

• A FullRefreshPropertiesMetaData() lehetővé teszi az inline szerkesztést.


• A RenderEPiServerQuickNavigator() egy apró menüt jelenít meg, amikor egy CMS-szerkesztő
bejelentkezett, hasznos CMS-linkekkel.
• A RenderBody() megjeleníti az oldalvezérlő kimenetét. Ez egy szabványos MVC segédosztály.
Layout ViewModel
Ebben a megközelítésben az elrendezés renderelése előtt az oldal kérését elfogjuk, és egy globális
nézetmodellt injektálunk a kérési objektumba. Ez a globális nézet-modell az összes adat átadására
szolgál. Az elrendezési fájl által igényelt adatok átadására. A nézet-modell átadása a globális
elrendezésbe a leggyakrabban használt megközelítés, amellyel találkoztam. Azért olyan népszerű ez a
megközelítés, mert ez a így működött az eredeti Alloy demo oldal. Az új Episerver-fejlesztők
hajlamosak lemásolni az Alloy-oldal működését, így természetesen ez lett a defacto szabvány.

Ez a minta egy ResultFilter használatával működik. Az eredményszűrő egy előfeladat, amelyet a .NET
csővezeték lefuttat, mielőtt a végrehajtást átadná a vezérlőnek. Az eredményszűrőben szükséges:

• A webhelybútorok megjelenítéséhez szükséges összes adat kinyerése az Episerverből.


• A nézeti modell létrehozása
• Hozzáadni a kérelemhez

Ez a minta hasonlít a hagymaarchitektúrához. Az elrendezésnek fogalma sincs a meghívott oldalról.


Az oldalvezérlő viszont nem tudja befolyásolni az elrendezést. Tegyük fel, hogy ezt a nagyon kitalált
példát:

public class GlobalLayoutViewModel()


{
public string ExampleProperty { get; set; }
}

A ResultFilter kódja így nézne ki:


public class PageLayoutActionFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
var model = filterContext.Controller.ViewData.Model;
var layoutModel = model as GlobalLayoutViewModel;
if (layoutModel != null)
{
var layout = new GlobalLayoutViewModel();
model = layout;
// Do some custom logic here
}
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}

A ResultFilteren belül a bejövő kontextus átadásra kerül az OnResultExecuting-be. Az


OnResultExecuting-en belül hozzáférünk az aktuális vezérlő tulajdonságához. A nézetmodellt
hozzáadjuk az aktuális kéréshez aResultExecutingContext.Controller.ViewData.Model tulajdonság
beállításával. A nézetmodell hozzárendelése ehhez a tulajdonsághoz azt jelenti, hogy az elrendezésen
belül egy háttértípusú modell lehet kötni. Az if utasításon belüli kódot arra kell használni, hogy az
oldalbútor által igényelt összes adatot megkapja, létrehozzon egy új elrendezés nézetmodellt, majd
ezt a nézetmodellt hozzárendelje a ViewData.Model értékhez.

Ne feledje, hogy az alkalmazáson belül regisztrálnia kell a ResultFilter-t, mielőtt használni fogja. Ezt a
regisztrációt egy inicializáló modul segítségével végezheti el. Az inicializáló modul egy Episerver
eseménykezelő, amely lehetővé teszi, hogy az alkalmazás indításakor néhány egyéni kódot futtasson.
Az inicializáló modul létrehozásának módját részletesen a 9. fejezetben tárgyaljuk. A létrehozandó
kód inicializáló modul létrehozása és a PageLayoutActionFilter regisztrálása az alábbiakban látható:
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class FilterConfig : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
GlobalFilters.Filters.Add(ServiceLocator.Current.GetInstance<PageLayoutActionFilter>());
}
public void Uninitialize(InitializationEngine context)
{
}
public void Preload(string[] parameters)
{
}
}

MEGJEGYZÉS Ez a részlet a ServiceLocator-t használja, ami egy anti-pattern, és jobb elkerülni. Az


inicializáló modulokon belül nem használhatja a konstruktor injektálást, így kénytelen a
ServiceLocator-t kell használnod.

A kéréshez csatolt GlobalLayoutViewModel segítségével a nézeti modell a @model használatával az


elrendezéshez köthető, például így:

@model GlobalLayoutViewModel
<!DOCTYPE html>
<html>
<head>
// Render SEO Stuff
</head>
<body>
@Html.RenderEPiServerQuickNavigator()
@Html.FullRefreshPropertiesMetaData()

<div class="header">
@Model.ExampleProperty
</div>

@RenderBody()
// Render Footer
</body>
</html>
Ennek a megközelítésnek az az előnye, hogy lehetővé teszi az adatok és a HTML tiszta szétválasztását,
ami jó. Az egyetlen nézeti modell használatának hátránya, hogy egy újabb kódterületet vezet be. Ami
valószínűleg egy istenosztály lesz. Mivel a GlobalLayoutViewModel-nek minden olyan beállításról
gondoskodnia kell, amelyre minden oldalnak szüksége van. A legtöbb projektben ez a nézetmodell
hajlamos nagyon nagy és nehézkes érthetővé válik. Ahogy folytatjuk ezt a szakaszt, meg fogom
tárgyalni a különböző módszereket, amelyekkel megakadályozhatjuk, hogy ez megtörténjen. Az első
ezek közül a blokkok felhasználása a beállítások tárolására.

Végül, ha nehezen érti meg, hogyan működik ez a folyamat, azt javaslom, hogy lépjen végig a kódon
az Alloy mintaoldalon. A hibakereső csatolását ajánlom ide.

Ennek a megközelítésnek az az előnye, hogy lehetővé teszi az adatok és a HTML tiszta elkülönítését,
ez jó. A hátránya a nézeti modell egytermészetű célja. Ez az óriási nézetmodell valószínűleg egy
istenosztály lesz. A nézetmodell hajlamos nagyon nagyra nőni, és több száz tulajdonságot
tartalmazhat.

The View Bag Approach - A táskás megközelítés


A beállítások kezelésének másik megoldási módja az adatok átadása az elrendezésbe a ViewBag-en
keresztül. Nem ajánlom, hogy ezt tegye, de a teljesség kedvéért az építészeti Megközelítések,
amelyeket használhatsz, így lehetséges:

public class MyController : Controller


{
public MyController()
{
var model = new LayoutViewModel();
this.ViewData["LayoutViewModel"] = model;
}
}

Az elrendezésben így érheti el a nézeti modellt (In the layout you ca access the view model like this):
@{
var viewModel = (LayoutViewModel)ViewBag.LayoutViewModel;
}

A nézet-modell hozzáadása az egyes vezérlőkben lévő elrendezésen belül nem ideális. Ez ismét sérti a
DRY elvét. Ennek következtében ez a jövőben sok refaktorálási rémálomhoz vezethet.

PropertyFor()
Egy másik téma, amivel még nem foglalkoztunk. Az elrendezés megjelenítéséhez szükséges összes
HTML-nek magában az elrendezési fájlban kell lennie, vagy tovább kell osztani részleges nézetekre?

Ha a globális elrendezésen belüli HTML tartalmazná a fejléc és a lábléc kódját is, akkor a jövőben
nehezebb lenne módosítani. Mit tennél például, ha hirtelen szükséged lenne a következőre egy új
típusú fejlécet kellene létrehozni, amelyet bizonyos oldalakon kellene megjeleníteni? Teljesen új
elrendezést hozna létre? Ez rengeteg duplikált HTML-t eredményezne. Hatékonyabb lenne, ha
egyszerűen kicserélni a fejléc megjelenítéséhez szükséges HTML-t.
A rugalmas kialakítás érdekében célszerű az elrendezésben a HTML-t funkció szerint elkülöníteni. A
fenti példában, ha új fejlécet szeretne létrehozni, akkor a fejlécet egy új nézetben hozhatja létre.

és az elrendezésen belül egy funkcióváltó segítségével határozhatná meg, hogy melyik nézet jelenjen
meg. Másodszor, ha a különböző webhelybútor-összetevők külön nézetekben vannak tárolva, a
globális elrendezés lehet fel lehet osztani. Minden nézetnek saját nézetmodellje is lehet, ami tovább
javítja a tervezésünket.

Ha tartalmi területeket és blokkokat használunk a fejléc és a lábléc beállításainak tárolására, akkor ez


a HTML-en belüli szétválasztás könnyen megvalósítható a PropertyFor() segédprogrammal. A
IResultFilterben a ServiceLocator segítségével az IContentRepository-n keresztül elérhetjük a
beállítási oldalt, így:

public class PageLayoutActionFilter : IResultFilter


{

public void OnResultExecuting(ResultExecutingContext filterContext)


{
var model = filterContext.Controller.ViewData.Model;
// Custom code here
var layoutModel = model as Layout;
if (layoutModel != null)
{
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var settingsPage = repo.Get<SettingsPage>(102);
var layout = new GlobalLayoutViewModel
{
Header = settingsPage.Header,
Footer - settingsPage.Footer
}
model = layout;
}
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}

A globális elrendezési modell kódja így nézhet ki:


public void GlobalLayoutViewModel
{
public ContentArea Header { get; set; }
public ContentArea Footer { get; set; }
}
Mint bármely más Episerver tulajdonság, a PropertyFor() is használható a blokk renderelésére, ahogy
az alábbiakban látható:
@model GlobalLayoutViewModel
<!DOCTYPE html>
<html>
<head>
// Render Head
</head>
<body>
@Html.RenderEPiServerQuickNavigator()
@Html.FullRefreshPropertiesMetaData()
@Html.PropertyFor(x => x.Header)
@RenderBody()
@Html.PropertyFor(x => x.Footer)
</body>
</html>

Az egyetlen kód, ami hiányzik ahhoz, hogy mindez működjön, a fejléc és a lábléc kapcsolódó vezérlői,
valamint a megfelelő nézet-modellek és nézetek. A megfelelő blokk-típus nélkül vezérlő nélkül a
fejléc blokk és a lábléc blokk 404-es hibaüzenetet fog eredményezni. A beállítási blokk vezérlőjének
létrehozása pontosan ugyanolyan, mint bármely más blokké. Amint az alább látható:
public class FooterBlockController : BlockController<FooterBlock>
{
public override ActionResult Index(FooterBlock currentContent)
{
var footerViewModel = // get FooterViewModel()
return PartialView("Index", footerViewModel );
}
}

A lábléc vezérlő létrehozásához örökölje a BlockController-t és használja a FooterBlock-ot T-ként.


Még mindig jó gyakorlat egy ViewModel használata. A megfelelő nézetet a views/partials mappában
kell létrehozni:
@model FooterViewModel
<footer class="main-footer">
</footer>

Ez a minta sokkal tisztább, mintha egyszerűen mindent az elrendezésen belül csinálnánk. A jövőben
frissítheti a fejléc blokkot és annak HTML-jét anélkül, hogy az elrendezést módosítania kellene. Ez a
nyitott/zárt elv a gyakorlatban.

Partial Views - Részleges nézetek


A következő megközelítés a vanilla MVC által biztosított funkciókat használja az elrendezés
szétválasztásához. Ebben a mintában a szabványos Html.Action() metódust használjuk arra, hogy a
HTML-ben összeállítsuk a szükséges HTML-t a fejléc és a lábléc helyett. Ebben a megközelítésben a
HTML.Action() további vezérlők hívására szolgál, amelyek a megfelelő HTML megjelenítésére
használhatók. Egy olyan webhelybútor-vezérlő létrehozásával, amely a fejléchez, a lábléchez és az
oldalak metaadataihoz egy-egy műveletet állít ki, biztosíthatja a gondok szép elkülönítését. Minden
egyes művelet felelős lehet a saját adatainak megszerzéséért, saját nézetének létrehozásáért.
modellekért, és a kapcsolódó HTML megjelenítéséért.

Ez a szétválasztás ortogonális architektúrát tesz lehetővé. Ez azt jelenti, hogy csak egy dolgot lehet
megváltoztatni anélkül, hogy bármi mást befolyásolna. A lábléc megváltoztatásához ebben a
megközelítésben csak a kódot kell megváltoztatni, amely a lábléchez kapcsolódó kódra lesz hatással.
Ezzel szemben a globális nézetmodell megközelítéssel szemben a változtatás a nézetmodell, az
eredményszűrő és az elrendezés HTML frissítését vonná maga után. Mindezek megtörhetik a az
elrendezés más területeit. Ezt a mintát követve a dolgok jelentősen leegyszerűsíthetők:
<!DOCTYPE html>
<html
<head>
</head>
<body>
@Html.Action("Header", "Partial")
RenderBody()
@Html.Action("Footer", "Partial")
</body>
</html>

A vezérlő kódja így fog kinézni:


public class PartialController : Controller
{
public PartialController(ISettingsFactory factory)
{
// we have our global settings being injected for easy access
}
[HttpGet]
public ActionResult Header()
{
return PartialView("Header", new HeaderViewModel());
}
[HttpGet]
public ActionResult Footer()
{
return PartialView("Footer", new FooterViewModel());
}

}
Amint láthatja, a vezérlő nem különleges. Vanília MVC-t használ. A HTML az elrendezésben tiszta. A
nyitott/zárt elvet követi. Egy másik előnye a különálló akciónak, hogy a az eredmények gyorsítótárba
helyezhetők: Az OutputCache attribútum alkalmazásával jelentősen javíthatja a teljesítményt,
miközben növelheti a kiszolgáló kapacitását:
[OutputCache(Duration = 3600)]
public ActionResult RenderHeader()
{
return PartialView("Header", new HeaderViewModel());
}

Bármely oldal első meghívásakor a fejléc HTML-je feldolgozódik, és egy órán keresztül gyorsítótárba
kerül. A következő kéréskor a fejléc visszakerül a gyorsítótárból. Most ahelyett, hogy a a HTML-t újra
generálni, a fejléc a gyorsítótárból szolgáltatható ki, így az oldalak betöltése is gyorsabbá válik!

Ha ezt a megközelítést alkalmazza, akkor regisztrálnia kell a részleges vezérlőt az útválasztási


táblázatban. Az útvonal regisztrálása ugyanúgy történik, mint a normál vanilla MVC-ben, pl. az
útvonal konfigurációban a global.ascx:
RouteTable.Routes.MapRoute(
"SharedPartial",
"Partial/{action}/{id}",
new
{
controller = "SharedPartial",
action = "Index",
id = UrlParameter.Optional
});

Mint látható, sok lehetőség van arra, hogy adatokat adjunk át egy elrendezésbe. Válassza ki azt,
amelyik boldoggá teszi. Javaslom, hogy a részleges vezérlő útvonalat válassza.
Building The Head - A fejléc építése
Ebben a szakaszban megtanulhatja, hogyan tervezzen meg néhány olyan összetevőt, amelyet a
fejlécbe kell beépítenie. Az első dolog, amit meg kell tervezni, a menü. Minden weboldalnak szüksége
van egy menüre, hogy segítsena látogatókat a webhelyen való átkelésben. Front-end szempontból a
menük nagyon különbözően nézhetnek ki és viselkedhetnek. Back-endben a menüelemek
lekérdezéséhez a CMS-ben használt kód szabványosabb. A két leginkább a CMS-ben a menü
felépítésének két leggyakoribb módja:

• Egy egyszerű menü, amely a kezdőlap alatt megjelenít néhány gyermek menüt.
• Egy összetett "mega-nav", ahol az oldalak és a linkek nem kapcsolódnak az oldalszerkezethez.

Mivel az egyszerű menü a legkönnyebben felépíthető menü, ezért ezzel kezdjük.

Building A Simple Menu - Egyszerű menü építése


Egy egyszerű menüstruktúrában a menüben megjelenített elemek a kezdőlap alatti legfelső szintű
oldalakról kerülnek ki. Vegyük ezt az oldalszerkezetet a CMS-en belül;

• Kezdőlap
o 1.oldal
o 2.oldal
o 3.oldal

Egy egyszerű menü kialakítását követően a honlap gyermekei jelennek meg, pl. "Page 1", "Page 2" és
"Page 3". Kódexszerűen az IContentRepository.GetChildren() metódus használható,

például így:
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var menuItems = contentRepository.GetChildren<PageData>(PageReference.StartPage)
.Where(x => x.VisibleInMenu);

TIPP 1 Ha nem szeretné az összes oldalt megjeleníteni a kezdőlap alatt, akkor a VisibleInMenu
tulajdonság segítségével szűrheti az oldalakat. A VisibleInMenu egy olyan mező, amely a PageData
osztályban van definiálva. így minden oldalon elérhető. A CMS-en belül megtalálja, ha megnyitja
bármelyik oldalt, és a szürke felső beállítási területen látnia kell a VisibleInMenu nevű
jelölőnégyzetet.

TIPP 2 Ha azt szeretné, hogy minden oldal alapértelmezés szerint rejtve legyen a menüből, akkor az
oldaltípus definícióján belül a SetDefaultProperties() funkcióval beállíthat egy alapértelmezett
értéket, amikor egy új oldal az adott típusú oldal létrehozásakor. A SetDefaultProperties()
segítségével a VisibleInMenu értékét false-ra állíthatja.

Ezt a mintát követve a fejléc nézetmodell egy IEnumerable<PageData> típusú tulajdonságot állítana
ki Menu néven, hogy a menüelemek elérhetők legyenek a nézeten belül:
public class HeaderViewModel
{
public IEnumerable<PageData> Menu { get; set; }
}
Megjegyzés: Ez a kód az egyszerűség kedvéért visszaadja a PageData objektumot a nézetnek. Jobb
megközelítés lenne, ha helyette egy nézeti modellt adnánk vissza. A menüelemek kinyerésére
szolgáló kódot ezután a Header műveletben helyeznénk el:
public class PartialController : Controller
{
private IContentRepository _repo;
public PartialController(IContentRepository repo)
{
_repo = repo;
}
[HttpGet]
public ActionResult Header()
{
var headerViewModel = HeaderViewModel
{
Menu = _repo.GetChildren<PageData>(PageReference.StartPage)
.Where(x => x.VisibleInMenu);
};
return PartialView("Header", headerViewModel );
}

Megjegyzés: Ez a kód az egyszerűség kedvéért visszaadja a PageData objektumot a nézetnek. Jobb


megközelítés lenne, ha helyette egy nézeti modellt adnánk vissza.

A menüelemek kinyerésére szolgáló kódot ezután a Header műveletben helyeznénk el:

Building A Mega-Nav - Egy Mega-Nav építése


A Wikipedia a mega-navigációt a következőképpen definiálja:

"A mega menük nagyméretű navigációs panelek, amelyek általában egy globális navigációs sávból
esnek le vagy repülnek ki.

Egy mega-navigáció építése összetettebb lesz, mint egy egyszerű menü építése. Valószínűleg
szükséged lesz néhány tulajdonságra a képek, a tartalom és az extra linkek tárolására. Ha
megpróbáljuk ezeket a további tulajdonságokat egy oldaltípusba, több problémát fog okozni, mint
amennyit megér. Ha mega-navigációt kell építenie, akkor több értelme lesz menüspecifikus
oldaltípusokat létrehozni. A CMS-en belül a legjobb hely ezeknek az oldalaknak a gyökércsomópont
alatt, a kezdőlap testvéreként, és semmiképpen sem a kezdőlap gyermekeiként.
Mega Menu Editor

Az oldalhierarchiától elkülönített és függetlenített menüterület nagyfokú rugalmasságot biztosít.


Ennek a mintának a standard alkalmazási módja a következő oldaltípusok létrehozása:

• Menu Container -
• Menu - Egyedi menü tárolója
• Menüelem - A menü egy elemének meghatározására szolgáló tároló.
• Menu Column - A főmenüben oszlopok létrehozására szolgáló tároló.

Menü konténer: Egy konténer, amely lehetővé teszi, hogy több menü legyen alatta. A legtöbb
webhelytervezés valószínűleg több menüt tartalmaz. A fejlécben lévő elsődleges navigáción kívül a
gyakori, hogy a láblécben is van egy menü. Ennek a konténernek az a célja, hogy annyi menüt
építhessen, amennyire szüksége van. A konténernek egyáltalán nem lesz szüksége tulajdonságokra:
[ContentType(
DisplayName = "Container Page",
Description = "A placeholder to help organize the EPiServer page tree",
GUID = "9997138c-4469-4dbe-8adc-87b615f30f56",
GroupName = "Standard")]
[AvailableContentTypes(Include = new[]
{
typeof(MenuPage),
})]
public class MenusContainer : PageData
{}

Vegyük észre, hogy az AvailableContentTypes úgy van beállítva, hogy csak MenuPage-t lehessen
létrehozni alatta.

Menüoldal, ez a típus egy új menü definiálására szolgál.


[ContentType(
DisplayName = "Menu Page",
GUID = "A74BDA60-305C-47AA-9795-408BD343DD04",
Description = "Menu Page",
GroupName = "Standard")]
[AvailableContentTypes(Include = new[]
{
typeof(MenuColumn),
})]
public class MenuPage : PageData
{
[Display(
Name = "Main Menu Title",
Description = "Main Menu Title",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual string MenuTitle { get; set; }
}

Vegyük észre, hogy az AvailableContentTypes úgy van beállítva, hogy csak a MenuColumn-t engedje
alatta. Menu Column Ezt az oldaltípust fogjuk használni az összes felső szintű menüelem
hozzáadására.
[ContentType(
DisplayName = "Menu Column",
GUID = "12040C26-3CD5-4D0B-BA0D-3FB7D9FBAA8E",
Description = "Menu Page",
GroupName = "Standard")]
[AvailableContentTypes(Include = new[]
{
typeof(MenuItem)
})]
public class MenuColumn : PageData
{
[Display(
Name = "Menu Image",
Description = "Sub Menu Title",
GroupName = SystemTabNames.Content,
Order = 300)]
[UIHint(UIHint.Image)]
public virtual Url MenuImageUrl { get; set; }
[Display(
Name = "Menu Url",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual LinkBLock Link { get; set; }
}

Menu Item - Menüelem: Az az oldaltípus, amely a felső szintű menüelem alatt egy további link
hozzáadására szolgál. A MenuItem a menüoszlop gyermekeként jön létre. Egy alternatív megközelítés
az oldal-típus használata helyett az lett volna, ha a MenuColumn oldal-típuson egy tartalmi területet
használunk. Azért használok oldal-típust a menüelemek definiálására, mert a visszajelzések alapján a
tartalomszerkesztők általában használhatóbbnak találják, ha van valami, amit az oldalfában
láthatnak.
[ContentType(
DisplayName = "Menu Item",
GUID = "12040C26-3CD5-4D0B-BA0D-3FB7D9FBA3ED",
Description = "Menu Page",
GroupName = "Standard")]
public class MenuItem : PageData
{
[Display(
Name = "Menu Url",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual LinkBLock Link { get; set; }
}

Ebben a példában egy helyi blokkot használtam a CMS-en belüli link modellezésére, LinkBlock Ne
feledje, hogy a helyi blokkokat az ilyen alaptípusok ábrázolására használja, mivel ez a kódbázist sokkal
könnyebbé teszi. tisztábbá teszi a kódkódot.

Menü szolgáltatás( Menu Service), a következő lépés egy olyan szolgáltatás létrehozása, amelyet az
egész kódbázisban használhatunk a menü eléréséhez. A jó gyakorlat követése érdekében továbbra is
használjunk nézeti modelleket az adatok visszaadására egy nézetbe, és ne használjuk közvetlenül az
oldaltípust. Ebben a példában egy NavigationItemViewModel nevű nézetmodellt használok.
public class NavigationViewModel()
{
public NavigationViewModel()
{
SubMenuItems = new List<NavigationItemViewModel>();
}
public string Name { get; set; }
public LinkViewModel Link { get; set; }
public string ImageUrl { get; set; }
public List<LinkViewModel> SubMenuItems { get; set; }
}

A kódtisztító elkészítéséhez hozzon létre egy LinkViewModel gyárat a nézet-modell létrehozásához. E


szolgáltatás nélkül a végén a kód duplikálódni fog az egész kódbázisban:
public LinkViewModel CreateLinkViewModel(string url, string displayText)
{
var linkViewModel = new LinkViewModel
{
Url = url,
Name = displayText
};
return linkViewModel;
}
Egy lehetséges felülbírálási lehetőséggel, amely a helyi link-blokk típusát is átadja:
public LinkViewModel CreateLinkViewModel(LinkBlock link)
{}

A menü eléréséhez szükséges szolgáltatás így nézhet ki:

public class MenuService : IMenuService


{
private readonly IContentRepository _repo;
public MenuService(IContentRepository repo)
{
_repo = repo;
}
public List<NavigationItemViewModel> GetMainMenu(ContentReference menu)
{
// view model that get used in the view
var navigationItems = new List<NavigationItemViewModel>();
var menuPages = _repo.Get<MenuPage>(menu);
foreach(var menuPage in menuPages.Children<MenuColumn>())
{
var navigationItem = new NavigationItemViewModel
{
Name = menuPage.MenuTitle,
Link = CreateLinkViewModel(menuPage.Link),
ImageUrl = menuPage.MenuImageUrl.ToString()
}
foreach(var menuItem in menuItems.Children<MenuItem>())
{
var linkViewModel = CreateLinkViewModel(menuPage.Link)
navigationItem.SubMenuItems.Add(linkViewModel);
}
navigationItems.Add(navigationItem);
}
return navigationItems;
}
}

Ez a szolgáltatás most már beilleszthető a webhely bútorvezérlőjébe, és szükség szerint használható.


A végső HTML nyilvánvalóan a tervezéstől függően változik. Egy nagyon egyszerű példa arra, hogyan
strukturálja a HTML felépítése az alábbiakban látható:
The View
<ul>
@foreach (var menuItem in Model.Layout.Menu)
{
<li>
<a href="@menuItem.Link">
<img src="@Url.ContentUrl(menuItem.ImageUrl)"/>
@menuItem.Name
</a>
@if(menuItem.SubMenuItems.Any())
{
<ul>
@foreach(var menuItem in menuItem.SubMenuItems)
{
<li>
<a href="@menuItem.Url">
@menuItem.Name
</a>
</li>
}
</ul>
}
</li>
}
</ul>

Ezeknek a példáknak a célja, hogy bemutassák, hogyan lehet összetett menüt létrehozni az
Episerverben. Kétséges, hogy ezt a kódot egyszerűen át tudja majd emelni és áthelyezni a
projektjébe. mindenféle testreszabás nélkül. Ezért fontos a megközelítés körüli fogalmak megértése.

What Pattern Should I Use? - Milyen mintát használjak?

Hajlamos vagyok a menükonténer mintát előnyben részesíteni, függetlenül attól, hogy mennyire
összetettnek kell lennie a főmenünek. Lehetetlen megjósolni, hogy egy vállalkozás és annak
weboldala idővel hogyan fog változni. A menü konténer minta nem csak korlátlan számú menü
létrehozását teszi lehetővé. Azt is lehetővé teszi, hogy a dolgokat könnyen összekeverjük, és ez
mindig is jól irányított engem.

Mivel a kezdőlap a leglátogatottabb oldal minden weboldalon, ezért azt javasolnám, hogy kerülje a
menüspecifikus adatok kemény kódolását oda. Azt is tanácsolnám, hogy ne használjon egy
alaposztályt annak érdekében, hogy hozzáadjon menüspecifikus tulajdonságok hozzáadásához.

Breadcrumb -
A következő komponens, amit meg kell építenünk, a kenyérmorzsa. Az eredeti "Breadcrumb"
kifejezés a Jancsi és Juliska című meséből származik. A két gyerek kenyérmorzsákat dobál, hogy
nyomot hagyjanak a saját útjukhoz.

hazafelé. A weboldal morzsa ugyanezt a feladatot látja el, ez egy másodlagos navigációs típus, amely
feltérképezi az aktuális oldalról a kezdőlapra vezető utat. A morzsa létrehozásához szükséges kód
egyszerű. Mint korábban említettük, a kenyérmorzsa a ContentRepository.GetAncestors()
segítségével hozható létre:
public static IEnumerable<IContent> GetBreadcrumb(ContentReference currentPage)
{
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
return contentRepository.GetAncestors(currentPage);
}

Annak biztosítása érdekében, hogy a breadcrumb ne renderelje a gyökérelemet is. Ehhez


használhatja a CompareToIgnoreWorkID(ContentReference) metódust:
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var breadcrumbLinks = contentRepository.GetAncestors(contentLink)
.Reverse()
.SkipWhile(x => ContentReference.IsNullOrEmpty(x.ParentLink)
|| !x.ParentLink.CompareToIgnoreWorkID(ContentReference.StartPage))
.OfType<PageData>()
.Select(x => x.PageLink);

A Collection Of Links - Linkek gyűjteménye


Az elsődleges navigáción kívül a legtöbb tervezőnek szüksége van arra is, hogy a webhelyen egy
linkgyűjteményt is megjelenítsen. Például a legtöbb webhely láblécében gyakran látható egy
gyűjtemény. jogi linkek gyűjteménye, beleértve az olyan oldalakra mutató linkeket is, mint például a
sütikre vonatkozó irányelvek.

A linkgyűjtemények megjelenítésénél négy fő minta közül választhat:

• A linkelem-gyűjtemény tulajdonság
• Egy tartalmi terület és egy blokk
• A menü konténer minta
• A Property<T> tulajdonság egy egyéni POCO entitással

Ha a menü tároló mintát már megvalósította, akkor nincs sok értelme más mintát használni. Az
összes kódot már implementálta, miért kellene újra feltalálni a kereket. Alternatívaként, ha nem
akarja használni a menükonténer mintát, akkor három lehetősége marad. A linkek kezeléséhez
mindig a beépített LinkItemCollection használatát javaslom. tulajdonságot. A LinkItemCollection
tulajdonság a CMS-en belül megjeleníti a linképítőt, és ez azt is jelenti, hogy a tartalomszerkesztő
nem ugrik ki az oldalról. A LinkItemCollection használata tulajdonság használata jó backend-élményt
nyújt a tartalomszerkesztő számára, és a menü megjelenítéséhez szükséges kód egyszerű, ahogy az
alább látható:
[Display(Name = "Footer Links",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual LinkItemCollection FooterLinks { get; set; }

A megfelelő HTML formátummal:


<ul>
@foreach (var link in Model.FooterLinks)
{
<li>
<a target="@link.Target" href="@Url.PageUrl(link.Href)">
@link.Text
</a>
</li>
}
</ul>

A linkek megjelenítésére az Episerverben más megközelítéseket is alkalmazhat. Használhat egy


tartalmi területet és egy blokkot. Használhatja a Property tulajdonságot is - ezt a következő
fejezetben részletesen tárgyaljuk. Hacsak nincs igazán határozott véleménye erről a megközelítésről,
akkor azt javaslom, hogy maradjon a menü konténer mintánál.

Advanced Episerver Data Types

You might also like