Vertrouw nooit gebruikersinvoer

Gisteren en vandaag heb ik na het zien van een stukje code dat ergens anders ontbrak  gebruikt om me eens flink te verdiepen in de veiligheid van PHP. En dan vooral de veiligheid van gebruikersinvoer want dat je die niet zonder meer mag vertrouwen is me de afgelopen maanden al wel duidelijk geworden.

En het was maar goed dat ik me erin verdiepte. Er ontbrak dus ergens een stukje code. In mijn code voor het gastenboek dat binnenkort hopelijk op Web development uitdagingen verschijnt. Dat kan tot het onderstaande resultaat leiden:

gehackt

Hoe heb ik deze ‘hack’ bewerkstelligd? Op de plek waar ik een bericht in kon vullen, heb ik simpelweg het volgende ingevuld:

<script>alert('Gehackt!');</script>

Dat was alles. Maar naar natuurlijk zijn er gevaarlijkere manieren om deze kwetsbaarheid te exploiteren. Je zou bijvoorbeeld een script van een andere pc kunnen laden en met met dat script die ander ongemerkt toegang geven tot jouw computer. De techniek heet Cross-site scripting (XSS).

Kwetsbaarheid oplossen

Gelukkig is de kwetsbaarheid die ik hier liet zien betrekkelijk eenvoudig op te lossen. Het gaat erom dat de PHP engine op de server te gevaarlijke code niet meer als zodanig interpreteert. Aanhalingstekens en haken moeten daartoe omgezet worden in ongevaarlijke tekens. Meerdere mogelijkheden, ik noem er drie:

  1. strip_tags.() Deze functie zorgt er in bovenstaande voorbeeld voor dat de script tags verwijderd worden waardoor het voorbeeld slechts een onschuldige tekst oplevert.
  2. htmlentities(). Deze functie zorgt ervoor dat alle karakters waarvoor de functie aangeroepen wordt, omgezet wordt naar HTML code.
  3. htmlspecialchars() Doet hetzelfde als nummer 2, maar behoudt accenten. Die worden door htmlentities() namelijk omgezet in HTML code.

Zelf geef ik de voorkeur aan htmlenities. Hoe maak je de code nu veilig? Ik geef de code die berichten uit het gastenboek laat zien.

