Som webudvikler har man ofte brug for at kunne eksperimentere med sagerne i en sandkasse, hvor andre ikke har adgang. Her er en vejledning i at sætte WordPress op på din localhost – det vil sige en WordPress, der virker på netværket derhjemme.
Læs mere om WordPress i min bog “WordPress in the Classroom” (2017). Her får du blandt andet historien om, hvordan WordPress themes har set ud gennem tiderne – og du kan lære mere om, hvordan man selv kan bygge et theme.
Opsætning af databasen i Windows I videoen er password = root og bruger = root; men sådan er det ikke på et Windows system. Her er bruger = root og passwordet er en tom linje.
NB: Denne tutorial er udviklet til et forløb på Multimediedesigneruddannelsen, hvor klasserne blandt andet lærer at sætte et WordPress-udviklingsmiljø op på en localhost.
“Drag and drop” (D&D) er alfa og omega når en GUI skal være intuitiv. D&D er en oplagt digital metafor, når vi skal efterligne et whiteboard. D&D er mulig i HTML5. Det er en relativt ny standard, og derfor må man forvente, at forældede browsere får problemer. Med D&D kan vi udvikle et interface på nettet med en funktionalitet, der minder om noget vi kender fra skrivebordsmetaforerne i OSX, Windows – eller Linux / Unix verdenens mangfoldighed af Windows Managers: Gnome, KDE, Ratpoison, LXDE, etc.
Det ser ud til at jQuery kan fyre en funktion af, når man dropper en dimmer et bestemt sted fx en firkant eller noget andet. ActionScript, Lingo etc. har noget, der minder om det her, nemlig “collision detection”.
Eksemplet “Drag and Drop To Columns” bruger et billedes position ved “drop” til at skabe strenge til databasen. Denne kode virker umiddelbart fornuftig som basis for mit projekt. Funktionen looper gennem arrayet af UL tags og laver en liste:
/*
Preparing data to be saved
*/
function saveDragDropNodes()
{
var saveString = "";
var uls = dragDropTopContainer.getElementsByTagName('UL');
for(var no=0;no<uls.length;no++){ // LOoping through all <ul>
var lis = uls[no].getElementsByTagName('LI');
for(var no2=0;no2<lis.length;no2++){
if(saveString.length>0)saveString = saveString + ";";
saveString = saveString + uls[no].id + '|' + lis[no2].id;
}
}
document.getElementById('saveContent').innerHTML = '<h1>Ready to save these nodes:</h1> ' + saveString.replace(/;$
}
Principielt burde denne funktion (modificeret til at loope gennem DIV-tags med en passende ID) kunne sætte en variabel – og en variabel må igen kunne overføres til en database via en sendeknap og GET eller POST.
På denne side er to eksempler på “send” med JS og Json:
function save(type){
var table_content;
table_content=REDIPS.drag.save_content('table1',type);
if(!table_content){alert('Table is empty!');}
else if(type==='json'){window.open('/my/multiple-parameters-json.php?p='+table_content,'Mypop','width=350,height=260,scrollbars=yes');}
else{window.open('/my/multiple-parameters.php?'+table_content,'Mypop','width=350,height=260,scrollbars=yes');}}
if(window.addEventListener){window.addEventListener('load',redips_init,false);}
else if(window.attachEvent){window.attachEvent('onload',redips_init);
}
Løsning: jeg forestiller mig, at værdierne fra loopene lægges ind i skjulte formfields via JS. Når denne form “submittes” via PHP gemmes positionerne i MySQL DB.
Test af et ny filter til Sony A290. Kontraster er markant forbedrede; men billedet bliver mørkere. Normalt bruges filteret til at dæmpe en lidt for lys himmel med hvide skyer eller til at fjerne reflekser på metal eller vandoverflader.
Du behøver ikke at gøre andet end det. Siden viser kun et flag på en flagdag. Hvis den er blank er det altså forklaringen.
De følgende afsnit forklarer, hvordan PHP-koden virker. Hvis det lyder lidt for nørdet, så drop resten af denne artikel.
Klassen flagdag
Men hvordan fungerer denne PHP-kode så? Først har jeg defineret en klasse, der indeholder de vigtigste funktioner (der er kun to funktioner):
class flagDag
{
// printer hvis dagen er en flagdag
public function dag($dato, $maaned, $hvad) {
$flagstang = "dannebrog.gif"; // stien til billedet af Dannebrog
// undersøger om det er en flagdag
if (date('m') == $maaned && date('d') == $dato) {
echo "<img src='" . $flagstang . "' alt='Dannebrog' width='50' height='38' >"; // kan skaleres efter behov
echo "<p style='font-size:smaller'>I dag flages for: " . $hvad . "</p>";
}
}
// sådan: plusTid('+3 weeks +5 days');
function fePaaske($tid, $hvad) {
// Denne funktion beregner dato for skæve helligdage
$date = date("Y-m-d", easter_date()); // påskedag
$newdate = strtotime ( $tid, strtotime ( $date ) ) ; // her plus-minuses
$newdate = date ( 'd,m' , $newdate ); // datoen formatteres
return $newdate . "," . $hvad; // udskriver resultatet
}
}
Dannebrog vises ved hjælp af denne funktion:
public function dag($dato, $maaned, $hvad) {
$flagstang = "dannebrog.gif"; // stien til billedet af Dannebrog
// undersøger om det er en flagdag
if (date('m') == $maaned && date('d') == $dato) {
echo "<img src='" . $flagstang . "' alt='Dannebrog' width='50' height='38' >"; // kan skaleres efter behov
echo "<p style='font-size:smaller'>I dag flages for: " . $hvad . "</p>";
}
}
Funktionen bruger $dato og $maaned til at definere datoen. $hvad er en kort beskrivelse af begivenheden. Når dagen og måneden indtræffer vises et flag (dannebrog.gif) samt den korte beskrivelse af begivenheden, fx “H.K.H. Prins Joachim”.
Herefter var det kun et spørgsmål om at instantiere klassen:
$ny = new flagDag(); // instantierer klassen
… og om at definere diverse flagdage, som fremgår af kalenderen hos Danmarks-Samfundet. Flagdagen defineres sådan:
$ny->dag(01,01,"Nytårsdag");
Påskeproblemet
De “kalenderfaste” flagdage var relativt simple. Det er straks værre med påsken, der følger en relativt kompleks månekalender. da.wikipedia.org skriver at påsken falder sådan:
Beregning af påskedagene kræver altså viden om jævndøgn, og hvornår det er fuldmåde. Heldigvis har PHP en funktion, der beregner påskedagen, nemlig easter_date().
På nettet fandt jeg en metode til at lægge tid til en dato, en den funktionalitet byggede jeg så ind i denne funktion:
function fePaaske($tid, $hvad) {
// Denne funktion beregner dato for skæve helligdage
$date = date("Y-m-d", easter_date()); // påskedag
$newdate = strtotime ( $tid, strtotime ( $date ) ) ; // her plus-minuses
$newdate = date ( 'd,m' , $newdate ); // datoen formatteres
return $newdate . "," . $hvad; // udskriver resultatet
}
Kirkens påskedag er bestemmende for en hel række helligdage, der falder lidt forskelligt fra år til år. Systemet ser sådan ud:
Palmesøndag – søndagen før påske (påske minus en uge)
Skærtorsdag – påske søndag minus 3 dage (Halv stang t. kl. 12:00)
1. påskedag – påskesøndagen
2. påskedag – påske søndag + en dag
Store Bededag – 4. fredag efter påske
Kristi Himmelfart – 6. torsdag efter skærtorsdag
1. pinsedag – 7. søndag efter påske
2. pinsedag – pinsedag + 1dag
Julen falder heldigvis på faste datoer, så det er til at have med at gøre…
1. juledag – fast dato 25.12.
2. juledag – fast dato 26.12.
Ved hjælp af min funktion kan man lægge år, dage, uger og måneder til påskedagen. Og derfor bliver beregningen af fx. 1. pinsedag relativt simpel:
Men scriptet returnerer en streng og funktionen, der viser en falgdag kræver to tal og en streng. En streng kan forvandles til et tal med (int); men jeg har kun brug for en del af strengen. Dagen og måneden skal isoleres ved hjælp af substring. Det leder frem til denne magiske formular, der viser flaget på de “skæve” helligdage:
Den ovenstående kode skulle skrives 8 gange, og det ligner et job for et loop. I en senere version blev denne kode derfor erstattet med et array og et loop. Koden kom til at se sådan ud:
$kadosh = array(
$ny->fePaaske("-1 weeks", "Palmesøndag"), // Palmesøndag
$ny->fePaaske("-3 days", "Skærtorsdag"), // Skærtorsdag
$ny->fePaaske("+0 days", "1. Påskedag"), // 1. Påskedag (fuldmåne efter equinox)
$ny->fePaaske("+1 days", "2. Påskedag"), // 2. Påskedag
$ny->fePaaske("+5 days +3 weeks", "Store Bededag"), // Store Bededag
$ny->fePaaske("-3 days +6 weeks","Kristi Himmelfart"), // Kristi Himmelfart
$ny->fePaaske("+7 weeks", "1. Pinsedag"), // 1. Pinsedag
$ny->fePaaske("+7 weeks +1 days", "2. Pinsedag") // 2. Pinsedag
);
$i = 0; // looper derefter gennem kadosh-arrayet og kombinerer ny->dag med ny->fePaaske
while($i <= count($kadosh))
{
$ny->dag(
(int)substr($kadosh[$i],0,2), // dag substring som integer
(int)substr($kadosh[$i],3,4), // måned substring som integer
substr($kadosh[$i],6) // hvad (pladrer strengen ud fra 6. karakter)
);
$i++;
};
Tilbage stod at indskrive flagdatoerne i scriptet. Resultatet kan ses her. Måske. Hvis det ikke er flagdag i dag, så er siden altså blank. Og det var netop meningen. Der skal kun være et flag når det er en flagdag.
Debugging
Nu får vi så se, om koden virker. Debugging varer et års tid. Hvis multimusen.dk flager på en flagdag, så virker sagerne jo.
Koden
Herunder er PHP-koden som den så ud i første omgang, inden loopet herover. Det er selvfølgelig den rå betaversion; men den kan bygges ind i et PHP-baseret website. Det forudsættes, at koden ligger i samme mappe som billedet af flaget.
<?php
/* DANSKE FLAGDAGE
Af: Per Thykjaer Jensen
Beskrivelse: Printer danske flagdage til en webside via PHP.
Version: 0.2 Beta - flagdage.
Ændringer:
Version 0.2 - denne version kan beregne kirkelige flagdage baseret på påskedag.
0.11 - Dannebrog som .gif af hensyn til kompabilitet.
Version 0.1 - basal funktionalitet. På flagdage med fast dato vises et flag.
Dato: 20120608
Copyright: GPLv3 - se licensen her: http://www.gnu.org/copyleft/gpl.html
*/
class flagDag
{
// printer hvis dagen er en flagdag
public function dag($dato, $maaned, $hvad) {
$flagstang = "dannebrog.gif"; // stien til billedet af Dannebrog
// undersøger om det er en flagdag
if (date('m') == $maaned && date('d') == $dato) {
echo "<img src='" . $flagstang . "' alt='Dannebrog' width='50' height='38' >"; // kan skaleres efter behov
echo "<p style='font-size:smaller'>I dag flages for: " . $hvad . "</p>";
}
}
// sådan: plusTid('+3 weeks +5 days');
function fePaaske($tid, $hvad) {
// Denne funktion beregner dato for skæve helligdage
$date = date("Y-m-d", easter_date()); // påskedag
$newdate = strtotime ( $tid, strtotime ( $date ) ) ; // her plus-minuses
$newdate = date ( 'd,m' , $newdate ); // datoen formatteres
return $newdate . "," . $hvad; // udskriver resultatet
}
}
$ny = new flagDag(); // instantierer klassen
// FLAGDAGE
$ny->dag(01,01,"Nytårsdag");
$ny->dag(05,02,"H.K.H. Kronprinsesse Mary");
$ny->dag(06,02,"H.K.H. Prinsesse Marie");
$ny->dag(09,04,"Danmarks besættelse. Der flages på halv stang til kl. 12:00.");
$ny->dag(16,04,"H.K.H. Dronning Margrethe II.");
$ny->dag(29,04,"H.K.H. Prinsesse Benedikte.");
$ny->dag(05,05,"Danmarks befrielse 1945.");
$ny->dag(26,05,"H.K.H. Kronprins Frederik.");
$ny->dag(05,06,"Grundlovsdag (1849).");
$ny->dag(07,06,"H.K.H. Prins Joachim"); // protektor for Danmarks-Samfundet
$ny->dag(11,06,"H.K.H. Prinsgemal Henrik.");
$ny->dag(15,06,"Valdemarsdag og Genforeningen (1920)");
$ny->dag(05,09,"H.K.H. Prins Joachim");
$ny->dag(25,12,"Juledag.");
// FORSVARETS FLAGDAGE
$ny->dag(29,01,"Holmens Hæderstegn.");
$ny->dag(02,02,"Kampen ved Mysunde (1864).");
$ny->dag(11,02,"Stormen på København (1659).");
$ny->dag(02,04,"Slaget på Reden (1801).");
$ny->dag(18,04,"Slaget ved Dybbøl (1864).");
$ny->dag(09,05,"Kampen ved Helgoland (1864).");
$ny->dag(05,06,"Kampen ved Dybbøl (1848).");
$ny->dag(01,07,"Slaget i Køge Bugt (1677).");
$ny->dag(06,07,"Slaget ved Fredericia (1849).");
$ny->dag(25,07,"Slaget ved Isted 1850.");
$ny->dag(04,10,"Stormen på Frederiksstad 1850.");
/* KIRKELIGE FLAGDAGE
De "skæve" kirkelige helligdage følger en månekaldender og falder et antal dage efter en bestemt fuldmåne.
Udgangspunktet for beregningerne er påskedag.
Systemet ser sådan ud:
Palmesøndag - søndagen før påske (påske minus en uge)
Skærtorsdag - påske søndag minus 3 dage (Halv stang t. kl. 12:00)
1. påskedag - påskesøndagen
2. påskedag - påske søndag + en dag
Store Bededag - 4. fredag efter påske
1. pinsedag - 7. søndag efter påske
2. pinsedag - pinsedag + 1dag
Kristi Himmelfart - 6. torsdag efter skærtorsdag
1. juledag - fast dato 25.12.
2. juledag - fast dato 26.12.
Eftersom de skæve helligdage afhænger af påsken og månen så er PHPs påskeberegning et udgangspunkt for tidsberegningerne
*/
$palmeS = $ny->fePaaske("-1 weeks", "Palmesøndag"); // Palmesøndag
$skaerT = $ny->fePaaske("-3 days", "Skærtorsdag"); // Skærtorsdag
$PaaD = $ny->fePaaske("+0 days", "1. Påskedag"); // 1. Påskedag (fuldmåne)
$APaaD = $ny->fePaaske("+1 days", "2. Påskedag"); // 2. Påskedag
$stB = $ny->fePaaske("+5 days +3 weeks", "Store Bededag"); // Store Bededag
$KrH = $ny->fePaaske("-3 days +6 weeks","Kristi Himmelfart"); // Kristi Himmelfart
$fPin = $ny->fePaaske("+7 weeks", "1. Pinsedag"); // 1. Pinsedag
$aPin = $ny->fePaaske("+7 weeks +1 days", "2. Pinsedag"); // 2. Pinsedag
$ny->dag(25,12,"1. Juledag."); // helligdage med fast dato
$ny->dag(26,12,"2. Juledag.");
// Et loop gennem et array kunne ha gjort det følgende mere elegant ... næste version ...
$ny->dag((int)substr($palmeS,0,2), // Palmesøndag
(int)substr($palmeS,3,4),
substr($palmeS,6)
);
$ny->dag((int)substr($skaerT,0,2), // Skærtorsdag
(int)substr($skaerT,3,4),
substr($skaerT,6)
);
$ny->dag((int)substr($paaD,0,2), // Påskedag
(int)substr($paaD,3,4),
substr($paaD,6)
);
$ny->dag((int)substr($APaaD,0,2), // 2. Påskedag
(int)substr($APaaD,3,4),
substr($APaaD,6)
);
$ny->dag((int)substr($stB,0,2), // Store Bededag
(int)substr($xstB,3,4),
substr($stB,6)
);
$ny->dag((int)substr($KrH,0,2), // Kristi Himmelfartsdag
(int)substr($KrH,3,4),
substr($KrH,6)
);
$ny->dag((int)substr($fPin,0,2), // 1. Pinsedag
(int)substr($fPin,3,4),
substr($fPin,6)
);
$ny->dag((int)substr($aPin,0,2), // 2. Pinsedag
(int)substr($aPin,3,4),
substr($aPin,6)
);
/* PRIVATE FLAGDAGE
Indfør dine private flagdage herunder
Format: "dd,mm, begivenhed"
eksempel $ny->dag(03,06,"test");
*/
// eksempel
// $ny->dag(27,02,"Pers fødselsdag");
?>
Koden herover kan faktisk bruges til mange ting. Ved få ændring kan den gøres til et WordPress plugin – og det er i denne form at jeg bruger koden nu.
Det kunne være festligt, hvis min webside hejste Dannebrog på flagdagene. Derfor har jeg eksperimenteret lidt med en PHP-sag, der viser Dannebrog og begivenheden på flagdage.
Resultatet ses herunder (og ja: hvis dagen i dag ikke er en flagdag, så kan du ikke se noget herunder…).
De kirkelige hellig- og flagdage skal beregnes via PHPs easter_date() klasse. Det er lidt mere kompliceret – de skæve helligdage kommer med i den næste version. Kopier koden herunder til din webside:
Systematisk. således at man kan finde bogen, når man har brug for den.
Lige nu står vores ca. 900 bøger pænt. De er til en vis grad grovsorteret i emner, og de står efter størrelse. Sådan er der plads til flere bøger på hylderne. Konsekvensen af denne systematik er, at jeg skal bruge timer på at finde mine bøger. For hvor står Aleister Crowleys “Gems from the Equinox” eller “Farvernes Metafysik” af Ingolf Jensen?
Hvordan kan man løse problemet? Jeg har brug for en database!
Regneark som hyldemetafor
Et regneark er smart og til at finde rundt i. Første kolonnes tredje række hedder fx A3. Jeg kunne jo begynde med at navngive mine reoler A, B C … N eller hvor mange der er. Herefter er det bare om at tælle hylderne. Herefter kan jeg referere til en bogs placering som fx I4. Mere præcist kunne man selvfølgelig referere til D7:15 – altså reol D, hylde 7 bog 15 fra højre.
Men bare jeg kan finde ud af reolen, så finder jeg nok frem til bogen. Regnearksmetaforen er nem at forstå. Den kræver kun, at du udpeger en eller anden reol til at være A.
Første udkast til databasen
ER diagrammet viser en simpel databasestruktur. Et værk er skrevet af en forfatter. Hver for sig er de entiteter. Hvis jeg adskiller dem, så får jeg en mere fleksibel database. Hvis databasen skal bruges i en artikel, så kunne jeg lave et henvisningsregister, der også kunne gøres søgbart. På den måde får jeg en akademisk database over mine bøger.
Og vigtigst af alt – jeg kan finde mine bøger igen.
Tidsskrifter
Hvordan henviser man så til artikler i tidsskrifter – eller måske til en artikel i en bog, der ret beset er en artikelsamling? Måske burde man supplere med en artikelentitet. Nu udvikler mit ER-diagram sig sådan:
Lidt id-er skal tilføjes, og lidt tanker tænkes, så ser den sådan ud:
Occams Barberblad
Filosoffen Occam mente, at hvis der er flere mulige løsninger, så er den enkleste den bedste. Occams barberblad handler om at fjerne det, som gør sagerne unødigt komplicerede. I det lange løb bliver adskillelsen af forfatter og værk lidt kunstig, og så kan jeg bruge Occams barberblad og reducere hele baduljen til:
HTML
Efter en tur i PHPMyAdmin er databasen ved at være på plads. Den er ikke helt som modellen ovenover; men det ligner lidt. Diagrammerne kan nemt omsættes til tabeller i MySQL databasen.. Nu vil jeg have noget html. i form af nogle includefiler:
Formular til indtastning af nye bøger
Indtaste titler på artikler, der er dele af bøger
Søgefelt
Præsentationer af søgninger
Formular til at redigere resultaterne.
Og så begynder det jo at ligne en webside; selv om formularer uden PHP ingenting kan, ud over at være sådan nogenlunde ikke alt for grimme.
Nu ved jeg nogenlunde, hvad applikationen skal kunne. Så nu er det også indlysende, hvad det er mine classes skal kunne (indrømmet det er CRUD = Create, Update, Delete). Og ja, formularerne validerer på W3C.
‘Building PHP Applications’ (Wrox 2011) handler om at udvikle PHP-applikationer ved hjælp af frameworks. Bogen fortæller om en lang række PHP-relaterede frameworks, og vælger at gå i dybden med de frameworks, som forfatterne anser for mest populære:
CakePHP
Symphony
Zend
Bogen kommer således vidt omkring; men det kan ærlig talt være lidt trættende at læse, hvordan man laver fx en adresseliste med det samme eksempel i CakePHP, Symphony og Zend. Derefter går man videre til et nyt eksempel, der skives efter samme algoritme.
Men eksemplerne er gode, og forfatterne er ærlige nok til at skrive, at nogle af disse frameworks har en stejl indlæringskurve. CakePHP skulle være mest enkelt at gå til – og dokumentationen i dette framework roses til skyerne. Det sidste kan undre; men det siger måske lidt om dokumentationen på frameworks generelt.
‘Building PHP Applications’ vrimler med herlige kabbalistiske magiske ord: LAMP, WAMP, MAMP, CRUD, ORM, CMS, MVC, MVP, SVN, ODBC, CSRF, AJAX, LDAP, ACL etc. Den elizabetanske renessancemagiker John Dee ville blegne af midsundelse over dette farverige fagsprog. Men det skal dog siges, at de mange begreber forklares godt og grundigt. Og derefter kan man jo selv kaste om sig med dem.
Jeg købte bogen med det formål at få en bedre forklaring af CakePHP end den som er tilgængelig på CakePHPs egne sider (på disse sider kan man fx læse, at en model er en model – og det er jo en gang tautologisk vrøvl).
‘Building PHP Applications’ forklarer CakePHP på en fin måde – man skal bare springe let og elegant hen over eksempler på Zend og Symphony. Omvendt kunne det jo være, at Zend og Symphony viser sig at være et godt alternativ?
‘Building PHP Applications’ er således en god indføring i PHP-frameworks.
Multimusen.dk will set a few cookies from Doubleclick, Google and the Social Media plugins they ay set some cookies. Some of my pages use APIs - such as YouTube, LinkedIn, Google Fonts, Google Maps, Mapbox, Spotify, Jetpack, Twitter, Facebook &c.. Such plugins may set the odd cookie.