Currently I'm having one global assets.yml file in my project, where I define my assets and I use them throughout the whole application. I have several bundles and all their assets are defined in this global assets.yml which is not clear and not good.
I'd like to define one assets.yml with corresponding assets per each bundle. They would lie in the bundle configuration.
I don't know how to make them accessible for the entire application. Should I use import somehow or does the framework load files (which name follow certain convention)? I'd appreciate hints how can I achieve the above.
edit: I should explain a bit more... In my config.yml I import assets.yml as a resource:
imports:
- { resource: assets.yml }
and the assets.yml looks like the following:
assetic:
use_controller: false
filters:
cssrewrite: ~
yui_js:
jar: %kernel.root_dir%/Resources/java/yui-compressor.jar
#apply_to: "\.js$"
yui_css:
jar: %kernel.root_dir%/Resources/java/yui-compressor.jar
#apply_to: "\.css$"
assets:
jquery:
inputs:
- '%kernel.root_dir%/Resources/public/js/jquery-1.8.0.js'
- '%kernel.root_dir%/Resources/public/js/jquery.sizes.js'
- '%kernel.root_dir%/Resources/public/js/jquery.form.js'
- '%kernel.root_dir%/Resources/public/js/jquery.validate.js'
- '%kernel.root_dir%/Resources/public/js/jquery.metadata.js'
[...]
Check the official documentation for How to expose a Semantic Configuration for a Bundle
Some refs:
When you create a bundle, you have two choices on how to handle configuration:
Normal Service Configuration (easy):
You can specify your services in a configuration file (e.g. services.yml) that lives in your bundle and then import it from your main application configuration. This is really easy, quick and totally effective. If you make use of parameters, then you still have the flexibility to customize your bundle from your application configuration. See "Importing Configuration with imports" for more details.
Exposing Semantic Configuration (advanced):
This is the way configuration is done with the core bundles (as described above). The basic idea is that, instead of having the user override individual parameters, you let the user configure just a few, specifically created options. As the bundle developer, you then parse through that configuration and load services inside an "Extension" class. With this method, you won't need to import any configuration resources from your main application configuration: the Extension class can handle all of this.
So the main idea is to create Extension class in each bundle and load bundle specific configuration files.
You can also check core symfony or third-party bundles for some examples.
Related
Can I reuse my Bundle created in Symfony in non-Symfony project, f.e. Zend? (Or I only can reuse Components?)
What about services from that Bundle?
A Symfony bundle can certainly be included in with other projects, via a composer.json & composer.lock file - it doesn't mean that there is any useful code to run within that bundle however.
If there is useful code as part of the bundle, then you can use it directly, but a Symfony Bundle is just a library that will usually include some Symfony-specific configuration.
Best practice for a bundle is to put any useful, common code, into a separate library (which could be used independently - such as what Symfony calls a 'Component'), and then enable that code (for example creating Symfony services, or configuration) with the bundle configuration.
There have been projects that are Symfony bundles, and also have the configurations for other frameworks as well, such as Silex, and also appropriate Laravel configurations within the same codebase.
In Symfony 3.0 (and I'm sure 2.X as well), if I want to make a custom constraint validator with a dependency, I have to register that validator as a service in the dependency injection container (which is described by default in project_directory/app/config/services.yml) using a special tag ( as described here).
This means that the Validator component must know where to look for the service container. This issue also comes up for the ControllerResolver. Since controllers can be registered as services, the ControllerResolver must know where the service container is.
How do the Symfony components know where to look for the service container, and how can I configure this? I ask because I want to build a custom framework using the Symfony components, which means I'll be making my own service container, and I'd like to be able to point the Validator and the ControllerResolver to that service container.
In Symfony Standard Edition, the container is initialised by the Kernel. Have a look at the AppKernel and its parent class.
The kernel loads a configuration file in the registerContainerConfiguration() method:
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
}
This code will load an environment specific configuration file (config_prod.yml, config_dev.yml etc). In a standard setup that file imports the main config.yml file.
The services.yml file is loaded with an import in config.yml:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
If you're thinking of building your own framework (which is a good learning experience), you'll need to read more code of existing frameworks first. Also, it's worth to read the excellent Create your own PHP framework.
This means that the Validator component must know where to look for the service container
This is scary. I see no connection between validation and the service container. I'd think of a better design.
P.S. Everyone should write their own framework once. The next step should be deleting it.
I'd like to build a mid-sized website which also includes a mobile website and an API.
As I already have some experience with Symfony I'd like to build the project on top of it.
However, I have no idea how to structure my project. Maybe there are some guidelines how to approach this problem?
Is it a good idea to build a each component as an individual Bundle? E.g. CoreBundle, APIBundle, WebsiteBundle and MobileWebsiteBundle, whereas CoreBundle would contain all Models and Validation and the other Bundles Controllers and Views?
Or is there a completely other way?
You don't need to put all of your code into the bundles. In fact the more code you put there, the more you're coupling it to the framework.
Consider extracting some of the non-Symfony related code into separate namespaces and treat bundles more like a glue between your PHP code and Symfony framework.
For example:
Acme
Bundles
ApiBundle
WebsiteBundle
Entity
Tools
Twig
If you decide to put entities outside of the bundle you'll have to configure a new mapping in the app/config/config.yml:
doctrine:
orm:
mappings:
Bossa:
type: annotation
is_bundle: false
dir: %kernel.root_dir%/../src/Acme/Entity
prefix: Acme\Entity\
alias: Acme
I am migrating from symfony1 to symfony2, I have hard time implementing propel behaviors. Where do I actually have the propel.ini in symfony2?
Well in sf1.4, it was inside root config directory. How about symfony2?
The Propel ORM Symfony2 page says this:
You can add a app/config/propel.ini file in your project to specify some configuration parameters. ... However, the recommended way to configure Propel is to rely on build properties.
You can define build properties by creating a propel.ini file in app/config like below, but you can also follow the Symfony2 convention by adding build properties in app/config/config.yml
So I believe you can come close to the Symfony1 behaviour by creating app/config/propel.ini, but the more idiomatic way is to use app/config/config.yml as that page illustrates.
Caveat: I haven't used Propel with Symfony2, so this answer is solely based on the manual.
I was wondering if I could define some variables in parameters.ini and use them in various yml files like validation, routing, etc?
Is this possible?
For any of Symfony2's YAML files that support imports, you can use the following syntax:
imports:
- { resource: parameters.yml }
Of course, this requires a bit of upgrading since parameters.yml is currently Symfony 2.1.x and 2.0.x still uses parameters.ini.
You would be better off passing variables around using service parameters. See this section of the documentation on the service container.
The configuration of validator and routing differs in its implementation.
DependencyInjection configuration files support the imports keyword.
Routing configuration files support the resources keyword.
Validator configuration files do not support import.
Translation configuration files do not support import.