function show_post($result)
		{
			
			foreach ($result as $key => $value)
				{
					echo '<div class="box">';
					foreach ($value as $subkey => $subvalue)
						{
							$subkey = htmlspecialchars($subkey);
							$subvalue = htmlspecialchars($subvalue);
							echo '<div class="' . $subkey . '">' .  $subvalue . '</div>';	
							if($subkey == "id")
								{
									echo '<a href="update.php?id=' . $subvalue . '"><div class="update"></div></a>';
									echo '<a href="delete.php?id=' . $subvalue . '"><div class="delete"></div></a>';
								}
						}
					
					echo '</div>';
				}

In de oorspronkelijke code ontbraken regels 9 en 10. Deze regels zorgen er nu voor dat de gebruikersinvoer gecontroleerd wordt voordat deze op het scherm getoond wordt.

Nog een kwetsbaarheid

Bij formulieren is het gebruikelijk om aan te geven welke method (get of post) er gebruikt wordt. En welke pagina de afhandeling verzorgt (action). Het action attribuut kan sinds HTML5 weggelaten worden. In dat geval is de huidige pagina de pagina die het formulier afhandelt.

Je kunt ook kiezen voor een stukje PHP. De functie $_SERVER[‘PHP_SELF’] is huidige pagina. Die kun je als volgt opnemen in je action.

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Met htmlspecialchars dus. Doe je dat niet dan kun je met de volgende tekst achter de url in de adresbalk hetzelfde ‘Gehackt’ scherm te zien krijgen als waar we mee begonnen.

/%22%3E%3Cscript%3Ealert('Gehackt!')%3C/script%3E

Het laatste voorbeeld is overigens afkomstig van W3Schools. Welbestede dagen, zou ik denken. Eenvoudig te testen veiligheid.

Wordt ongetwijfeld vervolgd, al is het maar met een aflevering over gebruikersinvoer en de database.

Challenges uit The Complete Web Developer Course

Web development uitdagingen
Voor ik aan mijn opleidingstraject tot web developer begon, heb ik eerst gekeken of het mij echt interesseerde en of ik er voldoende van begreep om het enigszins kansrijk te maken.

Ik ben namelijk nogal talig aangelegd, wiskunde is dan ook niet mijn sterkste kant. Die eerste kennismaking verliep aan de hand van de Udemy Course The Complete Web Developer Course van Rob Percival HTML & CSS. Design and build websites van Jon Duckett, HTML en CSS de basis van Andree Hollander, Handboek JavaScript & jQuery van Peter Kassenaar en wat CodeCademy. Toen mijn vorige baan teneinde liep was ik al begonnen, vandaar en het duurde even voor ik met mijn cursus kon beginnen.

Testen en nog eens testen

Omdat ik ervan doordrongen was dat mezelf testen voor mij een belangrijke voorwaarde is om succesvol te leren, heb ik zo veel mogelijk oefeningen gemaakt en heb daarnaast veel in Anki gezet (Anki is een programma waarmee je jezelf kunt overhoren volgens de principes van gespreid herhalen).  Veel van wat ik in Anki zette, formuleerde ik als kleine opdracht: maak een array met zeven huisdieren en geef er daarvan drie cursief weer. Doordat ik die opdrachten uitschrijf in Notepad++ en vervolgens in de browser open om te kijken of het daadwerkelijk werkt, maak ik me de eigenaardigheden van de code eerder eigen dan wanneer ik de oplossingen alleen voor me uit prevel. Dit alles wordt nog versterkt doordat ik Anki iedere avond gebruik. Ook met de opdrachten van mijn opleiding probeer ik dagelijks bezig te zijn.

Web Development uitdagingen

De afgelopen dagen ben ik bezig geweest de opdrachten die ik voor de Udemy cursus gemaakt heb, online te zetten op Web development uitdagingen, de site bij deze blogserie. Ik vond die cursus als inleiding behoorlijk interessant, zeker omdat je zowel kennismaakte met HTML/CSS als met JavaScript/jQuery en PHP/MySQL en Bootstap. Het is echter inleidend en mijn huidige opleiding graaft dieper.

Challenges

Maar omdat de Udemy cursus iedere module afsloot met een leuke programmeeropdracht, leek het mij aardig om die programmeeropdrachten op de site te zetten. Hier en daar heb ik er wat aanpassingen in aangebracht. Zo kreeg ik met mijn oorspronkelijke uitwerking van PHP opdracht een PHP foutmelding als ik mijn eigen woonplaats opzocht. Dat heb ik opgevangen door eerst te controleren of de url bestaat (i.e. geen 404 oplevert).

Voor het geheime dagboek dat de MySQL module vormde heb ik besloten om de md5 encryptie te vervangen door password_hash en password_verify. Dit omdat PHP.net het gebruik van md5 afraadt bij het opslaan van wachtwoorden.

Tot slot vond ik het spelen met JavaScript spelletje zo leuk, dat ik er zelf nog een versie voor 2 personen voor heb gemaakt.

Neem dus vooral een kijkje op Web development uitdagingen.

Volgende uitdaging:

Maak een contactformulier.

Waarom ik vertalen zo leuk vind

En waarom ik wat minder gemakkelijk blog

Deze post is eigenlijk een vorm van uitstelgedrag. Maar ik merk dat ik ondanks mijn goede voornemens en ontdekking van laatst nog niet zo heel heel lang geleden, nog niet heel veel verder ben met mijn bloggen. Niet getreurd, komt goed. Maar ik ben op dit moment weer druk bezig met vertalen. Ja, er is altijd wat te vertalen omdat slechts rond de 100 van de ruim 160 boeken van Captain Johns in het Nederlands zijn verschenen.

Iedere keer vind ik het weer geweldig leuk en slokt het me qua vrije tijd volledig op. Het past helemaal bij me. Met taal bezig zijn. Je dienstbaar opstellen (hoop ik), aan toekomstige lezers en aan de auteur. En met dat laatste stip ik een cruciaal verschil aan met bloggen. Mijn blogs mag ik helemaal zelf schrijven, al heb ik regelmatig, zoals vandaag, wat hulp wat hulp bij het onderwerp, maar toch.

Bij vertalen echter ligt er al veel meer vast. Een boek of in ieder geval een tekst van de auteur of van je medevertaler(s). Ik hoef ‘alleen maar’ te vertalen of na te lezen en te corrigeren. En dat vind ik wel zo prettig. Het vanuit het Engels zoeken naar een zo goed mogelijke weergave in het Nederlands: heerlijk. Blijven slijpen, nadenken, herlezen, overleggen, opzoeken, corrigeren, tot aan drukproefcorrecties, die door het werken vanaf papier vaak meer correcties opleveren dan voorzien. Ja, als ik met al die dingen bezig ben dan voel ik mij soms bijna de koning te rijk dat er nog zo’n mooie stapel boeken van Captain Johns te vertalen valt.

En natuurlijk blijf ik bloggen, ook dat vind ik veel te leuk.

~ ~ ~ ~

#SG16 Iedere dinsdag geeft een Carel een woord op uit spreekwoorden en gezegden waar je dan over kunt bloggen.

3 andere manieren om pagina’s ontoegankelijk te maken

Zaterdag schreef ik dat je door de includes map buiten de www/public_html map te plaatsen, een map hoger dus, een mooie manier hebt om ervoor te zorgen dat bestanden die je opneemt als onderdeel van andere pagina’s niet als zelfstandige pagina’s te benaderen zijn. Gisteravond meende ik te ontdekken dat dat voor deze website niet lukte.

Het ging althans niet via WinSCP, maar ik ontdekte net pas dat het wel ging ik de file manager van het beheer systeem van de website gebruikte.  Ondertussen had ik al al drie andere oplossingen gevonden. Die schrijf ik maar gauw op voordat ik ze vergeet.

Methode 1: .htaccess

De eerste methode is waarschijnlijk de eenvoudigste. Stel dat je de map onzichtbaar niet benaderbaar wilt hebben. Je plaatst dan in die map het bestandje .htaccess. Dat wil zeggen: beginnen met een punt en eindigen zonder extensie. Dat bestandje heeft maar 1 regel nodig:

deny from all

De methode werkt prima, maar heeft als nadeel dat het er gebruikersonvriendelijk uit ziet. Kijk maar:


Forbidden

You don’t have permission to access /wachtwoord/ on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.


Methode 2: gebruik functies

Methode 2 levert een blanco scherm op. Zie dit voorbeeld. De pagina bevat echter wel code. Maar die code maakt onderdeel uit van een functie en het resultaat van de functie is pas zichtbaar als de functie aangeroepen wordt, wat hier dus niet is gebeurd. Dit principe kun je gebruiken om de van inhoud van pagina’s in een includemap onzichtbaar te maken. Je neemt het bestand op in een pagina en roept vanaf die pagina de functie pas aan. Je kunt het ook gebruiken als je alleen HTML hebt. Je maakt dan als volgt een functie aan:

function htmlWeergeven() {
echo '
<p>Hier plaats je alle html code</p>
';
}

PHP code is nooit zichtbaar en een browser in de code de opdracht is gegeven HTML output te generen, bijvoorbeeld met het commando echo, zoals hierboven.

Methode 3: gebruik het verschil in URL

Dit vind ik zelf de leukste methode omdat je hiermee de vrijheid hebt om zelf te bepalen wat je bezoeker te zien krijgt.

Waar het bij deze methode om draait, is dat de bestanden toegankelijk moeten zijn als ze ingevoegd zijn, met ofwel include of met require. Benader je het losse bestand dan dient het bestand niet toegankelijk te zijn. Het draait om de url. Als een bestand ingevoegd is, heeft het geen zelfstandige url. Als je bestand zelf benadert, krijg je bijvoorbeeld deze url:
http://webdevelopmentuitdagingen.nl/oefenpaginas/includes/verbergen.php

Het gaat om  de map includes. Die wil ik ontoegankelijk maken. In PHP kun je met verschillende functies urls uitlezen.  De code die daarvoor zorgt in bovengenoemd bestand is:


$url = $_SERVER['REQUEST_URI'];
$url = explode('/', $url);
print_r($url);

In de eerste regel wordt de url van het bestand als tekst (string) opgeslagen opgeslagen in de variabele $url. De 2 regel maakt losse blokken van de url met de / als scheidingsteken en de derde regel toont die losse blokken; of array elementen, om ze hun juiste namen te geven. De print_r regel toont de array op het scherm en moet weg voor je het bestand daadwerkelijk uploadt.

Je kunt nu een voorwaarde maken op basis van de url. Array element nummer 2 van $url is includes. Dat kun je bevragen:

if ($url[2]=='includes') {
		echo '<h1>Excuses</h1><p>Deze pagina is helaas
 niet beschikbaar. Klik 
<a href="http://www.webdevelopmentuitdagingen.nl">hier
</a> om terug te gaan naar de site.<p>';
		exit();
	}

Binnen dat echo is natuurlijk alles mogelijk. Maar je kunt ook automatisch doorlinken door in plaats van echo header('Location:http://www.webdevelopmentuitdagingen.nl'); op te nemen. Voor die header mag echter geen enkele code ge-echo’d. worden, zelfs geen spatie of nog erger html code die niet gemaakt is door PHP.

Typ overigens niet Loation i.p.v. Location, een tikfout die mij nogal eens overkomt. De hoofdletter, de () en de aanhalingstekens zijn verplicht, net als de puntkomma aan het einde.

Het commmando exit() zorgt ervoor dat alle code die hierna komt niet meer uitgevoerd wordt, hetzij PHP, hetzij HTML/JavaScript. En exit() werkt ook voor de pagina waarin het bestand eventueel ingevoegd wordt.

Het mooie van dit script op basis van if ($url[2]=='includes') is dat je de conditie zo in kunt vullen als je zelf wilt en dat je ook helemaal zelf kunt invullen wat er gebeurt als niet aan de conditie wordt voldaan. Je kunt bij wijze van een spreken een pseudo-404-pagina ontwerpen als je daar zin in hebt. Of een mooie easter egg verstoppen.

En het allerleukste?

Je kunt dit script uiteraard met een simpele regel code ‘includen’ of ‘requiren’ in alle bestanden waarvan je inhoud wilt verbergen.

Have a break

Hoe vaak ik het nu al wel niet heb gemerkt sinds ik het hoorde in de MOOC Learning How to Learn en bovendien daarna nog las in A Mind for Numbers van Barbara Oakley en tot slot ook nog eens gemerkt heb wat een prachtig neveneffect het is van elke dag wandelen, toch schijn ik hardleers te zijn. Bovendien had ik vanmiddag al een uur gewandeld dus daar schoot ik vanavond niks mee op.

Ik was bezig de challenges die bij die The Complete Web Developer Course van Rob Percival op Udemy over te zetten van dit domein naar www.webdevelopmentuitdagingen.nl. Aan die cursus was ik begonnen omdat mijn recentste werkgever vroeg of ik mij in PHP wilde verdiepen. Dat wilde ik wel, maar dan wilde ik ook kennismaken met andere JavaScript en jQuery. Het kwam er niet echt van omdat mijn baan tot een einde kwam maar in de tijd dat ik mij op een vervolg van mijn carrière oriënteerde, heb ik wel die cursus gevolgd en de opdrachten gemaakt.

Die was dus over aan het zetten. Maar het lukte maar niet om de MySQL challenge werkend te krijgen en het was me vrijwel meteen duidelijk dat er geen verbinding gemaakt werd met de tabel in de vers aangemaakte database. En wat ik ik knipte en plakte, het lukte niet. Tot ik eindelijk even pauzeerde en een ingeving kreeg. Als ik die tabel nou eens uit de database zou halen en gewoon ergens een WordPress installeerde. Zo gezegd, zo gedaan. Maar bij het installeren kon ik in eerste instantie geen verbinding maken met de database. Gelukkig had ik nog andere instellingen en daarmee werkte het wel.

Gelukkig bleek hiermee ook het probleem van mijn MySQL challenge opgelost te zijn. Met de gegevens van WordPress meldde mijn testbestandje dat er verbinding kon worden gemaakt met de database. WordPress deïnstalleren en testen of de MySQL challenge nu wekt: ja dus.

Geleerde les: op tijd pauzeren

Ik moet nog wat inleidende teksten teksten schrijven, dan pas ik de site weer aan.

Include en require

Web development uitdagingen

Na het stellen van mijn opdracht in de vorige aflevering van deze serie had ik ook de opdracht die ik daarna wilde uitvoeren al snel in gedachten. Ik heb nu besloten beide opdrachten om te draaien. Ik was van plan om eerst de site van inhoud te voorzien en daarna te zorgen voor een goede paginastructuur.

Bij nader inzien lijkt me dat een onlogische volgorde. Het toevoegen van pagina’s gaat namelijk een stuk efficiënter als je eerst zorgt voor een goede paginastructuur. Op die manier hoef je per pagina zo weinig mogelijk te wijzigen.

Een stukje geschiedenis

Een webpagina bestaat voor een groot deel uit onderdelen die voor elke pagina hetzelfde zijn. Denk een een header, een menu en een footer. Alleen het gedeelte met de inhoud van een pagina is steeds verschillend. Voordat dynamische websites opkwamen kon je in HTML dergelijke onderdelen in je site zetten met frames en een frameset. Belangrijk nadeel van deze techniek is dat leessoftware voor blinden een slechtzienden er niet mee overweg, wat waarschijnlijk een reden is geweest waarom de frame techniek geen onderdeel meer uitmaakt van HTML5.

Enter PHP

Tegenwoordig los je bovengenoemd scenario op met wat server side includes worden genoemd. Je maakt dan losse pagina’s voor je footer, je menu enz. en die voeg je dan op de plek waar ze in pagina moeten toe aan de code. Voor web development uitdagingen pagina betekende dat ik de werkende index.php pagina heb gepakt en daar de header, het menu, de footer en de aside van mee gemaakt heb. Voordeel van deze  aanpak is dat ik dus niet op 10 pagina’s het menu moet aanpassen, maar alleen maar menu.php.

Pagina’s in een andere pagina opnemen gaat heel makkelijk met include. Mocht een in te voegen deel van een pagina nu essentieel zijn voor de werking van de pagina dan heb je daar de functie require voor. In dat geval zal de pagina niet werken als het benodigde bestand ontbreekt. Van beide functies heb je ook een _once variant. Die is handig om te voorkomen dat je 2 keer een include opneemt waarin je een functie definieert. Een functie mag namelijk maar een keer gedefinieerd worden.

Includepad

Het is gebruikelijk de losse in te voegen bestanden in een includes map te zetten. Bijvoorbeeld www.example.com/includes/menu.php. Nadeel van deze werkwijze is dat het menu los van de site waar het bijhoort  te benaderen is. Je kunt er ook voor kiezen om je includes op te slaan in de map boven je www (root) map. Je verwijst dan als volgt vanaf de root ../includes.menu.php. Het menu wordt nu keurig opgenomen in de site maar is door bezoekers niet meer los te benaderen.

Benieuwd naar het resultaat tot nu toe? Klik op de schermafbeelding van de website. Die geeft overigens niet de actuele situatie weer.

Volgende uitdaging:

Lege pagina’s vullen.

If else

if else

Als je mijn blog vaker leest, dan weet je misschien dat ik bezig ben met een omscholingstraject richting web development. Dat gaat prima maar binnenkort meer daar over.

Net viel me echter een bekend patroon op. Of beter gezegd, het viel me op dat mijn beslissingsproces over de vraag of ik vandaag wel of niet blog sterk lijkt op de manier waarop een computer keuzes maakt. In wezen is er daarbij alleen ja of nee en dat ja of nee wordt bepaald door allerlei voorwaarden – waaraan wel of niet wordt voldaan.

Als dit of dan voert de computer een bepaald codeblok uit. Wordt aan een voorwaarde niet voldaan, dan wordt er geen of een ander stuk code uitgevoerd.

En eigenlijk blog ik vaak op dezelfde manier

Ik stel allerlei voorwaarden. Als ik een onderwerp heb, als ik tijd heb, als ik vandaag niet heb toegegeven aan allerlei slechte gewoontes; dan blog ik. Voldoe ik aan al die voorwaarden niet, dan treedt de else constructie in werking: ik blog vandaag niet.

Vandaar dat het dus nog niet echt wil vlotten met de activiteit op dit blog. En dan zit me behoorlijk dwars. Daar dacht ik dus vanmorgen al nieuwsbrief lezend over na. Eigenlijk gaan van de dingen die ik vaker wil doen vooral die dingen me gemakkelijk af waar ik geen voorwaarden aan heb gekoppeld en en waar ik mee ben begonnen terwijl ik mee las met het project over het aanwennen van gewoontes waar Peter vorig jaar over blogde aan de hand van het Zen habits boek van Leo Babauta.

Grote verschil: geen voorwaarden maar gewoon doen.

En dat me ook voor dit blog een goede insteek. Dus laat ik voortaan mijn if (voorwaarde) {doe dit;} (else {doe dat;}) constructies aan de programmeertalen en zijn schrijfvoorwaarden op dit blog hopelijk taboe.

@foto VIA PIXABAY met CC0 verklarinG

#WOT 30 Concept

Het eerste Biggles-boek dat ik vertaalde, The Boy Biggles, verhaalde onder andere Victoria_Cross_Medal_Ribbon_&_Barover iemand die het Victoria Cross had ontvangen. In mijn vertaling kende ik deze persoon prompt het Ijzeren Kruis toe. De onderscheiding van de (latere) vijand. Gelukkig zag ik het tijdig en staat het alleen in een concept. Jeugdig enthousiasme zullen we maar zeggen. Toch blijkt ieder boek weer dat er toch nog bepaalde dingen verder komen dan de diverse concepten, hoe vaak mijn medevertaler(s), bestuursleden  of ik het ook herlezen. Ik kan meestal wel een verklaring voor de foutjes vinden zodat ik er lering uit kan trekken, maar toch.

Ook dit blog ziet er in concept heel anders uit dan in de harde werkelijkheid. Zo had ik een week of vier terug stoute plannen: ik ging weer meedoen aan #WOT, aan #SG16, aan #50books en ik zou wekelijks een blogpost schrijven over mijn nieuwe opleiding tot webontwikkelaar en ook wekelijks nog eentje over hoe ik leer. Het concept was prachtig, ik vergat alleen dat ik de blogposts ook nog daadwerkelijk moest schrijven.

Daarnaast zat ik een beetje met mezelf in de knoop omdat mijn betere ik niet genoeg op mijn werkelijke ik leek, maar hopelijk kan ik daar nu langzaam verandering in gaan brengen. Ideeën genoeg om over te bloggen omdat het prima gaat op mijn opleiding en ik van mezelf weet dat ik beter leer als ik het nog eens opschrijf/uitleg. Webruimte heb ik alvast zodat het dit blog niet in de weg zit.

De weg van concept naar realiteit mag er dan een zijn vol hobbels, maar juist die hobbels maken de reis leerzaam. En bovendien heeft Raymond groot gelijk: kennis delen is fijn.

Deze blogpost maakt deel uit van #WOT: Write on Thursday. Iedere donderdag een woord van Martha/DrsPee om over te bloggen of vloggen.

~ ~ ~ ~

Bron afbeelding: Wikipedia.

Mobile first met een kleurtje

Web development uitdagingen

De uitdaging die ik mijzelf stelde in de eerste aflevering van deze nieuwe serie over de vorderingen die ik maak tijdens mijn opleiding tot webontwikkelaar was om een website te bouwen. De serie heet Web development uitdagingen en toen bleek dat het bijbehorende domein nog vrij was, heb ik dat maar snel geregistreerd.

Het resultaat van uitdaging 1 is dan ook te bewonderen op dat nieuwe domein. Dat geeft mij de vrijheid om te oefenen zonder dat ik mijn blog in de weg zit. Neem vooral even een kijkje, ik loop niet weg.

De uitdaging die ik mij hier stelde viel uiteen in een tweetal deeluitdagingen:

  1. Ontwerp een pagina die responsive is. Of te wel een pagina die er op elk formaat scherm goed uitziet. Natuurlijk had ik het mezelf makkelijk kunnen maken door uit te gaan van een kant-en-klaar Bootstrap ontwerp maar daarmee zou de uitdaging een stuk minder interessant zijn. Het was er mij juist om te doen om een zelf van de grond af een responsive website te bouwen en zo toe te passen wat ik tijdens mijn opleiding heb geleerd.Gelukkig blijkt responsive design niet heel ingewikkeld. Het geheim zit hem vooral in de grid en de media queries. Het eerste is een matrix waarmee je een scherm onderverdeelt in vlakken. Bij grid systems als Bootstrap zijn dat er meestal 12. Een pagina is dan opgebouwd uit rijen met daarin kolommen. De som van het totale aantal kolommen in een volledige rij bedraagt altijd 12. Ik heb in mijn ontwerp gekozen voor een item van drie kolommen (het menu), een van zes voor de hoofdtekst  waar nu nog een dummytekst staat en waar drie kolommen voor Done/To do.

    Bekijk je de pagina echter met een smartphone dan zijn de elementen gestapeld, of stacked, zoals dat in het Engels heet. Dat doe je door media queries op te nemen in je stylesheet. Een media query ziet er bijvoorbeeld zo uit:

    @media screen and (max-width: 767px){
    	[class*="col-"] {
        width: 100%;
    }
    

    Deze regel zorgt ervoor dat op schermen die maximaal 767 pixels breed zijn (smartphones) alle elementen de klasse “col-” in de naam 100% breed zijn en dus gestapeld worden.

    In de stylesheet en de html pagina heb ik ook van jQuery gebruikt om de pagina schaalbaar te maken,  het menu te verbergen bij kleine schermen om de breedte van het middengedeelte breder te maken als er een geen menu in beeld is. In code ziet dat er als volgt uit:

    <script>
    	$(document).ready(function() {
    		$("#menubutton").click(function() {
    			$("#menubutton").hide();
    			$("#menu").show();
    			$("#content").toggleClass("col-md-9");
    		});
    	});
    </script>
  2. Het tweede deel van de uitdaging lag in het grafisch ontwerp van de de site. Zelf heb ik weinig kleurgevoel maar gelukkig is daar Paletton (voorheen Color Scheme Designer). Kleurenlay-outs met 2, 3,  of 4 kleurgroepen of juist varianten van één bepaalde tint, het kan allemaal met een paar klikken. Zelf koos ik via de kleurencirkel voor een ontwerp met 1 hoofdkleur en 2 secundaire kleuren die ik keurig geëxporteerd kreeg naar CSS waarden. Maar het bleek nog een aardige klus om en ander te verwerken in mijn eigen pagina-ontwerp. Eerst had ik ook nog een lichtgroene zijbalk, maar dat vond ik minder mooi. Wat er staat, bevalt me zolang het duurt. Het aanpassen van het kleurenschema hoeft echter – dat heb ik nu wel geleerd – geen heel ingewikkelde zaak te zijn en omdat ik daarbij niet op mijn eigen gevoel voor kleurencombinaties hoef te vertrouwen, heb ik goede hoop dat het resultaat blijft ogen.

Web development uitdaging 2

Tot zover mijn uitwerking van de uitdaging van anderhalve week geleden.  Nu staat er nog dummycontent op de site en werken de links nog niet. Voordat ik aan mijn opleiding begon heb ik ook wat gewinkeld bij Udemy. De uitdaging voor volgende week is om de opdrachten die ik daarvoor gemaakt heb nog eens door te nemen en te verwerken in mijn nieuwe site.

PS: bij nader inzien leek het mij handiger om de verschijningsdagen van Van lezen naar doen en Web development uitdagingen om te draaien. De tweede aflevering van Van lezen naar doen verschijnt dan ook komende vrijdag en de web development uitdagingen blijven op de maandag.

Van lezen naar doen: aftrap

start

Weet ik van mijn serie Web development uitdagingen ongeveer wat daarvan het doel is, van deze serie is dat me iets minder duidelijk. Grondgedachten achter het idee zijn dat alleen lezen op zichzelf geen handige manier is om iets te leren  maar dat ik vaak juist dingen die het onthouden bevorderen vermijd.

Een kleine greep:

  • Uitstelgedrag (inclusief nogmaals lezen)
  • Alles voor mezelf houden (in plaats van het met een ander bespreken)
  • Geen aantekeningen maken
  • Niet oproepen uit geheugen
  • Niet toepassen

Deze serie kon wel eens een zoektocht gaan worden naar hoe ik deze en andere punten op kan lossen. Ik vrees dat ik daarvoor nog meer ga lezen. Maar nu met het oogmerk op toepassen. Hoewel ik nog geen Waanzinnig Plan heb, lijkt het (bijna) gelijknamige boek van Marcel van Driel of zijn Geen tijd, geen geld, toch doen uit wat ik ervan heb begrepen met doorbladeren redelijk actiegericht. Juist actie waar ik iemand anders voor nodig heb, ligt mij niet echt. Durf te vragen, zeg maar.

Voor de eerste week ga ik op zoek naar manieren om informatie te kanaliseren. Voor deze serie en voor Web development uitdagingen ben ik namelijk van plan veel meer gebruik te gaan maken van bronvermelding. Simpelweg omdat het minder mijn eigen ervaring is die ik deel maar mijn leerproces. En leren doe je vaak van een ander.

Evernote c.s. Here I come.

Overigens wil ik behalve eenmalig lezen en toepassen er ook voor zorgen dat ik wat ik schrijf ook een blijvend onthoud/toepas. Strategieën die ik daarvoor inzet of uitprobeer, zal ik ook in deze serie bespreken.

@foto VIA PIXABAY met CC0 verklarinG