unleashing creative freedom with modx (2015-09-03 at groningenphp)

38
Unleashing Creative Freedom with

Upload: mark-hamstra

Post on 12-Apr-2017

482 views

Category:

Internet


0 download

TRANSCRIPT

Unleashing Creative Freedom with

What is your current platform of choice?

Who am I?Mark Hamstra

Founder & CEA at modmore Freelance MODX Developer

my doggies

Turbo

Bommel

Agenda

• What is MODX, for whom, available features, how to build a MODX site

• Tour of the MODX Manager (back-end)

• The Architecture of MODX, xPDO ORM, extending and overriding

MOD-what?

• Open Source

• Written in PHP (of course)

• Primarily used with MySQL, other drivers available

• Already 10 years old young

• Content Management System Framework Platform

https://twitpic.com/3pvrmw

For who is MODX

• Web Professionals

• Designers

• Front-end developers

• Using MODX as a tool

• Est 4-5.000.000 sites

Community

• Professional and helpful • Official Forum: forums.modx.com 50.544 • +- 1M views of modx.com per month • Twitter: #MODX • Slack: modx.org 286

All the features of a CMS

rich text editor versioning user groups multisite templates multilingual extensions

markdown media browser hierarchical page tree commercial support automatic menu builder blogging permissions seo

friendly urls server-side caching

Installs without Assumptions

Elements as Building Blocks

TemplatesTemplate Variables

ChunksSnippetsPlugins

Templates

• Usually HTML

• Contains MODX tags

• One template per page

Template Variables

• Custom field for resources

• Commonly “TV”

• Tied to templates

• Text, image, select, checkbox, date, radio, richtext, tag and custom types available

• [[*name-of-tv]]

Chunks

• Usually HTML

• Reusable piece of code

• [[$name-of-chunk]]Template

Chunk “head”

Snippets

• PHP!

• Comparable to a function

• Accepts properties

• [[name-of-snippet]] or [[!name-of-snippet]]

Snippet “helloWorld”

Template

Snippets

But wait, there’s more!

• [[name-of-snippet]]

• [[!name-of-snippet]]

• = uncached!

• [[++name-of-setting]][[!++name-of-setting]]

• [[$name-of-chunk]][[!$name-of-chunk]]

• [[*name-of-field]][[!*name-of-field]]

But wait, there’s even more!

• [[helloWorld? &property=`value ̀]]

• [[$head? &extraCss=`<link rel=.. href=..> ̀]]

Plugins

• PHP!

• Event-based, so no tags

• Can read and often influence behaviour

No need to reinventthe wheel

• Packages (aka extras, add-ons, extensions, third party components…) provide common functionality

• Install via Package Installer inside the manager

Example: getResources

• Lists resources matching conditions

• Uses a Chunk as template

• Use Cases:

• Article listings

• Dynamic (sub)menus

• RSS feed generation

Template

Chunk “blogListItem”

Time for a Manager Tour!http://localhost/tmp/phpfrl/manager/

MODX Architecture

Secure by Design

• Automatic $_GET, $_POST, $_REQUEST sanitisation in the request handler

• xPDO ORM prevents SQL Injections

• 28 CVE entries, 8 since 2014 • WordPress: 906, already ~85 in 2015 • Drupal: 915, already ~120 in 2015

2015-07, cve.mitre.org

xPDO

• Object Relational Bridge / ORM

• Open Source (modxcms/xpdo)

• Extension to PHP’s PDO

• Support for MySQL, sqlsrv (and more)

Fetching a Single Object

$obj = $modx->getObject(‘modChunk’, 5);

$c = array(‘name’ => ‘head’);

$obj = $modx->getObject(‘modChunk’, $c)

Easy Query Builder

$c = $modx->newQuery(‘modResource’);

$c->where([

‘parent’ => 0,

‘AND:pagetitle:LIKE => ‘%About%’

]);

$matches = $modx->getCollection(‘modResource’, $c);

foreach ($matches as $modResource) { . . . }

Automatic Filtering

$search = $_POST[‘search’];

$c = $modx->newQuery(‘modResource’);

$c->where([

‘introtext:LIKE’ => “%{$search}%”,

]);

$modx->setPlaceholder(‘search’, sanitise($search));

function sanitise($value) { return htmlentities($value, ENT_QUOTES, ‘UTF-8’); }

👍

Custom Models with xPDO

1. Create an xPDO Package Schema (XML)

2. Use build script to write schema into the actual model files/classes

3. Register it before use ($modx->addPackage)

4. Use any xPDO method (getObject, getCollection) on your custom model

xPDO Package Schema - Head

<?xml version="1.0" encoding="UTF-8"?>

<model package="phpfrl"

baseClass="xPDOSimpleObject"

platform="mysql"

defaultEngine="MyISAM"

version="1.1">

xPDO Package Schema - Object

<?xml version="1.0" encoding="UTF-8"?>

<model package=“phpfrl” …

<object class="frlMeetup" table=“meetups”>

.. fields ..

</object>

<object class="frlSpeaker" table=“speakers”> … </object>

</model>

xPDO Package Schema - Fields<?xml version="1.0" encoding="UTF-8"?>

<model package=“phpfrl” …

<object class="frlMeetup" table=“meetups">

<field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default=“PHP FRL Meetup" />

xPDO Package Schema - Indices

<?xml version="1.0" encoding="UTF-8"?>

<model package=“phpfrl” …

<object class="frlMeetup" table=“meetups"> <field key="name" dbtype=“varchar" … <field key=“starts_on" dbtype=“datetime" <field key="name" dbtype=“varchar" …

<index alias="name" name="name" primary="false" unique="false" type="BTREE"> <column key="name" length="" collation="A" null="false" /> </index> </object>

xPDO Package Schema - Relations<?xml version="1.0" encoding="UTF-8"?>

<model package=“phpfrl” baseClass=“xPDOSimpleObject" …

<object class="frlMeetup" table=“meetups"> <field key="name" dbtype=“varchar” …>

<composite alias=“Speakers” class=“frlSpeaker” local=“id” foreign=“meetup” cardinality=“many” owner=“local” /> </object>

<object class="frlSpeaker" table=“speakers"> <field key="name" dbtype=“varchar” …> <field key="meetup" dbtype=“int” …>

<aggregate alias=“Meetup” class=“frlMeetup” local=“meetup” foreign=“id” cardinality=“one” owner=“foreign” /> </object>

xPDO Generated Model

<?phpclass frlMeetup extends xPDOSimpleObject {

}

Interacting with that model$modx->addPackage(‘phpfrl’, ‘/path/to/model/‘);

$c = $modx->newQuery(‘frlMeetup’);$c->sortby(‘starts_on’, ‘DESC’);$meetup = $modx->getObject(‘frlMeetup’, $c);

echo ‘De volgende meetup is ‘ . $meetup->name . ‘ en vind plaats op ‘ . $meetup->starts_on . ‘. ’;

$speakers = $meetup->getMany(‘Speakers’); // or just $meetup->Speakersforeach ($speakers as $spegfytaker) { echo $speaker->name . ‘ zal vertellen over ‘ . $speaker->subject;}

Interesting links: • MODX.com => official website • rtfm.modx.com => official documentation • github.com/modxcms/revolution => source code • MODX.today => daily links/articles about MODX • modmore.com => premium extras for MODX • https://joind.in/talk/view/15031 => please leave feedback

Enjoy your Creative Freedom