mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
DOCS Update requirements and error handling, fix typos and markdown rendering bugs
This commit is contained in:
parent
0b09a510f4
commit
ee0bd1a541
@ -29,44 +29,53 @@ Requiring assets from the template is restricted compared to the PHP API.
|
||||
It is common practice to include most Requirements either in the *init()*-method of your [controller](../controllers/), or
|
||||
as close to rendering as possible (e.g. in [FormField](api:SilverStripe\Forms\FormField)).
|
||||
|
||||
:::php
|
||||
```php
|
||||
<?php
|
||||
|
||||
class MyCustomController extends Controller {
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\View\Requirements;
|
||||
|
||||
public function init() {
|
||||
class MyCustomController extends Controller
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
Requirements::javascript("<my-module-dir>/javascript/some_file.js");
|
||||
Requirements::css("<my-module-dir>/css/some_file.css");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CSS Files
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::css($path, $media);
|
||||
```
|
||||
|
||||
If you're using the CSS method a second argument can be used. This argument defines the 'media' attribute of the
|
||||
`<link>` element, so you can define 'screen' or 'print' for example.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::css("<my-module-dir>/css/some_file.css", "screen,projection");
|
||||
```
|
||||
|
||||
### Javascript Files
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::javascript($path, $options);
|
||||
```
|
||||
|
||||
A variant on the inclusion of custom javascript is the inclusion of *templated* javascript. Here, you keep your
|
||||
JavaScript in a separate file and instead load, via search and replace, several PHP-generated variables into that code.
|
||||
|
||||
:::php
|
||||
$vars = array(
|
||||
```php
|
||||
$vars = [
|
||||
"MemberID" => Member::currentUserID(),
|
||||
);
|
||||
];
|
||||
|
||||
Requirements::javascriptTemplate("<my-module-dir>/javascript/some_file.js", $vars);
|
||||
```
|
||||
|
||||
In this example, `some_file.js` is expected to contain a replaceable variable expressed as `MemberID`.
|
||||
|
||||
@ -75,24 +84,26 @@ that your included files provide these scripts. This will ensure that subsequent
|
||||
Requirement calls that rely on those included scripts will not double include those
|
||||
files.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::javascript('<my-module-dir>/javascript/dist/bundle.js', ['provides' => [
|
||||
'<my-module-dir>/javascript/jquery.js'
|
||||
'<my-module-dir>/javascript/src/main.js',
|
||||
'<my-module-dir>/javascript/src/functions.js'
|
||||
]]);
|
||||
Requirements::javascript('<my-module-dir>/javascript/jquery.js'); // Will will skip this file
|
||||
```
|
||||
|
||||
You can also use the second argumet to add the 'async' and/or 'defer attributes to the script tag generated:
|
||||
You can also use the second argument to add the 'async' and/or 'defer attributes to the script tag generated:
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::javascript(
|
||||
"<my-module-dir>/javascript/some_file.js",
|
||||
array(
|
||||
[
|
||||
"async" => true,
|
||||
"defer" => true,
|
||||
)
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
### Custom Inline CSS or Javascript
|
||||
|
||||
@ -101,7 +112,7 @@ of 'configuration' from the database in a raw format. You'll need to use the `h
|
||||
this is generally speaking the best way to do these things - it clearly marks the copy as belonging to a different
|
||||
language.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::customScript(<<<JS
|
||||
alert("hi there");
|
||||
JS
|
||||
@ -113,20 +124,22 @@ language.
|
||||
}
|
||||
CSS
|
||||
);
|
||||
```
|
||||
|
||||
## Combining Files
|
||||
|
||||
You can concatenate several CSS or javascript files into a single dynamically generated file. This increases performance
|
||||
by reducing HTTP requests.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::combine_files(
|
||||
'foobar.js',
|
||||
array(
|
||||
[
|
||||
'<my-module-dir>/javascript/foo.js',
|
||||
'<my-module-dir>/javascript/bar.js',
|
||||
)
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
<div class="alert" markdown='1'>
|
||||
To make debugging easier in your local environment, combined files is disabled when running your application in `dev`
|
||||
@ -165,7 +178,7 @@ is not appropriate. Normally a single backend is used for all site assets, so a
|
||||
replaced. For instance, the below will set a new set of dependencies to write to `mysite/javascript/combined`
|
||||
|
||||
|
||||
:::yaml
|
||||
```yaml
|
||||
---
|
||||
Name: myrequirements
|
||||
---
|
||||
@ -195,6 +208,7 @@ replaced. For instance, the below will set a new set of dependencies to write to
|
||||
SilverStripe\View\Requirements_Backend:
|
||||
properties:
|
||||
AssetHandler: '%$SilverStripe\Assets\Storage\GeneratedAssetHandler.custom-generated-assets'
|
||||
```
|
||||
|
||||
In the above configuration, automatic expiry of generated files has been disabled, and it is necessary for
|
||||
the developer to maintain these files manually. This may be useful in environments where assets must
|
||||
@ -215,10 +229,10 @@ the third paramter of the `combine_files` function:
|
||||
$loader = SilverStripe\View\ThemeResourceLoader::inst();
|
||||
$themes = SilverStripe\View\SSViewer::get_themes();
|
||||
|
||||
$printStylesheets = array(
|
||||
$printStylesheets = [
|
||||
$loader->findThemedCSS('print_HomePage.css', $themes),
|
||||
$loader->findThemedCSS('print_Page.css', $themes)
|
||||
);
|
||||
];
|
||||
|
||||
SilverStripe\View\Requirements::combine_files('print.css', $printStylesheets, 'print');
|
||||
```
|
||||
@ -240,12 +254,12 @@ You can also add the 'async' and/or 'defer' attributes to combined Javascript fi
|
||||
$loader = SilverStripe\View\ThemeResourceLoader::inst();
|
||||
$themes = SilverStripe\View\SSViewer::get_themes();
|
||||
|
||||
$scripts = array(
|
||||
$scripts = [
|
||||
$loader->findThemedJavascript('some_script.js', $themes),
|
||||
$loader->findThemedJavascript('some_other_script.js', $themes)
|
||||
);
|
||||
];
|
||||
|
||||
SilverStripe\View\Requirements::combine_files('scripts.js', $scripts, array('async' => true, 'defer' => true));
|
||||
SilverStripe\View\Requirements::combine_files('scripts.js', $scripts, ['async' => true, 'defer' => true]);
|
||||
```
|
||||
|
||||
### Minification of CSS and JS files
|
||||
@ -294,13 +308,15 @@ tools to do this for you, e.g. [Webpack](https://webpack.github.io/), [Gulp](htt
|
||||
|
||||
## Clearing assets
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::clear();
|
||||
```
|
||||
|
||||
Clears all defined requirements. You can also clear specific requirements.
|
||||
|
||||
:::php
|
||||
Requirements::clear(THIRDPARTY_DIR.'/prototype.js');
|
||||
```php
|
||||
Requirements::clear('modulename/javascript/some-lib.js');
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
Depending on where you call this command, a Requirement might be *re-included* afterwards.
|
||||
@ -315,8 +331,9 @@ included requirements, and ones included after the `block()` call.
|
||||
One common example is to block the core `jquery.js` added by various form fields and core controllers, and use a newer
|
||||
version in a custom location. This assumes you have tested your application with the newer version.
|
||||
|
||||
:::php
|
||||
Requirements::block(ADMIN_THIRDPARTY_DIR . '/jquery/jquery.js');
|
||||
```php
|
||||
Requirements::block('silverstripe-admin/thirdparty/jquery/jquery.js');
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
The CMS also uses the `Requirements` system, and its operation can be affected by `block()` calls. Avoid this by
|
||||
@ -338,8 +355,9 @@ careful when messing with the order of requirements.
|
||||
By default, SilverStripe includes all Javascript files at the bottom of the page body, unless there's another script
|
||||
already loaded, then, it's inserted before the first `<script>` tag. If this causes problems, it can be configured.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::set_force_js_to_bottom(true);
|
||||
```
|
||||
|
||||
`Requirements.force_js_to_bottom`, will force SilverStripe to write the Javascript to the bottom of the page body, even
|
||||
if there is an earlier script tag.
|
||||
@ -347,8 +365,9 @@ if there is an earlier script tag.
|
||||
If the Javascript files are preferred to be placed in the `<head>` tag rather than in the `<body>` tag,
|
||||
`Requirements.write_js_to_body` should be set to false.
|
||||
|
||||
:::php
|
||||
```php
|
||||
Requirements::set_write_js_to_body(false);
|
||||
```
|
||||
|
||||
|
||||
## API Documentation
|
||||
|
@ -13,9 +13,10 @@ warning of a potential issue to handle.
|
||||
For informational and debug logs, you can use the Logger directly. The Logger is a PSR-3 compatible LoggerInterface and
|
||||
can be accessed via the `Injector`:
|
||||
|
||||
:::php
|
||||
```php
|
||||
Injector::inst()->get(LoggerInterface::class)->info('User has logged in: ID #' . Member::currentUserID());
|
||||
Injector::inst()->get(LoggerInterface::class)->debug('Query executed: ' . $sql);
|
||||
```
|
||||
|
||||
Although you can raise more important levels of alerts in this way, we recommend using PHP's native error systems for
|
||||
these instead.
|
||||
@ -23,28 +24,32 @@ these instead.
|
||||
For notice-level and warning-level issues, you should use [user_error](http://www.php.net/user_error) to throw errors
|
||||
where appropriate. These will not halt execution but will send a message to the
|
||||
|
||||
:::php
|
||||
function delete() {
|
||||
```php
|
||||
public function delete()
|
||||
{
|
||||
if ($this->alreadyDelete) {
|
||||
user_error("Delete called on already deleted object", E_USER_NOTICE);
|
||||
return;
|
||||
}
|
||||
...
|
||||
// ...
|
||||
}
|
||||
|
||||
function getRelatedObject() {
|
||||
public function getRelatedObject()
|
||||
{
|
||||
if (!$this->RelatedObjectID) {
|
||||
user_error("Can't find a related object", E_USER_WARNING);
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
...
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
For errors that should halt execution, you should use Exceptions. Normally, Exceptions will halt the flow of executuion,
|
||||
but they can be caught with a try/catch clause.
|
||||
|
||||
:::php
|
||||
```php
|
||||
throw new \LogicException("Query failed: " . $sql);
|
||||
```
|
||||
|
||||
### Accessing the logger via dependency injection.
|
||||
|
||||
@ -53,22 +58,23 @@ it also means that you're coupling your code to global state, which is a bad des
|
||||
approach is to use depedency injection to pass the logger in for you. The [Injector](../extending/Injector)
|
||||
can help with this. The most straightforward is to specify a `dependencies` config setting, like this:
|
||||
|
||||
:::php
|
||||
class MyController {
|
||||
|
||||
private static $dependencies = array(
|
||||
```php
|
||||
class MyController extends Controller
|
||||
{
|
||||
private static $dependencies = [
|
||||
'logger' => '%$Psr\Log\LoggerInterface',
|
||||
);
|
||||
];
|
||||
|
||||
// This will be set automatically, as long as MyController is instantiated via Injector
|
||||
public $logger;
|
||||
|
||||
function init() {
|
||||
protected function init()
|
||||
{
|
||||
$this->logger->debug("MyController::init() called");
|
||||
parent::init();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
In other contexts, such as testing or batch processing, logger can be set to a different value by the code calling
|
||||
MyController.
|
||||
@ -94,6 +100,7 @@ for you to try.
|
||||
|
||||
To send emails, you can use Monolog's [NativeMailerHandler](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/NativeMailerHandler.php#L74), like this:
|
||||
|
||||
```yaml
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
Psr\Log\LoggerInterface:
|
||||
calls:
|
||||
@ -108,6 +115,7 @@ To send emails, you can use Monolog's [NativeMailerHandler](https://github.com/S
|
||||
properties:
|
||||
ContentType: text/html
|
||||
Formatter: %$SilverStripe\Logging\DetailedErrorFormatter
|
||||
```
|
||||
|
||||
The first section 4 lines passes a new handler to `Logger::pushHandler()` from the named service `MailHandler`. The
|
||||
next 10 lines define what the service is.
|
||||
@ -119,6 +127,7 @@ The calls key, `MailHandler`, can be anything you like: its main purpose is to l
|
||||
|
||||
To log to a file, you can use Monolog's [StreamHandler](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/StreamHandler.php#L74), like this:
|
||||
|
||||
```yaml
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
Psr\Log\LoggerInterface:
|
||||
calls:
|
||||
@ -128,6 +137,7 @@ To log to a file, you can use Monolog's [StreamHandler](https://github.com/Selda
|
||||
constructor:
|
||||
- "../silverstripe.log"
|
||||
- "info"
|
||||
```
|
||||
|
||||
The log file will be relative to the framework/ path, so "../silverstripe.log" will create a file in your project root.
|
||||
|
||||
@ -136,10 +146,12 @@ The log file will be relative to the framework/ path, so "../silverstripe.log" w
|
||||
You can disable a handler by removing its pushHandlers call from the calls option of the Logger service definition.
|
||||
The handler key of the default handler is `DisplayErrorHandler`, so you can disable it like this:
|
||||
|
||||
```yaml
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
Psr\Log\LoggerInterface:
|
||||
calls:
|
||||
DisplayErrorHandler: %%remove%%
|
||||
```
|
||||
|
||||
### Setting a different configuration for dev
|
||||
|
||||
@ -147,6 +159,7 @@ In order to set different logging configuration on different environment types,
|
||||
configuration features that the config system proviers. For example, here we have different configuration for dev and
|
||||
non-dev.
|
||||
|
||||
```yaml
|
||||
---
|
||||
Name: dev-errors
|
||||
Only:
|
||||
@ -173,7 +186,7 @@ non-dev.
|
||||
calls:
|
||||
pushFileLogHandler: [ pushHandler, [ %$LogFileHandler ]]
|
||||
pushDisplayErrorHandler: [ pushHandler, [ %$DisplayErrorHandler ]]
|
||||
LogFileHander:
|
||||
LogFileHandler:
|
||||
class: Monolog\Handler\StreamHandler
|
||||
constructor:
|
||||
- "../silverstripe.log"
|
||||
@ -192,6 +205,7 @@ non-dev.
|
||||
properties:
|
||||
Title: "There has been an error"
|
||||
Body: "The website server has not been able to respond to your request"
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
In addition to SilverStripe-integrated logging, it is advisable to fall back to PHPs native logging functionality. A
|
||||
@ -199,22 +213,6 @@ script might terminate before it reaches the SilverStripe error handling, for ex
|
||||
sure `log_errors` and `error_log` in your PHP ini file are configured.
|
||||
</div>
|
||||
|
||||
## Email Logs
|
||||
|
||||
You can send both fatal errors and warnings in your code to a specified email-address.
|
||||
|
||||
**mysite/_config.php**
|
||||
|
||||
:::php
|
||||
if(!Director::isDev()) {
|
||||
// log errors and warnings
|
||||
SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors-warnings.log'), SS_Log::WARN, '<=');
|
||||
|
||||
// or just errors
|
||||
SS_Log::add_writer(new SS_LogEmailWriter('admin@domain.com'), SS_Log::ERR);
|
||||
}
|
||||
|
||||
|
||||
## Replacing default implementations
|
||||
|
||||
For most application, Monolog and its default error handler should be fine, as you can get a lot of flexibility simply
|
||||
@ -226,11 +224,13 @@ others.
|
||||
Monolog comes by default with SilverStripe, but you may use another PSR-3 compliant logger, if you wish. To do this,
|
||||
set the `Injector.Logger` configuration parameter, providing a new injector definition. For example:
|
||||
|
||||
```yaml
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
ErrorHandler:
|
||||
class: Logging\Logger
|
||||
constructor:
|
||||
- 'alternative-logger'
|
||||
```
|
||||
|
||||
If you do this, you will need to supply your own handlers, and the `Logger.handlers` configuration parameter will
|
||||
be ignored.
|
||||
@ -247,9 +247,11 @@ Core.php will call `start()` on this method, to start the error handler.
|
||||
This error handler is flexible enough to work with any PSR-3 logging implementation, but sometimes you will want to use
|
||||
another. To replace this, you should registered a new service, `ErrorHandlerLoader`. For example:
|
||||
|
||||
```yaml
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
ErrorHandler:
|
||||
class: MyApp\CustomErrorHandlerLoader
|
||||
```
|
||||
|
||||
You should register something with a `start()` method.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user