Professional Documents
Culture Documents
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
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.
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:
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.
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.
• 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.
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
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.
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.
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:
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.
• 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.
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.
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.
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.
• Colour
• Name
• Type
• Tab
• Notes
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!
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.
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.
PROS
CONS
PROS
CONS
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.
PRO
CON
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
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
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.
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.
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.
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.
• 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.
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.
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.
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.
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.
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:
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.
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.
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
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.
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.
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:
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:
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:
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.
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.
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.
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.
• root
o Customers
o Members
o ContentEditors
o Administrators
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
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.
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ő.
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.
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/
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
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:
• 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.
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>
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.
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.
1. Minden fejlesztőnek saját helyi adatbázisa van, ideális esetben a saját gépén.
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.
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?
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 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.
útvonalak a következők:
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);
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.
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)
{
}
}
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.
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.
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.
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
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.
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:
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 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.
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.
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; }
}
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.
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.
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);
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.
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);
{
// 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ő
A [ContentType] attribútum lehetővé teszi néhány igen hasznos metaadat hozzáadását az oldalról:
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.
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.
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].
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.
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.
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:
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
{}
Properties - Tulajdonságok
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.
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.
• PropertyBoolean
• PropertyNumber
• PropertyDate
• PropertyFloatNumber
• PropertyPageType
• PropertyLongString
• PropertyUrl
• 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
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
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.
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
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:
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
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:
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.
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
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á!
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.
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>
Ha nem szeretné, hogy a tartalmi terület megjelenítse az extra <div> címkéket, akkor ez is lehetséges.
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.
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 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; }
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:
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.
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
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.
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
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.
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.
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);
}
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:
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>
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()
[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; }
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:
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.
@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:
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:
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:
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é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.
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
};
}
}
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 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.
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
{}
_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";
}
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.
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 PageReference használható a globális blokkok mappa azonosítójának megadására is, például így:
PageReference.SiteBlockFolder
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.
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:
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.
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;
}
}
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.
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
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);
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.
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);
}
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.
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)
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ó:
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/
Egy másik hasznos tény, hogy a GetBySegment() sokkal gyorsabb, mint a GetChildren() használata.
Vagy:
var landingPages = contentTypeRepository.List().Where(x => typeof(LandingPage).IsAssignableFrom(x.ModelType));
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:
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 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:
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.
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.
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?
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.
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?
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.
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.
• 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!
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.
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:
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)
{
}
}
@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.
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.
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 );
}
}
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.
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>
}
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!
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.
• 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 );
}
"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
• 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.
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; }
}
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.
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);
}
• 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; }