nette framework (webelement #28)
DESCRIPTION
TRANSCRIPT
![Page 1: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/1.jpg)
NETTE FRAMEWORKA POPULAR TOOL FOR PHP WEB DEVELOPMENT...
(ON SERVER)
Adam Štipák (@new_POPE)
![Page 2: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/2.jpg)
CREATED BY
@DAVIDGRUDL
![Page 3: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/3.jpg)
1.4.2014
![Page 4: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/4.jpg)
DIED!
![Page 5: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/5.jpg)
WELCOMENETTE "SMALL PROJECTS"!
![Page 6: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/6.jpg)
I WILL TALK ABOUT NETTE
AS IF IT WERE ONE PACKAGE
![Page 7: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/7.jpg)
ROBOTLOADER $loader = new Nette\Loaders\RobotLoader; $loader->addDirectory('app'); $loader->addDirectory('libs'); $loader->setCacheStorage(...); $loader->register();
netterobots.txt
Disallow: /Zend
![Page 8: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/8.jpg)
FORMSvalidate sent data both client-side (JavaScript) and server-sideprovide high level of securitymultiple render modestranslations, i18n
![Page 9: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/9.jpg)
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>
![Page 10: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/10.jpg)
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}
![Page 11: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/11.jpg)
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>
![Page 12: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/12.jpg)
TEMPLATING (LATTE)macros & helpersuser-defined macrosblocks & inheritanceContext-Aware Escaping
![Page 13: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/13.jpg)
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="…"
![Page 14: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/14.jpg)
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>
![Page 15: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/15.jpg)
BLOCKS & INHERITANCEfoo.latte
{block foo} FOO {/block}
<div n:block="foo"> FOO </div>
bar.latte
{extends 'foo.latte'}
{block foo} BAR {/block} <!-- n:block -->
![Page 16: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/16.jpg)
CONTEXT-AWARE ESCAPING <div>{$foo}</div>
<script type="text/javascript">
</script>
alert({$foo}); arr = {$array};
![Page 17: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/17.jpg)
DI, DI EXTENSIONS
![Page 18: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/18.jpg)
DIconfig.neon
services: foo: Foo bar: Bar
PHP
class Bar { function __construct(Foo $foo) { // $foo is instanceof Foo } }
![Page 19: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/19.jpg)
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 ]
![Page 20: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/20.jpg)
COMPONENTS &CONTROLS
reusable codesignalsflash messages
![Page 21: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/21.jpg)
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(); }
![Page 22: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/22.jpg)
SIGNALSIn component
$url = $this->link('click!', $x, $y);
<a n:href="click! $x, $y"> ... </a>
![Page 23: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/23.jpg)
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}
![Page 24: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/24.jpg)
ROUTINGTwo way conversion!SimpleRouterRoute
![Page 25: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/25.jpg)
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
![Page 26: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/26.jpg)
ROUTE $route = new Route( '<presenter>/<action>[/<id>]', 'Homepage:default' );
$route = new Route( '<presenter>/<action>[/<id>]', array( 'presenter' => 'Homepage', 'action' => 'default' ) );
![Page 27: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/27.jpg)
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); }, ), ) );
![Page 28: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/28.jpg)
AJAJAAJ AJAXAJAXsnippets
![Page 29: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/29.jpg)
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'); }
![Page 30: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/30.jpg)
SNIPPETStemplate
{snippet header} Hello {$foo}! {/header} <a n:href="redrawHeader">Click me!</a>
PHP
function handleRedrawHeader() { $this->template->foo = "World"; $this->redrawControl('header'); }
![Page 31: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/31.jpg)
DEBUGGING AND ERRORHANDLING
debugger barquickly detect and correct errorslog errors
![Page 32: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/32.jpg)
DEBUGGER BAR
![Page 34: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/34.jpg)
TRACY (PRODUCTION MODE)
![Page 35: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/35.jpg)
LOG ERRORS // Log an error. Debugger::log('Unexpected error');
// Set error mail. Debugger::$email = '[email protected]';
// config.neon common: nette: debugger: email: [email protected]
![Page 36: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/36.jpg)
DATABASEYOU ALREADY KNOW SOMETHING LIKE NOTORM, DIBI,
DOCTRINE
![Page 37: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/37.jpg)
NETTE 2.2 BETA
![Page 38: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/38.jpg)
ApplicationCachingComponentModelNette DatabaseDIFinderFormsHttpLatteMailNeonPhpGeneratorReflectionRobotLoaderSecurity...
![Page 39: Nette framework (WebElement #28)](https://reader034.vdocument.in/reader034/viewer/2022042813/5481f61e5906b5e2048b45c1/html5/thumbnails/39.jpg)
THANKS