Nette framework (WebElement #28)

Preview:

DESCRIPTION

 

Citation preview

NETTE FRAMEWORKA POPULAR TOOL FOR PHP WEB DEVELOPMENT...

(ON SERVER)

Adam Štipák (@new_POPE)

CREATED BY

@DAVIDGRUDL

1.4.2014

DIED!

WELCOMENETTE "SMALL PROJECTS"!

I WILL TALK ABOUT NETTE

AS IF IT WERE ONE PACKAGE

ROBOTLOADER $loader = new Nette\Loaders\RobotLoader; $loader->addDirectory('app'); $loader->addDirectory('libs'); $loader->setCacheStorage(...); $loader->register();

netterobots.txt

Disallow: /Zend

FORMSvalidate sent data both client-side (JavaScript) and server-sideprovide high level of securitymultiple render modestranslations, i18n

FIRST FORM $form = new Form; $form->addText('name', 'Name:'); $form->addText('surname', 'Surname:') ->setRequired('Please fill your surname.');

if ($form->isSubmitted() && $form->isValid()) { echo 'Form was submitted and passed validation';

$values = $form->getValues(); dump($values); }

<script src="netteForms.js"></script>

PRESENTER FORMSPresenter

protected function createComponentSignInForm() { $form = new Nette\Application\UI\Form; $form->addText('name', 'Name:'); $form->addPassword('password', 'Password:'); $form->addSubmit('login', 'Log in'); $form->onSuccess[] = array($this, 'signInFormSubmitted'); return $form; }

function signInFormSubmitted($form) { // called when form is submitted and successfully validated }

Latte

{control signInForm}

MULTIPLE RENDER MODES {form signForm} <table> <tr class="required"> <th>{label name /}</th> <td>{input name}</td> </tr>

...

</table> {/form signForm}

<table> <tr class="required"> <th><label for="frm-name"></th> <td><input cols=40 n:name="name"></td> </tr> <table>

TEMPLATING (LATTE)macros & helpersuser-defined macrosblocks & inheritanceContext-Aware Escaping

MACROS & HELPERS <ul n:if="$items"> {foreach $items as $item} <li id="item-{$iterator->counter}">{$item|capitalize}</li> {/foreach} </ul>

macro in braces, for example {foreach …}n:macro, for example n:if="…"

USER-DEFINEDMacro

$latte = new Nette\Latte\Engine; $set = new Nette\Latte\Macros\MacroSet($latte->compiler);

$set->addMacro('if', function($node, $writer) { return $writer->write('if (%node.args):'); }, 'endif');

Helper

$template->registerHelper('shortify', function ($s) { return mb_substr($s, 0, 10); });

<p>{$text|shortify:100}</p>

BLOCKS & INHERITANCEfoo.latte

{block foo} FOO {/block}

<div n:block="foo"> FOO </div>

bar.latte

{extends 'foo.latte'}

{block foo} BAR {/block} <!-- n:block -->

CONTEXT-AWARE ESCAPING <div>{$foo}</div>

<script type="text/javascript">

</script>

alert({$foo}); arr = {$array};

DI, DI EXTENSIONS

DIconfig.neon

services: foo: Foo bar: Bar

PHP

class Bar { function __construct(Foo $foo) { // $foo is instanceof Foo } }

DI CONTAINER EXTENSIONSconfig.neon

extensions: blog: MyBlogExtension

blog: # same name as your extension postsPerPage: 10 comments: FALSE

PHP

class MyBlogExtension extends Nette\DI\CompilerExtension {

public function loadConfiguration() { $config = $this->getConfig(); // array(2) [ 'postsPerPage' => 10, 'comments' => FALSE ]

COMPONENTS &CONTROLS

reusable codesignalsflash messages

COMPONENT use Nette\Application\UI\Control;

class PollControl extends Control { ... }

public function render() { $template = $this->template; $template->setFile(dirname(__FILE__) . '/PollControl.latte');

$template->param = 'some value';

$template->render(); }

SIGNALSIn component

$url = $this->link('click!', $x, $y);

<a n:href="click! $x, $y"> ... </a>

FLASH MESSAGEScomponent

public function deleteFormSubmitted(Form $form) { ... delete record using model ...

// pass flash message $this->flashMessage('Item was deleted.');

$this->redirect(...); // and redirect }

template

{foreach $flashes as $flash} <div class="flash {$flash->type}">{$flash->message}</div> {/foreach}

ROUTINGTwo way conversion!SimpleRouterRoute

TWO WAY CONVERSION \Nette\Http\IRequest (includes URL) -> \Nette\Application\Request

\Nette\Application\Request -> absolute URL

template

{link Foo:bar 1} -> /foo/bar/1 {link Foo: 1} -> /foo/default/1 {link :Module:Presenter:action} -> /module/presenter/action

ROUTE $route = new Route( '<presenter>/<action>[/<id>]', 'Homepage:default' );

$route = new Route( '<presenter>/<action>[/<id>]', array( 'presenter' => 'Homepage', 'action' => 'default' ) );

ROUTE $route = new Route( '<presenter=Homepage>/<action=default>', array( 'action' => array( Route::FILTER_IN => function($action) { return strrev($action); }, Route::FILTER_OUT => function($action) { return strrev($action); }, ), ) );

AJAJAAJ AJAXAJAXsnippets

AJAX public function actionDelete($id) { if ($this->isAjax()) { $this->payload->message = 'Success'; } }

public function handleClick($param) { ... }

$this->sendResponse(new JsonResponse(array('key' => 'value', ...)));

public function handlePool(...) { $this->redrawControl('header'); }

SNIPPETStemplate

{snippet header} Hello {$foo}! {/header} <a n:href="redrawHeader">Click me!</a>

PHP

function handleRedrawHeader() { $this->template->foo = "World"; $this->redrawControl('header'); }

DEBUGGING AND ERRORHANDLING

debugger barquickly detect and correct errorslog errors

DEBUGGER BAR

TRACY (PRODUCTION MODE)

LOG ERRORS // Log an error. Debugger::log('Unexpected error');

// Set error mail. Debugger::$email = 'admin@example.com';

// config.neon common: nette: debugger: email: admin@example.com

DATABASEYOU ALREADY KNOW SOMETHING LIKE NOTORM, DIBI,

DOCTRINE

NETTE 2.2 BETA

ApplicationCachingComponentModelNette DatabaseDIFinderFormsHttpLatteMailNeonPhpGeneratorReflectionRobotLoaderSecurity...

THANKS

Recommended