SlideShare ist ein Scribd-Unternehmen logo
1 von 142
Downloaden Sie, um offline zu lesen
The Naked Bundle
Matthias Noback
Assuming you all have a
working project
https://github.com/matthiasnoback/
high-quality-bundles-project
Generate a bundle
Use app/console generate:bundle
Namespace: Dpc/Bundle/TutorialBundle
Bundle name: DpcTutorialBundle
Configuration: yml
Whole directory structure: yes
The full directory structure of a bundle:
What's wrong?
Too many comments
Routing and a controller
Translations
Twig templates
A useless test
You are not going to use it all,
but it will be committed!
Before we continue, clean up your
bundle
Remove the following files and directories:
Controller
Resources/doc
Resources/public
Resources/translations
Resources/views
Tests
Also remove any superfluous comments!
The official
view on
bundles
First-class citizens
Documentation » The Quick Tour » The Architecture
I think your code is more important than the framework,
which should be considered an implementation detail.
All your code lives in a
bundle
Documentation » The Book » Creating Pages in Symfony2
I don't think that's a good idea.
It contradicts the promise of reuse of "pre-built feature
packages".
Almost everything lives
inside a bundle
Documentation » Glossary
Which is not really true, because many things live inside
libraries (e.g. the Symfony components), which is good.
Best practices
Documentation » Cookbook » Bundles
Controllers
Controllers don't need to extend anything at all.
ContainerAware*should be avoided in all cases.
Tests
What's up with the 95%?
Twig
Why Twig? I though Symfony didn't care about this.
Documentation » The Book » Creating and Using Templates
The old view on bundles is
not sufficient anymore
People are reimplementing things because existing
solutions are too tightly coupled to a framework (or even a
specific version).
Why is it necessary to do all these things again for Symfony,
Laravel, Zend, CodeIgniter, CakePHP, etc.?
Last year I started working
on this
Then it became this
About bundles
A bundle is...
A thin layer of Framework-specific
configuration to make resources from some
library available in a Symfony2 application.
A "Symfony application"
meaning:
A project that depends on the Symfony FrameworkBundle.
Resources are
Routes (Symfony Routing Component)
Services (Symfony DependencyInjection Component)
Templates (Twig)
Form types (Symfony Form Component)
Mapping metadata (Doctrine ORM, MongoDB ODM, etc.)
Translations (Symfony Translation Component)
Commands (Symfony Console Component)
...?
So: a bundle is mainly configuration to make these resources
available, the rest is elsewhere in a library.
I also wrote
The challenge
Make the bundle as clean as possible
Entities
Create an entity
Use app/console doctrine:generate:entity
Specs
The entity shortcut name: DpcTutorialBundle:Post.
Configuration format: annotation
It has a title(string) field.
Run app/console doctrine:schema:createor
update --forceand make sure your entity has a
corresponding table in your database.
Let's say you've modelled the Post
entity very well
You may want to reuse this in other projects.
Yet it's only useful if that project uses Doctrine ORM too!
Why?
Annotations couple the Postclass to Doctrine ORM.
(Since annotations are classes!)
Also: why are my entities inside a
bundle?
They are not only useful inside a Symfony project.
Move the entity to another
namespace
E.g. DpcTutorialModelPost.
Create an XML mapping file
E.g. DpcTutorialModelMappingPost.orm.xml
<doctrine-mappingxmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-ma
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entityname="DpcTutorialModelPost">
<idname="id"type="integer">
<generatorstrategy="AUTO"/>
</id>
<fieldname="title"type="string"/>
</entity>
</doctrine-mapping>
You can copy the basic XML from
/vendor/doctrine/orm/docs/en/reference/xml-
mapping.rst.
In fact
Always use XML mapping, it makes a lot of sense, and you
get auto-completion in your IDE!
Remove all ORM things (annotations) from the Postclass
If you are going to try the following at home:
Update DoctrineBundle
Modify composer.json:
{
"require":{
...
"doctrine/doctrine-bundle":"~1.2@dev"
}
}
Run composer update doctrine/doctrine-bundle
Add a compiler pass to your bundle
It will load the XML mapping files
useDoctrineBundleDoctrineBundleDependencyInjectionCompilerDoctrineOrmMappingsPass;
classDpcTutorialBundle
{
publicfunctionbuild(ContainerBuilder$container)
{
$container->addCompilerPass($this->buildMappingCompilerPass());
}
privatefunctionbuildMappingCompilerPass()
{
returnDoctrineOrmMappingsPass::createXmlMappingDriver(
array(
__DIR__.'/../../Test/Model/Mapping/'
=>'DpcTutorialModel'
)
);
}
}
What have we won?
Clean model classes
They are reusable in non-Symfony projects
They are reusable with different persistence libraries
Documentation » The Cookbook » Doctrine » How to provide model classes for several Doctrine
implementations
Controllers
Create a controller
Use app/console generate:controller
Specs
Name: DpcTutorialBundle:Post
Configuration: annotation
Template: twig
The route contains an idparameter.
Action: showAction
Route: /post/{id}/show
Implement the following logic
Modify the action to retrieve a Postentity from the
database:
publicfunctionshowAction(Post$post)
{
returnarray('post'=>$post);
}
Don't forget to register the route
#inthebundle'srouting.ymlfile:
DpcTutorialBundle_Controllers:
resource:"@DpcTutorialBundle/Controller"
type:"annotation"
By the way
Consider using XML for routing too!
For the same reasons
Does all of this really need
to be inside the bundle?
Move the controller class to the
library
Remove parent Controllerclass
We are going to inject every dependency by hand instead of
relying on the service container.
Create a service for the controller
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
Remove @Routeannotations
Instead: define actual routes in the bundle's routing.yml
file.
Use the service id of the controller instead of its class name.
dpc_tutorial.post_controller.show:
path:/post/{id}/show
defaults:
_controller:dpc_tutorial.post_controller:showAction
Remove @Templateannotations
Inject the templatingservice instead and use it to render
the template.
useSymfonyComponentHttpFoundationResponse;
useSymfonyComponentTemplatingEngineInterface;
classPostController
{
publicfunction__construct(EngineInterface$templating)
{
$this->templating=$templating;
}
publicfunctionshowAction(Post$post)
{
returnnewResponse(
$this->templating->render(
'DpcTutorialBundle:Post:show.html.twig',
array('post'=>$post)
)
);
}
}
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
arguments:
-@templating
What about the
Templates
Move the template to the library
E.g. from Dpc/Bundle/TutorialBundle/Resources/views/Post/show.html.twigto
Dpc/Tutorial/View/Post/show.html.twig
Change the template reference
$this->templating->render(
'@DpcTutorial/Post/show.html.twig',
array('post'=>$post)
)
Register the new location of the
templates
#inconfig.yml
twig:
...
paths:
"%kernel.root_dir%/../src/Dpc/Tutorial/View":DpcTutorial
Documentation » The Cookbook » Templating » How to use and Register namespaced Twig Paths
Well...
We don't want to ask users to modify their config.yml!
Let's prepend
configuration
useSymfonyComponentDependencyInjectionExtensionPrependExtensionInterface;
classDpcTutorialExtensionextendsConfigurableExtensionimplementsPrependExtensionInter
{
...
publicfunctionprepend(ContainerBuilder$container)
{
$bundles=$container->getParameter('kernel.bundles');
if(!isset($bundles['TwigBundle'])){
return;
}
$container->prependExtensionConfig(
'twig',
array(
'paths'=>array(
"%kernel.root_dir%/../src/Dpc/Tutorial/View"=>'DpcTutorial'
)
)
);
}
}
Documentation » The Cookbook » Bundles » How to simplify configuration of multiple Bundles
One last step!
The action's $postargument relies on something called
.param converters
Those convert the idfrom the route to the actual Post
entity.
This is actually Symfony framework-specific behavior
Rewrite the controller to make use
of a repository
useDoctrineCommonPersistenceObjectRepository;
classPostController
{
publicfunction__construct(...,ObjectRepository$postRepository)
{
...
$this->postRepository=$postRepository;
}
publicfunctionshowAction($id)
{
$post=$this->postRepository->find($id);
if(!($postinstanceofPost)){
thrownewNotFoundHttpException();
}
...
}
}
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
arguments:
-@templating
-@dpc_tutorial.post_repository
dpc_tutorial.post_repository:
class:DoctrineCommonPersistenceObjectRepository
factory_service:doctrine
factory_method:getRepository
arguments:
-DpcTutorialModelPost
What do we have now?
Reusable templates
Reusable controllers
They work with Silex too!
Who would have though that was possible?
Console commands
Create a console command
Use app/console generate:console-command
Make it insert a new post in the database.
It takes one argument: the post's title.
Something like this
useDpcTutorialModelPost;
useSymfonyBundleFrameworkBundleCommandContainerAwareCommand;
useSymfonyComponentConsoleInputInputArgument;
useSymfonyComponentConsoleInputInputInterface;
useSymfonyComponentConsoleOutputOutputInterface;
classCreatePostCommandextendsContainerAwareCommand
{
protectedfunctionconfigure()
{
$this
->setName('post:create')
->addArgument('title',InputArgument::REQUIRED);
}
protectedfunctionexecute(InputInterface$input,OutputInterface$output)
{
$manager=$this->getContainer()
->get('doctrine')
->getManagerForClass('DpcTutorialModelPost');
$post=newPost();
$post->setTitle($input->getArgument('title'));
$manager->persist($post);
$manager->flush();
$output->writeln('Newpostcreated:'.$post->getTitle());
}
}
Why is it inside a bundle?
Because it is automatically registered when it's in the
Commanddirectory.
So let's move it out!
Move the command to the library
Create a service for it
Give it the tag console.command.
Or else it won't be recognized anymore!
services:
dpc_tutorial.create_post_command:
class:DpcTutorialCommandCreatePostCommand
tags:
-{name:console.command}
What about ContainerAware?
It couples our command to the Symfony framework.
Which is not needed at all.
Extend from Command
Then inject dependencies instead of fetching them from the
container.
useDoctrineCommonPersistenceManagerRegistry;
classCreatePostCommandextendsCommand
{
private$doctrine;
publicfunction__construct(ManagerRegistry$doctrine)
{
parent::__construct();
$this->doctrine=$doctrine;
}
...
protectedfunctionexecute(InputInterface$input,OutputInterface$output)
{
$manager=$this->doctrine->getManager();
...
}
}
services:
dpc_tutorial.create_post_command:
class:DpcTutorialCommandCreatePostCommand
arguments:
-@doctrine
tags:
-{name:console.command}
What do we have?
Explicit dependencies
Reusable commands that works in all projects that use the
Symfony Console Component (like )
A bit less magic (no auto-registering commands)
Which means now we can put anything we want in the
Commanddirectory
Cilex
Testing a
bundle
Or: testing configuration
The Configurationclass
I don't get it!
I don't trust myself with it.
And when I don't trust myself, I write tests
SymfonyConfigTest
On GitHub: SymfonyConfigTest
{
"require-dev":{
"matthiasnoback/symfony-config-test":"~0.1"
}
}
Prepare a test suite for your
Configurationclass
Create a directory Tests/DependencyInjectioninside
the bundle.
In that directory create a new class:
ConfigurationTest.
Create the test class
The ConfigurationTestshould extend from
AbstractConfigurationTestCase
Implement the missing method getConfiguration()
namespaceDpcBundleTutorialBundleTestsDependencyInjection;
useDpcBundleTutorialBundleDependencyInjectionConfiguration;
useMatthiasSymfonyConfigTestPhpUnitAbstractConfigurationTestCase;
classConfigurationTestextendsAbstractConfigurationTestCase
{
protectedfunctiongetConfiguration()
{
returnnewConfiguration();
}
}
Desired structure in config.yml
dpc_tutorial:
#hostshouldbearequiredkey
host:localhost
A required value: host
Test first
/**
*@test
*/
publicfunctionthe_host_key_is_required()
{
$this->assertConfigurationIsInvalid(
array(
array()
),
'host'
);
}
If we provide no values at all, we expect an exception
containing "host".
See it fail
bin/phpunit-capp
Make the test pass
$rootNode
->children()
->scalarNode('host')
->isRequired()
->end()
->end();
Trial and error
You're done when the test passes!
Repeated configuration values
Desired structure in config.yml
dpc_tutorial:
servers:
a:
host:server-a.nobacksoffice.nl
port:2730
b:
host:server-b.nobacksoffice.nl
port:2730
...
hostand portare required keys for each server
configuration
Test first
/**
*@test
*/
publicfunctionhost_is_required_for_each_server()
{
$this->assertConfigurationIsInvalid(
array(
array(
'servers'=>array(
'a'=>array()
)
)
),
'host'
);
}
Run the tests
bin/phpunit-capp
Write the code
$rootNode
->children()
->arrayNode('servers')
->useAttributeAsKey('name')
->prototype('array')
->children()
->scalarNode('host')
->isRequired()
->end()
Run the tests
Test first
Repeat these steps for port
Make sure your test first fails
Then you add some code
Then the test should pass
Merging config values
$this->assertConfigurationIsInvalid(
array(
array(
...//e.g.valuesfromconfig.yml
),
array(
...//e.g.valuesfromconfig_dev.yml
)
),
'host'
);
Disable merging
Test first
/**
*@test
*/
publicfunctionserver_configurations_are_not_merged()
{
$this->assertProcessedConfigurationEquals(
array(
array(
'servers'=>array(
'a'=>array('host'=>'host-a','port'=>1)
)
),
array(
'servers'=>array(
'b'=>array('host'=>'host-b','port'=>2)
)
)
),
array(
'servers'=>array(
'b'=>array('host'=>'host-b','port'=>2)
)
)
);
}
Add some code
$rootNode
->children()
->arrayNode('servers')
->useAttributeAsKey('name')//don'treindexthearray
->prototype('array')//means:repeatable
->children()
->scalarNode('host')->end()
->scalarNode('port')->end()
->end()
->end()
->end()
->end();
Run the tests
bin/phpunit-capp
Disable deep merging
Values from different configuration sources should not be
merged.
$rootNode
->children()
->arrayNode('servers')
->performNoDeepMerging()
...
->end()
->end();
Advantages of TDD for
Configurationclasses
We gradually approach our goal.
We immediately get feedback on what's wrong.
We can test different configuration values without
changing config.ymlmanually.
We can make sure the user gets very specific error
messages about wrong configuration values.
Learn more about all the options by reading the
.
offical
documentation of the Config component
Testing Extension
classes
dpc_tutorial:
servers:
a:
host:localhost
port:2730
Should give us a dpc_tutorial.a_serverservice with
hostand portas constructor arguments.
Create a test class for your extension
Directory: Tests/DependencyInjection
Class name: [NameOfTheExtension]Test
Class should extend AbstractExtensionTestCase
Implement getContainerExtensions(): return an
instance of your extension class
namespaceDpcBundleTutorialBundleTestsDependencyInjection;
useDpcBundleTutorialBundleDependencyInjectionDpcTutorialExtension;
useMatthiasSymfonyDependencyInjectionTestPhpUnitAbstractExtensionTestCase;
classDpcTutorialExtensionTestextendsAbstractExtensionTestCase
{
protectedfunctiongetContainerExtensions()
{
returnarray(
newDpcTutorialExtension()
);
}
}
Test first
/**
*@test
*/
publicfunctionit_creates_service_definitions_for_each_server()
{
$this->load(
array(
'servers'=>array(
'a'=>array('host'=>'host-a','port'=>123),
'b'=>array('host'=>'host-b','port'=>234)
)
)
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.a_server',0,'host-a'
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.a_server',1,123
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.b_server',0,'host-b'
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.b_server',1,234
);
}
See it fail
Write the code
useSymfonyComponentDependencyInjectionDefinition;
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=newConfiguration();
$config=$this->processConfiguration($configuration,$configs);
foreach($config['servers']as$name=>$serverConfig){
$serverDefinition=newDefinition();
$serverDefinition->setArguments(
array(
$serverConfig['host'],
$serverConfig['port'],
)
);
$container->setDefinition(
'dpc_tutorial.'.$name.'_server',
$serverDefinition
);
}
}
See it pass
Refactor!
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=newConfiguration();
$config=$this->processConfiguration($configuration,$configs);
$this->configureServers($container,$config['servers']);
}
privatefunctionconfigureServers(ContainerBuilder$container,array$servers)
{
foreach($serversas$name=>$server){
$this->configureServer($container,$name,$server['host'],$server['port']);
}
}
privatefunctionconfigureServer(ContainerBuilder$container,$name,$host,$port)
{
$serverDefinition=newDefinition(null,array($host,$port));
$container->setDefinition(
'dpc_tutorial.'.$name.'_server',
$serverDefinition
);
}
Shortcuts versus the Real deal
The base class provides some useful shortcuts
To get the most out of testing your extension:
Read all about classes like Definitionin the official
documentation
Patterns of Dependency Injection
A Bundle
called Bandle
I thought a bundle is just a class that
implements BundleInterface...
Why the suffix is
necessary
abstractclassBundleextendsContainerAwareimplementsBundleInterface
{
publicfunctiongetContainerExtension()
{
...
$basename=preg_replace('/Bundle$/','',$this->getName());
$class=$this->getNamespace()
.'DependencyInjection'
.$basename
.'Extension';
if(class_exists($class)){
$extension=new$class();
...
}
...
}
}
Line 6: '/Bundle$/'
But: no need to guess, you
already know which class
it is, right?
Override the
getContainerExtension()of your
bundle class
Then make it return an instance of your extension class.
useDpcBundleTutorialBundleDependencyInjectionDpcTutorialExtension;
classDpcTutorialBundleextendsBundle
{
publicfunctiongetContainerExtension()
{
returnnewDpcTutorialExtension();
}
}
Now the extension doesn't need to be in the
DependencyInjectiondirectory anymore!
It still needs to have the Extensionsuffix though...
Open the Extensionclass (from the
HttpKernelcomponent)
Take a look at the getAlias()method.
abstractclassExtensionimplementsExtensionInterface,ConfigurationExtensionInterface
{
publicfunctiongetAlias()
{
$className=get_class($this);
if(substr($className,-9)!='Extension'){
thrownewBadMethodCallException(
'Thisextensiondoesnotfollowthenamingconvention;'
.'youmustoverwritethegetAlias()method.'
);
}
$classBaseName=substr(strrchr($className,''),1,-9);
returnContainer::underscore($classBaseName);
}
}
The alias is used to find out which configuration belongs to
which bundle:
#inconfig.yml
dpc_tutorial:
...
By convention it's the lowercase underscored bundle name.
But what happens when I
rename the bundle?
The alias changes too, which means configuration in
config.ymlwon't be recognized anymore.
Also:
The extension needs to be renamed too, because of the
naming conventions...
DpcTutorialBundle,DpcTutorialExtension,dpc_tutorial
NobackTestBundle,NobackTestExtension,noback_test
So: open your extension class
Override the getAlias()method.
Make it return the alias of your extension (a string).
E.g. DpcTutorialBundle::getAlias()returns
dpc_tutorial.
classDpcTutorialExtensionextendsExtension
{
publicfunctiongetAlias()
{
return'dpc_tutorial';
}
}
But now we have some
duplication of information
The alias is also mentioned inside the Configuration
class.
classConfigurationimplementsConfigurationInterface
{
publicfunctiongetConfigTreeBuilder()
{
$treeBuilder=newTreeBuilder();
$rootNode=$treeBuilder->root('dpc_tutorial');
...
return$treeBuilder;
}
}
Modify extension and configuration
How can we make sure that the name of the root node in
the configuration class is the same as the alias returned by
getAlias()?
classConfigurationimplementsConfigurationInterface
{
private$alias;
publicfunction__construct($alias)
{
$this->alias=$alias;
}
publicfunctiongetConfigTreeBuilder()
{
$treeBuilder=newTreeBuilder();
$rootNode=$treeBuilder->root($this->alias);
...
}
}
$configuration=newConfiguration($this->getAlias());
This introduces a bug
Run app/console config:dump-reference
[extension-alias]
Open the Extensionclass
Take the one from the DependencyInjection
component.
publicfunctiongetConfiguration(array$config,ContainerBuilder$container)
{
$reflected=newReflectionClass($this);
$namespace=$reflected->getNamespaceName();
$class=$namespace.'Configuration';
if(class_exists($class)){
$r=newReflectionClass($class);
$container->addResource(newFileResource($r->getFileName()));
if(!method_exists($class,'__construct')){
$configuration=new$class();
return$configuration;
}
}
}
Our Configurationclass has a constructor...
Override getConfiguration()in
your extension
Also: make sure only one instance of Configurationis
created in the extension class.
classDpcTutorialExtensionextendsExtension
{
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=$this->getConfiguration($configs,$container);
$config=$this->processConfiguration($configuration,$configs);
...
}
publicfunctiongetConfiguration(array$config,ContainerBuilder$container)
{
returnnewConfiguration($this->getAlias());
}
...
}
Now we are allowed to rename Configurationor put it
somewhere else entirely!
Some last improvement
Extend from ConfigurableExtension.
abstractclassConfigurableExtensionextendsExtension
{
finalpublicfunctionload(array$configs,ContainerBuilder$container)
{
$this->loadInternal(
$this->processConfiguration(
$this->getConfiguration($configs,$container),
$configs
),
$container
);
}
abstractprotectedfunctionloadInternal(array$mergedConfig,ContainerBuilder$conta
}
It will save you a call to processConfiguration().
classDpcTutorialExtensionextendsConfigurableExtension
{
publicfunctionloadInternal(array$mergedConfig,ContainerBuilder$container)
{
//$mergedConfighasalreadybeenprocessed
$loader=newXmlFileLoader($container,newFileLocator(__DIR__.'/../Resources/co
$loader->load('services.xml');
}
...
}
We introduced flexibility...
By hard-coding the alias
And by skipping all the magic stuff
Now we can
Change *Bundleinto *Bandle
Change *Extensioninto *Plugin
Change Configurationinto Complexity
If we want...
€ 15,00
I’m impressed. — Robert C. Martin
leanpub.com/principles-of-php-package-design/c/dpc2014
Feedback
joind.in/10849
Twitter
@matthiasnoback

Weitere ähnliche Inhalte

Was ist angesagt?

Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Ryan Weaver
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at PinterestPuppet
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet
 
Learning puppet chapter 2
Learning puppet chapter 2Learning puppet chapter 2
Learning puppet chapter 2Vishal Biyani
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
The road to Ember.js 2.0
The road to Ember.js 2.0The road to Ember.js 2.0
The road to Ember.js 2.0Codemotion
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with TwigRyan Weaver
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys AdminsPuppet
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Ryan Weaver
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveAcquia
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 

Was ist angesagt? (20)

Sf2 wtf
Sf2 wtfSf2 wtf
Sf2 wtf
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at Pinterest
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
 
Learning puppet chapter 2
Learning puppet chapter 2Learning puppet chapter 2
Learning puppet chapter 2
 
A dive into Symfony 4
A dive into Symfony 4A dive into Symfony 4
A dive into Symfony 4
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
The road to Ember.js 2.0
The road to Ember.js 2.0The road to Ember.js 2.0
The road to Ember.js 2.0
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys Admins
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal Perspective
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 

Andere mochten auch

How I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundleHow I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundlefogs24
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012D
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Ryan Weaver
 
Confoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to startConfoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to startQuentin Adam
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSocketsGonzalo Ayuso
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 

Andere mochten auch (20)

How I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundleHow I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundle
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
Amongst models
Amongst modelsAmongst models
Amongst models
 
Confoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to startConfoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to start
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 

Ähnlich wie High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014

The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaMatthias Noback
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slidesDavid Barreto
 
Building a p2 update site using Buckminster
Building a p2 update site using BuckminsterBuilding a p2 update site using Buckminster
Building a p2 update site using Buckminsterguest5e2b6b
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupDavid Barreto
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipseanshunjain
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
Android application architecture
Android application architectureAndroid application architecture
Android application architectureRomain Rochegude
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011YoungSu Son
 
Frankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGiFrankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGiToni Epple
 
High quality ap is with api platform
High quality ap is with api platformHigh quality ap is with api platform
High quality ap is with api platformNelson Kopliku
 
CS8251_QB_answers.pdf
CS8251_QB_answers.pdfCS8251_QB_answers.pdf
CS8251_QB_answers.pdfvino108206
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 

Ähnlich wie High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014 (20)

The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
 
Building a p2 update site using Buckminster
Building a p2 update site using BuckminsterBuilding a p2 update site using Buckminster
Building a p2 update site using Buckminster
 
Readme
ReadmeReadme
Readme
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Android application architecture
Android application architectureAndroid application architecture
Android application architecture
 
C++ development within OOo
C++ development within OOoC++ development within OOo
C++ development within OOo
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
 
React hooks
React hooksReact hooks
React hooks
 
LabDocumentation
LabDocumentationLabDocumentation
LabDocumentation
 
Frankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGiFrankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGi
 
High quality ap is with api platform
High quality ap is with api platformHigh quality ap is with api platform
High quality ap is with api platform
 
CS8251_QB_answers.pdf
CS8251_QB_answers.pdfCS8251_QB_answers.pdf
CS8251_QB_answers.pdf
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 

Mehr von Matthias Noback

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupMatthias Noback
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesMatthias Noback
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Matthias Noback
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP BarcelonaMatthias Noback
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsMatthias Noback
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...Matthias Noback
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adaptersMatthias Noback
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Matthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Matthias Noback
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2WebMatthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Matthias Noback
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and PatternsMatthias Noback
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous ServicesMatthias Noback
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Matthias Noback
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous servicesMatthias Noback
 

Mehr von Matthias Noback (20)

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetup
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: Queries
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP Barcelona
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adapters
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2Web
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous Services
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018
 
Designing for Autonomy
Designing for AutonomyDesigning for Autonomy
Designing for Autonomy
 
Docker workshop
Docker workshopDocker workshop
Docker workshop
 
Docker swarm workshop
Docker swarm workshopDocker swarm workshop
Docker swarm workshop
 
Docker compose workshop
Docker compose workshopDocker compose workshop
Docker compose workshop
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous services
 

Kürzlich hochgeladen

Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012rehmti665
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Excelmac1
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一Fs
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一Fs
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一Fs
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 

Kürzlich hochgeladen (20)

Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 

High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014