NEW: Update docs to be compliant with Gatsby site (#9314)
* First cut * Temporarily disable composer.json for netlify build * POC * New recursive directory query, various refinements * Fix flexbox * new styled components plugin * Apply frontmatter delimiters * Mobile styles, animation * Search * Redesign, clean up * Nuke the cache, try again * fix file casing * Remove production env file * ID headers * Move app to new repo * Add frontmatter universally * Hide children changelogs * Add how to title * New callout tags * Revert inline code block change * Replace note callouts * Fix icons * Repalce images * Fix icon * Fix image links * Use proper SQL icon
@ -1,6 +1,13 @@
|
||||
---
|
||||
title: Server Requirements
|
||||
icon: server
|
||||
summary: What you will need to run Silverstripe CMS on a web server
|
||||
---
|
||||
|
||||
|
||||
# Requirements
|
||||
|
||||
SilverStripe CMS needs to be installed on a web server. Content authors and website administrators use their web browser
|
||||
Silverstripe CMS needs to be installed on a web server. Content authors and website administrators use their web browser
|
||||
to access a web-based GUI to do their day-to-day work. Website designers and developers require access to the files on
|
||||
the server to update templates, website logic, and perform upgrades or maintenance.
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Composer
|
||||
summary: What is composer and how to use it with Silverstripe CMS
|
||||
---
|
||||
|
||||
# Installing and Upgrading with Composer
|
||||
|
||||
Composer is a package management tool for PHP that lets you install and upgrade SilverStripe and its modules. Although installing Composer is one extra step, it will give you much more flexibility than just downloading the file from silverstripe.org. This is our recommended way of downloading SilverStripe and managing your code.
|
||||
@ -19,9 +24,9 @@ You can then run Composer commands by calling `composer`. For example:
|
||||
composer help
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
It is also possible to keep `composer.phar` out of your path, for example, to put it in your project root. Every command would then start with `php composer.phar` instead of `composer`. This is handy if need to keep your installation isolated from the rest of your computer's set-up, but we recommend putting composer into the path for most people.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
#### Updating composer
|
||||
|
||||
@ -99,9 +104,9 @@ composer search silverstripe
|
||||
|
||||
This will return a list of package names of the forum `vendor/package`. If you prefer, you can search for packages on [packagist.org](https://packagist.org/search/?q=silverstripe).
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
**Version constraints:** `master` is not a legal version string - it's a branch name. These are different things. The version string that would get you the branch is `dev-master`. The version string that would get you a numeric branch is a little different. The version string for the `4` branch is `4.x-dev`.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Updating dependencies
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Environment Management
|
||||
summary: How to configure your server environment for Silverstripe CMS
|
||||
---
|
||||
|
||||
# Environment management
|
||||
|
||||
As part of website development and hosting it is natural for our sites to be hosted on several different environments.
|
||||
@ -59,9 +64,9 @@ SilverStripe\Core\Injector\Injector:
|
||||
MyProperty: '`ENV_VAR_HERE`'
|
||||
```
|
||||
|
||||
<div class="info">
|
||||
[info]
|
||||
<p>Environment variables cannot be used outside of Injector config as of version 4.2.</p>
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
|
||||
## Including an extra `.env` file
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Directory Structure
|
||||
summary: An overview of what each directory contains in a Silverstripe CMS installation
|
||||
icon: sitemap
|
||||
---
|
||||
|
||||
# Directory Structure
|
||||
|
||||
## Introduction
|
||||
|
@ -1,155 +0,0 @@
|
||||
# Common Problems
|
||||
|
||||
From time to time, things will go wrong. Here's a few things to try when you're confused.
|
||||
|
||||
## The output shows only "Website Error"
|
||||
|
||||
This first and foremost means that your environment is set to "live mode" (see [environment-management]), which disallows
|
||||
detailed error messages for security reasons. You'll typically need to get your environment into "dev mode" to see more
|
||||
information.
|
||||
|
||||
If you can log-in to the CMS as an administrator, append `?isDev=1` to any URL to temporarily set your browsing session into
|
||||
"dev mode". If you can't log-in in the first place because of the error, please
|
||||
configure an `SS_ENVIRONMENT_TYPE` through [environment-management] (don't forget to remove it afterwards!).
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
On "live" environments, the `?isDev=1` solution is preferred, as it means that your other visitors don't see ugly
|
||||
(and potentially security sensitive) PHP errors as well.
|
||||
</div>
|
||||
|
||||
## mod_rewrite isn't working but it's installed (prior to SilverStripe 3.1.11)
|
||||
|
||||
Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler)
|
||||
(precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site.
|
||||
To fix this place the following within the `mod_rewrite` section of your .htaccess file:
|
||||
|
||||
```
|
||||
<IfModule mod_rewrite.c>
|
||||
# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex disabled
|
||||
</IfModule>
|
||||
# ------ #
|
||||
</IfModule>
|
||||
```
|
||||
|
||||
## My templates don't update on page refresh
|
||||
|
||||
Putting ?flush=1 on the end of any SilverStripe URL will clear out all cached content; this is a pretty common solution
|
||||
to a lot of development problems. Here are some specifics situations:
|
||||
|
||||
* You've created a new SS or PHP file
|
||||
* You've edited a nested template (one inserted with the `<% include %>` tag)
|
||||
* You've published a new copy of your site
|
||||
* You've upgraded your version of SilverStripe
|
||||
|
||||
## A SQL query fails with "Column not found" or "Table not found"
|
||||
|
||||
Whenever you change the model definitions in PHP (e.g. when adding a property to the [$db](api:SilverStripe\ORM\DataObject::$db) array,
|
||||
creating a new page type), SilverStripe will need to update the database. Visiting `http://localhost/dev/build` in
|
||||
your browser runs a script that will check the database schema and update it as necessary. Putting `?flush=1` on the
|
||||
end makes sure that nothing that's linked to the old database structure will be carried over. If things aren't saving,
|
||||
pages aren't loading, or other random things aren't working it's possible that the database hasn't been updated to
|
||||
handle the new code. Here are some specifics situations:
|
||||
|
||||
* You've created a new page type / other data object type
|
||||
* You've change the type of one of your database fields
|
||||
* You've published a new copy of your site
|
||||
* You've upgraded your version of SilverStripe
|
||||
|
||||
## My edited CMS content doesn't show on the website
|
||||
|
||||
If you've set up your site and it used to be working, but now it's suddenly totally broken, you may have forgotten to
|
||||
publish your draft content. Go to the CMS and use the "publish" button. You can visit `admin/pages/publishall` to publish
|
||||
every page on the site, if that's easier. Note that this will only work on smaller websites.
|
||||
|
||||
## I can see unparsed PHP output in my browser
|
||||
|
||||
Please make sure all code inside `*.php` files is wrapped in classes. Due to the way [ClassManifest](api:SilverStripe\Core\Manifest\ClassManifest)
|
||||
includes all files with this extension, any **procedural code will be executed on every call**. The most common error here
|
||||
is putting a test.php/phpinfo.php file in the document root. See [datamodel](/developer_guides/model/data_model_and_orm) and [controllers](/developer_guides/controllers)
|
||||
for ways how to structure your code.
|
||||
|
||||
Also, please check that you have PHP enabled on the webserver, and you're running PHP 5.1 or later.
|
||||
The web-based [SilverStripe installer](/getting_started/installation) can help you with this.
|
||||
|
||||
## I've got file permission problems during installation
|
||||
|
||||
The php installer needs to be able to write files during installation, which should be restricted again afterwards. It
|
||||
needs to create/have write-access to:
|
||||
|
||||
* The main installation directory (for creating .htaccess file and assets directory)
|
||||
* The `app/` folder (to create _config.php)
|
||||
* After the install, the assets directory is the only directory that needs write access.
|
||||
* Image thumbnails will not show in the CMS if permission is not given
|
||||
|
||||
If you are running on a server instance where users other than the webserver user will need
|
||||
read / write access to files in the assets folder, then you should do one of the below:
|
||||
|
||||
- Ensure that all server users that modify this file belong to the same group
|
||||
- Modify the permissions that SilverStripe uses to write to a more permissive setting (see below)
|
||||
|
||||
It may be necessary to manually set the original permissions, and owner user/group of your assets folder on
|
||||
initial deployment.
|
||||
|
||||
For more information on understanding and determining file permissions, please see
|
||||
[wikipedia](https://en.wikipedia.org/wiki/File_system_permissions#Traditional_Unix_permissions)
|
||||
on unix permissions.
|
||||
|
||||
### Modifying write permissions of files
|
||||
|
||||
By default all files and `.htaccess` are written with permission `0664`.
|
||||
You could enable other users to access these files with the below config.
|
||||
Note: Please adjust the values below to those appropriate for your server configuration.
|
||||
You may require `0666` for combined files generated during requests where they are cleared or refreshed only during a flush.
|
||||
|
||||
*app/_config/assetperms.yml*
|
||||
|
||||
```yaml
|
||||
---
|
||||
Name: myassetperms
|
||||
---
|
||||
SilverStripe\Assets\Flysystem\AssetAdapter:
|
||||
file_permissions:
|
||||
file:
|
||||
public: 0666 # Replace with your desired permission for files
|
||||
dir:
|
||||
public: 0777 # Replace with your desired permission for folders
|
||||
```
|
||||
|
||||
Note: `public` key applies to all files whether they are protected or public; This is a flag internal to
|
||||
Flysystem, and file protection is applied by SilverStripe on top of these permissions.
|
||||
|
||||
## I have whitespace before my HTML output, triggering quirks mode or preventing cookies from being set
|
||||
|
||||
SilverStripe only uses class declarations in PHP files, and doesn't output any content
|
||||
directly outside of these declarations. It's easy to accidentally add whitespace
|
||||
or any other characters before the `<?php` opening bracket at the start of the document,
|
||||
or after the `?>` closing braket at the end of the document.
|
||||
|
||||
Since we're dealing with hundreds of included files, identifying these mistakes manually can be tiresome.
|
||||
The best way to detect whitespace is to look through your version control system for any uncommitted changes.
|
||||
If that doesn't work out, here's a little script to run checks in all relevant PHP files.
|
||||
Save it as `check.php` into your webroot, and run it as `php check.php` (or open it in your browser).
|
||||
After using the script (and fixing errors afterwards), please remember to remove it again.
|
||||
|
||||
```php
|
||||
// Check for whitespace around PHP brackets which show in output,
|
||||
// and hence can break HTML rendering and HTTP operations.
|
||||
$path = dirname(__FILE__);
|
||||
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
|
||||
$matched = false;
|
||||
foreach($files as $name => $file){
|
||||
if($file->getExtension() != 'php') continue;
|
||||
if(preg_match('/thirdparty|vendor/',$file->getPathname())) continue;
|
||||
$content = file_get_contents($file->getPathname());
|
||||
if(preg_match('/^[[:blank:]]+<\?' . 'php/', $content)) {
|
||||
echo sprintf("%s: Space before opening bracket\n", $file->getPathname());
|
||||
$matched = true;
|
||||
}
|
||||
if(preg_match('/^\?' . '>\n?[[:blank:]]+/m', $content)) {
|
||||
echo sprintf("%s: Space after closing bracket\n", $file->getPathname());
|
||||
$matched = true;
|
||||
}
|
||||
}
|
||||
```
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Getting Started
|
||||
introduction: SilverStripe is a web application. This means that you will need to have a webserver and database. We will take you through the setup of the server environment as well the application itself.
|
||||
icon: rocket
|
||||
---
|
||||
|
||||
## Server Requirements
|
||||
|
||||
@ -45,6 +48,11 @@ Webserver setup is covered in
|
||||
[Lesson 4: Setting up a local dev environment](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1)
|
||||
|
||||
|
||||
|
||||
## Keep learning
|
||||
|
||||
[CHILDREN]
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you run into trouble, see [common-problems](common_problems) or
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Lessons
|
||||
introduction: The lessons take a step by step look at how to build a SilverStripe application.
|
||||
icon: graduation-cap
|
||||
---
|
||||
|
||||
* [How to set up a local development environment in SilverStripe](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1)
|
||||
* [Lesson 1: Creating your first project](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-project)
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Introduction to the Data Model and ORM
|
||||
summary: Introduction to creating and querying a database records through the ORM (object-relational model)
|
||||
icon: database
|
||||
---
|
||||
|
||||
# Introduction to the Data Model and ORM
|
||||
|
||||
@ -60,10 +63,10 @@ It **won't** do any of the following
|
||||
their table names don't match a SilverStripe data class.
|
||||
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
You need to be logged in as an administrator to perform this command, unless your site is in [dev mode](../debugging),
|
||||
or the command is run through [CLI](../cli).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
When rebuilding the database schema through the [ClassLoader](api:SilverStripe\Core\Manifest\ClassLoader) the following additional properties are
|
||||
automatically set on the `DataObject`.
|
||||
@ -121,9 +124,9 @@ Or, a better way is to use the `create` method.
|
||||
$player = Player::create();
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Using the `create()` method provides chainability, which can add elegance and brevity to your code, e.g. `Player::create()->write()`. More importantly, however, it will look up the class in the [Injector](../extending/injector) so that the class can be overriden by [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
Database columns and properties can be set as class properties on the object. The SilverStripe ORM handles the saving
|
||||
@ -179,9 +182,9 @@ $members = Player::get()->filter([
|
||||
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Provided `filter` values are automatically escaped and do not require any escaping.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Lazy Loading
|
||||
|
||||
@ -440,11 +443,11 @@ $teams = Team::get()->filter('Players.Sum(PointsScored):LessThan', 300);
|
||||
It is also possible to filter by a PHP callback, this will force the data model to fetch all records and loop them in
|
||||
PHP, thus `filter()` or `filterAny()` are to be preferred over `filterByCallback()`.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Because `filterByCallback()` has to run in PHP, it has a significant performance tradeoff, and should not be used on large recordsets.
|
||||
|
||||
`filterByCallback()` will always return an `ArrayList`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
The first parameter to the callback is the item, the second parameter is the list itself. The callback will run once
|
||||
for each record, if the callback returns true, this record will be added to the list of returned items.
|
||||
@ -552,9 +555,9 @@ offset, if not provided as an argument, will default to 0.
|
||||
$members = Member::get()->sort('Surname')->limit(10, 4);
|
||||
```
|
||||
|
||||
<div class="alert">
|
||||
[alert]
|
||||
Note that the `limit` argument order is different from a MySQL LIMIT clause.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Mapping classes to tables with DataObjectSchema
|
||||
|
||||
@ -653,10 +656,10 @@ $members = Member::get()
|
||||
->innerJoin("Group_Members", "\"Rel\".\"MemberID\" = \"Member\".\"ID\"", "Rel");
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Passing a *$join* statement to will filter results further by the JOINs performed against the foreign table. It will
|
||||
**not** return the additionally joined data.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Default Values
|
||||
|
||||
@ -675,10 +678,10 @@ class Player extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Note: Alternatively you can set defaults directly in the database-schema (rather than the object-model). See
|
||||
[Data Types and Casting](/developer_guides/model/data_types_and_casting) for details.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Subclasses
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Relations between Records
|
||||
summary: Relate models together using the ORM using has_one, has_many, and many_many.
|
||||
icon: link
|
||||
---
|
||||
|
||||
# Relations between Records
|
||||
|
||||
@ -115,19 +118,19 @@ class Fan extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
Note: The use of polymorphic relationships can affect query performance, especially
|
||||
on joins, and also increases the complexity of the database and necessary user code.
|
||||
They should be used sparingly, and only where additional complexity would otherwise
|
||||
be necessary. E.g. Additional parent classes for each respective relationship, or
|
||||
duplication of code.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## has_many
|
||||
|
||||
Defines 1-to-many joins. As you can see from the previous example, `$has_many` goes hand in hand with `$has_one`.
|
||||
|
||||
<div class="alert" markdown='1'>
|
||||
[alert]
|
||||
Please specify a $has_one-relationship on the related child-class as well, in order to have the necessary accessors
|
||||
available on both ends. To add a $has_one-relationship on core classes, yml config settings can be used:
|
||||
```yml
|
||||
@ -135,7 +138,7 @@ SilverStripe\Assets\Image:
|
||||
has_one:
|
||||
MyDataObject: MyDataObject
|
||||
```
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
```php
|
||||
use SilverStripe\ORM\DataObject;
|
||||
@ -246,10 +249,10 @@ Defines many-to-many joins, which uses a third table created between the two to
|
||||
There are two ways in which this can be declared, which are described below, depending on
|
||||
how the developer wishes to manage this join table.
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
Please specify a $belongs_many_many-relationship on the related class as well, in order
|
||||
to have the necessary accessors available on both ends.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
Much like the `has_one` relationship, `many_many` can be navigated through the `ORM` as well.
|
||||
The only difference being you will get an instance of [ManyManyList](api:SilverStripe\ORM\ManyManyList) or
|
||||
@ -511,10 +514,10 @@ If your object is versioned, cascade_deletes will also act as "cascade unpublish
|
||||
on a parent object will trigger unpublish on the child, similarly to how `owns` causes triggered publishing.
|
||||
See the [versioning docs](/developer_guides/model/versioning) for more information on ownership.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Declaring cascade_deletes implies delete permissions on the listed objects.
|
||||
Built-in controllers using delete operations check canDelete() on the owner, but not on the owned object.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Cascading duplications
|
||||
|
||||
@ -597,10 +600,10 @@ class Team extends DataObject
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Adding new records to a filtered `RelationList` like in the example above doesn't automatically set the filtered
|
||||
criteria on the added record.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Relations on Unsaved Objects
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Managing Lists
|
||||
summary: The SS_List interface allows you to iterate through and manipulate a list of objects.
|
||||
icon: list
|
||||
---
|
||||
|
||||
# Managing Lists
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Data Types, Overloading and Casting
|
||||
summary: Learn how how data is stored going in and coming out of the ORM and how to modify it.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Data Types and Casting
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Extending DataObjects
|
||||
summary: Modify the data model without using subclasses.
|
||||
---
|
||||
|
||||
# Extending DataObjects
|
||||
|
||||
@ -85,10 +87,10 @@ class Player extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Note: There are no separate methods for *onBeforeCreate* and *onBeforeUpdate*. Please check `$this->isInDb()` to toggle
|
||||
these two modes, as shown in the example above.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Related Lessons
|
||||
* [Working with data relationships - $has_many](https://www.silverstripe.org/learn/lessons/v4/working-with-data-relationships-has-many-1)
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: SearchFilter Modifiers
|
||||
summary: Use suffixes on your ORM queries.
|
||||
icon: search
|
||||
---
|
||||
|
||||
# SearchFilter Modifiers
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Model-Level Permissions
|
||||
summary: Reduce risk by securing models.
|
||||
icon: lock
|
||||
---
|
||||
|
||||
# Model-Level Permissions
|
||||
|
||||
@ -11,10 +14,10 @@ The API provides four methods for this purpose: `canEdit()`, `canCreate()`, `can
|
||||
Since they're PHP methods, they can contain arbitrary logic matching your own requirements. They can optionally receive
|
||||
a `$member` argument, and default to the currently logged in member (through `Security::getCurrentUser()`).
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
By default, all `DataObject` subclasses can only be edited, created and viewed by users with the 'ADMIN' permission
|
||||
code.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
```php
|
||||
use SilverStripe\Security\Permission;
|
||||
@ -44,11 +47,11 @@ class MyDataObject extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
These checks are not enforced on low-level ORM operations such as `write()` or `delete()`, but rather rely on being
|
||||
checked in the invoking code. The CMS default sections as well as custom interfaces like [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) or
|
||||
[GridField](api:SilverStripe\Forms\GridField\GridField) already enforce these permissions.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## API Documentation
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: SQL Queries
|
||||
summary: Write and modify direct database queries through SQLExpression subclasses.
|
||||
iconBrand: searchengin
|
||||
---
|
||||
|
||||
# SQLSelect
|
||||
|
||||
@ -46,10 +49,10 @@ various assumptions the ORM and code based on it have:
|
||||
We'll explain some ways to use *SELECT* with the full power of SQL,
|
||||
but still maintain a connection to the ORM where possible.
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Please read our [security topic](/developer_guides/security) to find out
|
||||
how to properly prepare user input and variables for use in queries
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Model Validation and Constraints
|
||||
summary: Validate your data at the model level
|
||||
icon: check-square
|
||||
---
|
||||
|
||||
# Validation and Constraints
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Versioning
|
||||
summary: Add versioning to your database content through the Versioned extension.
|
||||
---
|
||||
|
||||
# Versioning
|
||||
|
||||
@ -11,7 +13,7 @@ from published content shown to your website visitors.
|
||||
|
||||
Versioning in SilverStripe is handled through the [Versioned](api:SilverStripe\Versioned\Versioned) class. As a [DataExtension](api:SilverStripe\ORM\DataExtension) it is possible to be applied to any [DataObject](api:SilverStripe\ORM\DataObject) subclass. The extension class will automatically update read and write operations done via the ORM via the `augmentSQL` database hook.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
There are two complementary modules that improve content editor experience around "owned" nested objects (e.g. elemental blocks).
|
||||
Those are in experimental status right now, but we would appreciate any feedback and contributions.
|
||||
|
||||
@ -25,7 +27,7 @@ The second module extends CMS History UI adding control over nested objects.
|
||||
![](../../_images/snapshot-admin.png)
|
||||
|
||||
*Example screenshot from versioned-snapshot-admin*
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Understanding versioning concepts
|
||||
|
||||
@ -63,11 +65,11 @@ SilverStripe makes this possible by using the concept of _cascade publishing_. Y
|
||||
|
||||
A non-recursive publish operation is also available if you want to publish a new version of a object without cascade publishing all its children.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Declaring ownership implies publish permissions on owned objects.
|
||||
Built-in controllers using cascading publish operations check canPublish()
|
||||
on the owner, but not on the owned object.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
#### Ownership of unversioned object
|
||||
|
||||
@ -92,11 +94,11 @@ Changes to many objects can be grouped together using the [`ChangeSet`](api:Silv
|
||||
Records can be added to a changeset in the CMS by using the "Add to campaign" button
|
||||
that is available on the edit forms of all pages and files. Programmatically, this is done by creating a `SilverStripe\Versioned\ChangeSet` object and invoking its `addObject(DataObject $record)` method.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
DataObjects can be added to more than one ChangeSet.
|
||||
Most of the time, these objects contain changes.
|
||||
A ChangeSet can contain unchanged objects as well.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
#### Implicit vs. Explicit inclusions
|
||||
|
||||
@ -144,15 +146,15 @@ class VersionedModel extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
The extension is automatically applied to `SiteTree` class. For more information on extensions see
|
||||
[Extending](../extending) and the [Configuration](../configuration) documentation.
|
||||
</div>
|
||||
<a href="../extending">extending</a> and the <a href="../configuration">Configuration</a> documentation.
|
||||
[/notice]
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Versioning only works if you are adding the extension to the base class. That is, the first subclass
|
||||
of `DataObject`. Adding this extension to children of the base class will have unpredictable behaviour.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
|
||||
### Defining ownership between related versioned DataObjects
|
||||
@ -344,10 +346,10 @@ use SilverStripe\Versioned\Versioned;
|
||||
$historicalRecord = Versioned::get_version('MyRecord', <record-id>, <version-id>);
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The record is retrieved as a `DataObject`, but saving back modifications via `write()` will create a new version,
|
||||
rather than modifying the existing one.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
In order to get a list of all versions for a specific record, we need to generate specialized [Versioned_Version](api:SilverStripe\Versioned\Versioned_Version)
|
||||
objects, which expose the same database information as a `DataObject`, but also include information about when and how
|
||||
@ -512,10 +514,10 @@ Depending on whether staging is enabled, one or more new tables will be created
|
||||
is always created to track historic versions for your model. If staging is enabled this will also create a new
|
||||
`<class>_Live` table once you've rebuilt the database.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Note that the "Stage" naming has a special meaning here, it will leave the original table name unchanged, rather than
|
||||
adding a suffix.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
* `MyRecord` table: Contains staged data
|
||||
* `MyRecord_Live` table: Contains live data
|
||||
@ -682,22 +684,22 @@ SilverStripe\Control\Director:
|
||||
'my-objects/$ID': 'MyObjectController'
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The `choose_site_stage()` call only deals with setting the default stage, and doesn't check if the user is
|
||||
authenticated to view it. As with any other controller logic, please use `DataObject->canView()` to determine
|
||||
permissions, and avoid exposing unpublished content to your users.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Controlling permissions to versioned DataObjects
|
||||
|
||||
By default, `Versioned` will come out of the box with security extensions which restrict the visibility of objects in Draft (stage) or Archive viewing mode.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
As is standard practice, user code should always invoke `canView()` on any object before
|
||||
rendering it. DataLists do not filter on `canView()` automatically, so this must be
|
||||
done via user code. This be be achieved either by wrapping `<% if $canView %>` in
|
||||
done via user code. This be be achieved either by wrapping `<% if $canView %>;` in
|
||||
your template, or by implementing your visibility check in PHP.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
#### Version specific _can_ methods
|
||||
|
||||
@ -845,7 +847,7 @@ public function init()
|
||||
|
||||
SilverStripe will usually call these low level methods for you when you. However if you have specialised needs, you may call them directly.
|
||||
|
||||
To move a saved version from one stage to another, call [writeToStage(<stage>)](api:SilverStripe\Versioned\Versioned::writeToStage()) on the object. This is used internally to publish DataObjects.
|
||||
To move a saved version from one stage to another, call [writeToStage(stage)](api:SilverStripe\Versioned\Versioned::writeToStage()) on the object. This is used internally to publish DataObjects.
|
||||
|
||||
`copyVersionToStage($versionID, $stage)` allow you to restore a previous version to a specific stage. This is used internally when performing a rollback.
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Building Model and Search Interfaces around Scaffolding
|
||||
summary: A Model-driven approach to defining your application UI.
|
||||
icon: hammer
|
||||
---
|
||||
|
||||
# Scaffolding
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Indexes
|
||||
summary: Add Indexes to your Data Model to optimize database queries.
|
||||
icon: database
|
||||
---
|
||||
|
||||
# Indexes
|
||||
Indexes are a great way to improve performance in your application, especially as it grows. By adding indexes to your
|
||||
@ -69,10 +72,10 @@ class MyTestObject extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Please note that if you have previously used the removed `value` key to define an index's contents, SilverStripe will
|
||||
now throw an error. Use `columns` instead.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Complex/Composite Indexes
|
||||
For complex queries it may be necessary to define a complex or composite index on the supporting object. To create a
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Dynamic Default Fields
|
||||
summary: Learn how to add default values to your models
|
||||
---
|
||||
|
||||
# Default Values and Records
|
||||
|
||||
## Static Default Values
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Grouping DataObject sets
|
||||
summary: Learn how to split the results of a query into subgroups
|
||||
---
|
||||
|
||||
# Grouping lists of records
|
||||
|
||||
The [SS_List](api:SilverStripe\ORM\SS_List) class is designed to return a flat list of records.
|
||||
|
6
docs/en/02_Developer_Guides/00_Model/How_Tos/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Model and Databases
|
||||
|
||||
[CHILDREN]
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Model and Databases
|
||||
summary: Learn how SilverStripe manages database tables, ways to query your database and how to publish data.
|
||||
introduction: This guide will cover how to create and manipulate data within SilverStripe and how to use the ORM (Object Relational Model) to query data.
|
||||
icon: database
|
||||
---
|
||||
|
||||
In SilverStripe, application data will be represented by a [DataObject](api:SilverStripe\ORM\DataObject) class. A `DataObject` subclass defines the
|
||||
data columns, relationships and properties of a particular data record. For example, [Member](api:SilverStripe\Security\Member) is a `DataObject`
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Template Syntax
|
||||
summary: A look at the operations, variables and language controls you can use within templates.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Template Syntax
|
||||
|
||||
@ -40,10 +43,10 @@ An example of a SilverStripe template is below:
|
||||
</html>
|
||||
```
|
||||
|
||||
<div class="note">
|
||||
[note]
|
||||
Templates can be used for more than HTML output. You can use them to output your data as JSON, XML, CSV or any other
|
||||
text-based format.
|
||||
</div>
|
||||
[/note]
|
||||
|
||||
## Template file location
|
||||
|
||||
@ -91,10 +94,10 @@ If a variable returns a string, that string will be inserted into the template.
|
||||
the system will attempt to render the object through its `forTemplate()` method. If the `forTemplate()` method has not
|
||||
been defined, the system will return an error.
|
||||
|
||||
<div class="note" markdown="1">
|
||||
[note]
|
||||
For more detail around how variables are inserted and formatted into a template see
|
||||
[Formating, Modifying and Casting Variables](casting)
|
||||
</div>
|
||||
[/note]
|
||||
|
||||
Variables can come from your database fields, or custom methods you define on your objects.
|
||||
|
||||
@ -113,9 +116,9 @@ public function UsersIpAddress()
|
||||
<p>You are coming from $UsersIpAddress.</p>
|
||||
```
|
||||
|
||||
<div class="node" markdown="1">
|
||||
[note]
|
||||
Method names that begin with `get` will automatically be resolved when their prefix is excluded. For example, the above method call `$UsersIpAddress` would also invoke a method named `getUsersIpAddress()`.
|
||||
</div>
|
||||
[/note]
|
||||
|
||||
The variables that can be used in a template vary based on the object currently in [scope](#scope). Scope defines what
|
||||
object the methods get called on. For the standard `Page.ss` template the scope is the current [PageController](api:SilverStripe\CMS\Controllers\ContentController\PageController)
|
||||
@ -150,9 +153,9 @@ A conditional can also check for a value other than falsy.
|
||||
<% end_if %>
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
When inside template tags variables should have a '$' prefix, and literals should have quotes.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Conditionals can also provide the `else` case.
|
||||
|
||||
@ -280,13 +283,13 @@ collection.
|
||||
This snippet loops over the children of a page, and generates an unordered list showing the `Title` property from each
|
||||
page.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
$Title inside the loop refers to the Title property on each object that is looped over, not the current page like
|
||||
the reference of `$Title` outside the loop.
|
||||
|
||||
This demonstrates the concept of [Scope](#scope). When inside a <% loop %> the scope of the template has changed to the
|
||||
object that is being looped over.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### Altering the list
|
||||
|
||||
@ -370,10 +373,10 @@ iteration.
|
||||
</ul>
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
A common task is to paginate your lists. See the [Pagination](how_tos/pagination) how to for a tutorial on adding
|
||||
pagination.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
### Modulus and MultipleOf
|
||||
|
||||
@ -395,10 +398,10 @@ $MultipleOf(factor, offset)
|
||||
// returns <div class="column-3">, <div class="column-2">,
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
`$Modulus` is useful for floated grid CSS layouts. If you want 3 rows across, put $Modulus(3) as a class and add a
|
||||
`clear: both` to `.column-1`.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
$MultipleOf(value, offset) can also be utilized to build column and grid layouts. In this case we want to add a `<br>`
|
||||
after every 3rd item.
|
||||
@ -434,9 +437,9 @@ $Foo // returns "3"
|
||||
\$Foo // returns "$Foo"
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
For more information on formatting and casting variables see [Formating, Modifying and Casting Variables](casting)
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
## Scope
|
||||
|
||||
@ -473,7 +476,7 @@ When in a particular scope, `$Up` takes the scope back to the previous level.
|
||||
```
|
||||
|
||||
Given the following structure, it will output the text.
|
||||
|
||||
```
|
||||
My Page
|
||||
|
|
||||
+-+ Child 1
|
||||
@ -487,10 +490,10 @@ Given the following structure, it will output the text.
|
||||
Page 'Child 1' is a child of 'My Page'
|
||||
Page 'Grandchild 1' is a grandchild of 'My Page'
|
||||
Page 'Child 2' is a child of 'MyPage'
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
```
|
||||
[notice]
|
||||
Additional selectors implicitely change the scope so you need to put additional `$Up` to get what you expect.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
```ss
|
||||
<h1>Children of '$Title'</h1>
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Common Variables
|
||||
summary: Some of the common variables and methods your templates can use, including Menu, SiteConfig, and more.
|
||||
---
|
||||
|
||||
# Common Variables
|
||||
|
||||
@ -12,20 +14,20 @@ explained in more detail on the [syntax](syntax#scope) page. Many of the methods
|
||||
scope, and you can specify additional static methods to be available globally in templates by implementing the
|
||||
[TemplateGlobalProvider](api:SilverStripe\View\TemplateGlobalProvider) interface.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Want a quick way of knowing what scope you're in? Try putting `$ClassName` in your template. You should see a string
|
||||
such as `Page` of the object that's in scope. The methods you can call on that object then are any functions, database
|
||||
properties or relations on the `Page` class, `PageController` class as well as anything from their subclasses **or**
|
||||
extensions.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Outputting these variables is only the start, if you want to format or manipulate them before adding them to the template
|
||||
have a read of the [Formating, Modifying and Casting Variables](casting) documentation.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Some of the following only apply when you have the `CMS` module installed. If you're using the `Framework` alone, this
|
||||
functionality may not be included.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
## Base Tag
|
||||
@ -38,15 +40,15 @@ functionality may not be included.
|
||||
</head>
|
||||
```
|
||||
|
||||
The `<% base_tag %>` placeholder is replaced with the HTML base element. Relative links within a document (such as <img
|
||||
The `<% base_tag %>` placeholder is replaced with the HTML base element. Relative links within a document (such as `<img
|
||||
src="someimage.jpg" />) will become relative to the URI specified in the base tag. This ensures the browser knows where
|
||||
to locate your site’s images and css files.
|
||||
|
||||
It renders in the template as `<base href="http://www.yoursite.com" /><!--[if lte IE 6]></base><![endif]-->`
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
A `<% base_tag %>` is nearly always required or assumed by SilverStripe to exist.
|
||||
</div>
|
||||
[alert]
|
||||
A `<% base_tag %>;` is nearly always required or assumed by SilverStripe to exist.
|
||||
[/alert]
|
||||
|
||||
## CurrentMember
|
||||
|
||||
@ -71,9 +73,9 @@ Most objects within SilverStripe will respond to `$Title` (i.e they should have
|
||||
The CMS module in particular provides two fields to label a page: `Title` and `MenuTitle`. `Title` is the title
|
||||
displayed on the web page, while `MenuTitle` can be a shorter version suitable for size-constrained menus.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
If `MenuTitle` is left blank by the CMS author, it'll just default to the value in `Title`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Page Content
|
||||
|
||||
@ -84,21 +86,21 @@ $Content
|
||||
It returns the database content of the `Content` property. With the CMS Module, this is the value of the WYSIWYG editor
|
||||
but it is also the standard for any object that has a body of content to output.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
Please note that this database content can be `versioned`, meaning that draft content edited in the CMS can be different
|
||||
[info]
|
||||
Please note that this database content can be "versioned", meaning that draft content edited in the CMS can be different
|
||||
from published content shown to your website visitors. In templates, you don't need to worry about this distinction.
|
||||
|
||||
The `$Content` variable contains the published content by default,and only preview draft content if explicitly
|
||||
requested (e.g. by the "preview" feature in the CMS) (see the [versioning documentation](/../model/versioning) for
|
||||
more details).
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
### SiteConfig: Global settings
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
`SiteConfig` is a module that is bundled with the `CMS`. If you wish to include `SiteConfig` in your framework only
|
||||
web pages. You'll need to install it via `composer`.
|
||||
</div>
|
||||
[notice]
|
||||
`SiteConfig` is a module that is bundled with the CMS. If you wish to include `SiteConfig` in your framework only
|
||||
web pages. You'll need to install it via composer.
|
||||
[/notice]
|
||||
|
||||
```ss
|
||||
$SiteConfig.Title
|
||||
@ -117,9 +119,9 @@ The `$MetaTags` placeholder in a template returns a segment of HTML appropriate
|
||||
will set up title, keywords and description meta-tags, based on the CMS content and is editable in the 'Meta-data' tab
|
||||
on a per-page basis.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
If you don’t want to include the title tag use `$MetaTags(false)`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
By default `$MetaTags` renders:
|
||||
|
||||
@ -255,10 +257,10 @@ behavior based on the page type used:
|
||||
Will loop over all Children records of the current object context. Children are pages that sit under the current page in
|
||||
the `CMS` or a custom list of data. This originates in the `Versioned` extension's `getChildren` method.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
For doing your website navigation most likely you'll want to use `$Menu` since its independent of the page
|
||||
context.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### ChildrenOf
|
||||
|
||||
@ -295,9 +297,9 @@ preference, `AllChildren` does not filter by `ShowInMenus`.
|
||||
|
||||
`$Menu(1)` returns the top-level menu of the website. You can also create a sub-menu using `$Menu(2)`, and so forth.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Pages with the `ShowInMenus` property set to `false` will be filtered out.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Access to a specific Page
|
||||
|
||||
@ -367,11 +369,11 @@ of the `silverstripe/cms` module.
|
||||
<% end_if %>
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
To customise the markup that the `$Breadcrumbs` generates, copy `templates/BreadcrumbsTemplate.ss`
|
||||
from the `silverstripe/cms` module to
|
||||
`app/templates/BreadcrumbsTemplate.ss`, modify the newly copied template and flush your SilverStripe cache.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Forms
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Requirements
|
||||
summary: How to include and require other assets in your templates such as javascript and CSS files.
|
||||
iconBrand: js
|
||||
---
|
||||
|
||||
# Requirements
|
||||
|
||||
@ -85,9 +88,9 @@ When rendered in HTML code, these URLs will be rewritten to their matching path
|
||||
<% require javascript("<my-module-dir>/javascript/some_file.js") %>
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Requiring assets from the template is restricted compared to the PHP API.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## PHP Requirements API
|
||||
|
||||
@ -206,10 +209,10 @@ Requirements::combine_files(
|
||||
);
|
||||
```
|
||||
|
||||
<div class="alert" markdown='1'>
|
||||
[alert]
|
||||
To make debugging easier in your local environment, combined files is disabled when running your application in `dev`
|
||||
mode. You can re-enable dev combination by setting `Requirements_Backend.combine_in_dev` to true.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Configuring combined file storage
|
||||
|
||||
@ -305,10 +308,10 @@ SilverStripe\View\Requirements::combine_files('print.css', $printStylesheets, 'p
|
||||
By default, all requirements files are flushed (deleted) when ?flush querystring parameter is set.
|
||||
This can be disabled by setting the `Requirements.disable_flush_combined` config to `true`.
|
||||
|
||||
<div class="alert" markdown='1'>
|
||||
[alert]
|
||||
When combining CSS files, take care of relative urls, as these will not be re-written to match
|
||||
the destination location of the resulting combined CSS.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Combined JS Files
|
||||
|
||||
@ -366,10 +369,10 @@ SilverStripe\Core\Injector\Injector:
|
||||
Minifier: %$MyProject\MyMinifier
|
||||
```
|
||||
|
||||
<div class="alert" markdown='1'>
|
||||
[alert]
|
||||
While the framework does afford you the option of minification at runtime, we recommend using one of many frontend build
|
||||
tools to do this for you, e.g. [Webpack](https://webpack.github.io/), [Gulp](http://gulpjs.com/), or [Grunt](https://gruntjs.com/).
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
## Clearing assets
|
||||
@ -384,9 +387,9 @@ Clears all defined requirements. You can also clear specific requirements.
|
||||
Requirements::clear('modulename/javascript/some-lib.js');
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Depending on where you call this command, a Requirement might be *re-included* afterwards.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Blocking
|
||||
|
||||
@ -401,20 +404,20 @@ version in a custom location. This assumes you have tested your application with
|
||||
Requirements::block('silverstripe/admin:thirdparty/jquery/jquery.js');
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The CMS also uses the `Requirements` system, and its operation can be affected by `block()` calls. Avoid this by
|
||||
limiting the scope of your blocking operations, e.g. in `init()` of your controller.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Inclusion Order
|
||||
|
||||
Requirements acts like a stack, where everything is rendered sequentially in the order it was included. There is no way
|
||||
to change inclusion-order, other than using *Requirements::clear* and rebuilding the whole set of requirements.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Inclusion order is both relevant for CSS and Javascript files in terms of dependencies, inheritance and overlays - be
|
||||
careful when messing with the order of requirements.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Javascript placement
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Rendering data to a template
|
||||
summary: Call and render SilverStripe templates manually.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Rendering data to a template
|
||||
|
||||
@ -33,10 +36,10 @@ echo $arrayData->renderWith('Coach_Message');
|
||||
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Most classes in SilverStripe you want in your template extend `ViewableData` and allow you to call `renderWith`. This
|
||||
includes [Controller](api:SilverStripe\Control\Controller), [FormField](api:SilverStripe\Forms\FormField) and [DataObject](api:SilverStripe\ORM\DataObject) instances.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
```php
|
||||
$controller->renderWith(['MyController', 'MyBaseController']);
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Template Inheritance
|
||||
summary: Override and extend module and core markup templates from your application code.
|
||||
icon: sitemap
|
||||
---
|
||||
|
||||
# Template Inheritance
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Themes
|
||||
summary: What makes up a SilverStripe Theme. How to install one or write your own theme.
|
||||
icon: paint-brush
|
||||
---
|
||||
|
||||
# Themes
|
||||
|
||||
@ -24,10 +27,10 @@ composer require author/theme_name [version]
|
||||
|
||||
*Note:* `[version]` should be replaced with a version constraint if you know it, otherwise leave it blank to pull the latest version compatible with your project.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
As you've added new files to your SilverStripe installation, make sure you clear the SilverStripe cache by appending
|
||||
`?flush=1` to your website URL (e.g http://yoursite.com/?flush=1).
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Configuring themes
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Caching
|
||||
summary: Reduce rendering time with cached templates and understand the limitations of the ViewableData object caching.
|
||||
icon: rocket
|
||||
---
|
||||
|
||||
# Caching
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Translations
|
||||
summary: Definition of the syntax for writing i18n compatible templates.
|
||||
icon: globe
|
||||
---
|
||||
|
||||
# Translations
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Formatting, Modifying and Casting Variables
|
||||
summary: Information on casting, security, modifying data before it's displayed to the user and how to format data within the template.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Formatting and Casting
|
||||
|
||||
@ -34,10 +37,10 @@ $Content.FirstParagraph.NoHTML
|
||||
<!-- <div class="about-us"> -->
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
See the API documentation for [DBHtmlText](api:SilverStripe\ORM\FieldType\DBHtmlText), [FieldType](api:SilverStripe\ORM\FieldType), [DBText](api:SilverStripe\ORM\FieldType\DBText) for all the methods you can use to format
|
||||
your text instances. For other objects such as [DBDatetime](api:SilverStripe\ORM\FieldType\DBDatetime) objects see their respective API documentation pages.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## forTemplate
|
||||
|
||||
@ -92,10 +95,10 @@ class Page extends SiteTree
|
||||
When calling `$MyCustomMethod` SilverStripe now has the context that this method will contain HTML and escape the data
|
||||
accordingly.
|
||||
|
||||
<div class="note" markdown="1">
|
||||
[note]
|
||||
By default, all content without a type explicitly defined in a `$casting` array will be assumed to be `Text` content
|
||||
and HTML characters encoded.
|
||||
</div>
|
||||
[/note]
|
||||
|
||||
## Escaping
|
||||
|
||||
@ -103,9 +106,9 @@ Properties are usually auto-escaped in templates to ensure consistent representa
|
||||
displaying un-escaped ampersands in HTML. By default, values are escaped as `XML`, which is equivalent to `HTML` for
|
||||
this purpose.
|
||||
|
||||
<div class="note" markdown="1">
|
||||
[note]
|
||||
There's some exceptions to this rule, see the ["security" guide](../security).
|
||||
</div>
|
||||
[/note]
|
||||
|
||||
For every field used in templates, a casting helper will be applied. This will first check for any
|
||||
`casting` helper on your model specific to that field, and will fall back to the `default_cast` config
|
||||
@ -148,11 +151,11 @@ See [DBField](api:SilverStripe\ORM\FieldType\DBField) for the specific implement
|
||||
E.g. `<element>$Field.CDATA</element>` will ensure that the `<element>` body is safely escaped
|
||||
as a string.
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Note: Take care when using `.XML` on `HTMLText` fields, as this will result in double-encoded
|
||||
html. To ensure that the correct encoding is used for that field in a template, simply use
|
||||
`$Field` by itself to allow the casting helper to determine the best encoding itself.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Cast summary methods
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: How to Create a Navigation Menu
|
||||
summary: Build a multi-tiered navigation UI.
|
||||
---
|
||||
|
||||
# How to Create a Navigation Menu
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: How to Create a Paginated List
|
||||
summary: Break up the result of a database query into multiple pages
|
||||
---
|
||||
|
||||
# How to Create a Paginated List
|
||||
|
||||
@ -24,10 +27,10 @@ public function PaginatedPages()
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Note that the concept of "pages" used in pagination does not necessarily mean that we're dealing with `Page` classes,
|
||||
it's just a term to describe a sub-collection of the list.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
There are two ways to generate pagination controls: [PaginatedList::Pages()](api:SilverStripe\ORM\PaginatedList::Pages()) and
|
||||
[PaginatedList::PaginationSummary()](api:SilverStripe\ORM\PaginatedList::PaginationSummary()). In this example we will use `PaginationSummary()`.
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: Disable Anchor Rewriting
|
||||
summary: Get more control over how hash links are rendered.
|
||||
---
|
||||
|
||||
# Disable Anchor Rewriting
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Templates and Views
|
||||
|
||||
[CHILDREN]
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Templates and Views
|
||||
summary: This guide showcases the SilverStripe template engine and learn how to build your own themes.
|
||||
introduction: SilverStripe comes with it's own templating engine. This guide walks you through the features of the template engine, how to create custom templates and ways to customise your data output.
|
||||
icon: file-code
|
||||
---
|
||||
|
||||
Most of what will be public on your website comes from template files that are defined in SilverStripe. Either in the
|
||||
core framework, the modules or themes you install, and your own custom templates.
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Introduction to a Controller
|
||||
summary: A brief look at the definition of a Controller, creating actions and how to respond to requests.
|
||||
---
|
||||
|
||||
# Introduction to Controllers
|
||||
|
||||
@ -37,15 +39,15 @@ class TeamController extends Controller
|
||||
We need to define the URL that this controller can be accessed on. In our case, the `TeamsController` should be visible
|
||||
at http://yoursite.com/teams/ and the `players` custom action is at http://yoursite.com/team/players/.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
If you're using the `cms` module with and dealing with `Page` objects then for your custom `Page Type` controllers you
|
||||
would extend `ContentController` or `PageController`. You don't need to define the routes value as the `cms` handles
|
||||
routing.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Make sure that after you have modified the `routes.yml` file, that you clear your SilverStripe caches using `?flush=1`.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
**app/_config/routes.yml**
|
||||
|
||||
@ -66,9 +68,9 @@ For more information about creating custom routes, see the [Routing](routing) do
|
||||
Controllers respond by default to an `index` method. You don't need to define this method (as it's assumed) but you
|
||||
can override the `index()` response to provide custom data back to the [Template and Views](../templates).
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
It is standard in SilverStripe for your controller actions to be `lowercasewithnospaces`
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Action methods can return one of four main things:
|
||||
|
||||
|
@ -1,16 +1,18 @@
|
||||
---
|
||||
title: Routing
|
||||
summary: A more in depth look at how to map requests to particular controllers and actions.
|
||||
---
|
||||
|
||||
# Routing
|
||||
|
||||
Routing is the process of mapping URL's to [Controller](api:SilverStripe\Control\Controller) and actions. In the introduction we defined a new custom route
|
||||
for our `TeamController` mapping any `teams` URL to our `TeamController`
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
If you're using the `cms` module with and dealing with `Page` objects then for your custom `Page Type` controllers you
|
||||
would extend `ContentController` or `PageController`. You don't need to define the routes value as the `cms` handles
|
||||
routing.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
These routes by standard, go into a `routes.yml` file in your applications `_config` folder alongside your other
|
||||
[Configuration](../configuration) information.
|
||||
@ -31,9 +33,9 @@ SilverStripe\Control\Director:
|
||||
'': 'HomeController'
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
To understand the syntax for the `routes.yml` file better, read the [Configuration](../configuration) documentation.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Parameters
|
||||
|
||||
@ -47,9 +49,9 @@ It also contains 3 `parameters` or `params` for short. `$Action`, `$ID` and `$Na
|
||||
which will be filled when the user makes their request. Request parameters are available on the `HTTPRequest` object
|
||||
and able to be pulled out from a controller using `$this->getRequest()->param($name)`.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
All Controllers have access to `$this->getRequest()` for the request object and `$this->getResponse()` for the response.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Here is what those parameters would look like for certain requests
|
||||
|
||||
@ -103,9 +105,9 @@ echo $this->getRequest()->param('ID');
|
||||
The [RequestHandler](api:SilverStripe\Control\RequestHandler) class will parse all rules you specify against the following patterns. The most specific rule
|
||||
will be the one followed for the response.
|
||||
|
||||
<div class="alert">
|
||||
[alert]
|
||||
A rule must always start with alphabetical ([A-Za-z]) characters or a $Variable declaration
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
| Pattern | Description |
|
||||
| ----------- | --------------- |
|
||||
@ -143,13 +145,13 @@ start parsing variables and the appropriate controller action AFTER the `//`).
|
||||
|
||||
## URL Handlers
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
You **must** use the **$url_handlers** static array described here if your URL
|
||||
pattern does not use the Controller class's default pattern of
|
||||
`$Action//$ID/$OtherID`. If you fail to do so, and your pattern has more than
|
||||
2 parameters, your controller will throw the error "I can't handle sub-URLs of
|
||||
a *class name* object" with HTTP status 404.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
In the above example the URLs were configured using the [Director](api:SilverStripe\Control\Director) rules in the **routes.yml** file. Alternatively
|
||||
you can specify these in your Controller class via the **$url_handlers** static array. This array is processed by the
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Access Control
|
||||
summary: Define allowed behavior and add permission based checks to your Controllers.
|
||||
icon: user-lock
|
||||
---
|
||||
|
||||
# Access Control
|
||||
|
||||
@ -39,9 +42,9 @@ class MyController extends Controller
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info">
|
||||
[info]
|
||||
If the permission check fails, SilverStripe will return a `403` Forbidden HTTP status.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
An action named "index" is white listed by default, unless `allowed_actions` is defined as an empty array, or the action
|
||||
is specifically restricted.
|
||||
@ -130,9 +133,9 @@ class MyChildController extends MyController
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Access checks on parent classes need to be overwritten via the [Configuration API](../configuration).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Forms
|
||||
|
||||
@ -190,10 +193,10 @@ class MyController extends Controller
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
This is recommended as an addition for `$allowed_actions`, in order to handle more complex checks, rather than a
|
||||
replacement.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Controller Level Checks
|
||||
|
||||
@ -201,9 +204,9 @@ After checking for allowed_actions, each controller invokes its `init()` method,
|
||||
common state, If an `init()` method returns a `HTTPResponse` with either a 3xx or 4xx HTTP status code, it'll abort
|
||||
execution. This behavior can be used to implement permission checks.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
`init` is called for any possible action on the controller and before any specific method such as `index`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
```php
|
||||
use SilverStripe\Security\Permission;
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Redirection
|
||||
summary: Move users around your site using automatic redirection.
|
||||
icon: reply
|
||||
---
|
||||
|
||||
# Redirection
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: HTTP Middlewares
|
||||
summary: Create objects for modifying request and response objects across controllers.
|
||||
---
|
||||
|
||||
# HTTP Middlewares
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Built-in Middleware
|
||||
summary: Middleware components that come with SilverStripe Framework
|
||||
---
|
||||
|
||||
# Built-in Middleware
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Controllers
|
||||
summary: Controllers form the backbone of your SilverStripe application. They handle routing URLs to your templates.
|
||||
introduction: In this guide you will learn how to define a Controller class and how they fit into the SilverStripe response and request cycle.
|
||||
---
|
||||
|
||||
The [Controller](api:SilverStripe\Control\Controller) class handles the responsibility of delivering the correct outgoing [HTTPResponse](api:SilverStripe\Control\HTTPResponse) for a
|
||||
given incoming [HTTPRequest](api:SilverStripe\Control\HTTPRequest). A request is along the lines of a user requesting the homepage and contains
|
||||
|
@ -1,14 +1,17 @@
|
||||
---
|
||||
title: Introduction to Forms
|
||||
summary: An introduction to creating a Form instance and handling submissions.
|
||||
iconBrand: wpforms
|
||||
---
|
||||
|
||||
# Forms
|
||||
|
||||
The HTML `Form` is the most used way to interact with a user. SilverStripe provides classes to generate forms through
|
||||
the [Form](api:SilverStripe\Forms\Form) class, [FormField](api:SilverStripe\Forms\FormField) instances to capture data and submissions through [FormAction](api:SilverStripe\Forms\FormAction).
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
See the [Introduction to frontend forms](https://www.silverstripe.org/learn/lessons/v4/introduction-to-frontend-forms-1) lesson for a step by step process of creating a `Form`
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Creating a Form
|
||||
|
||||
@ -79,11 +82,11 @@ class PageController extends ContentController
|
||||
$HelloForm
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The examples above use `FormField::create()` instead of the `new` operator (`new FormField()`). These are functionally
|
||||
equivalent, but allows PHP to chain operations like `setTitle()` without assigning the field instance to a temporary
|
||||
variable.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
When constructing the `Form` instance (`new Form($controller, $name)`) both controller and name are required. The
|
||||
`$controller` and `$name` are used to allow SilverStripe to calculate the origin of the `Form object`. When a user
|
||||
@ -101,10 +104,10 @@ private static $allowed_actions = [
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Form actions (`doSayHello`), on the other hand, should _not_ be included in `$allowed_actions`; these are handled
|
||||
separately through [Form::httpSubmission()](api:SilverStripe\Forms\Form::httpSubmission()).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
## Adding FormFields
|
||||
@ -116,9 +119,9 @@ Some common examples are [TextField](api:SilverStripe\Forms\TextField) or [Dropd
|
||||
SilverStripe\Forms\TextField::create($name, $title, $value);
|
||||
```
|
||||
|
||||
<div class="info" markdown='1'>
|
||||
[info]
|
||||
A list of the common FormField subclasses is available on the [Common Subclasses](field_types/common_subclasses/) page.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
The fields are added to the [FieldList](api:SilverStripe\Forms\FieldList) `fields` property on the `Form` and can be modified at up to the point the
|
||||
`Form` is rendered.
|
||||
@ -170,20 +173,20 @@ Fields can be removed from the form.
|
||||
$form->getFields()->removeByName('Email');
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Forms can be tabbed (such as the CMS interface). In these cases, there are additional functions such as `addFieldToTab`
|
||||
and `removeFieldByTab` to ensure the fields are on the correct interface. See [Tabbed Forms](tabbed_forms) for more
|
||||
information on the CMS interface.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Modifying FormFields
|
||||
|
||||
Each [FormField](api:SilverStripe\Forms\FormField) subclass has a number of methods you can call on it to customise its' behavior or HTML markup. The
|
||||
default `FormField` object has several methods for doing common operations.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Most of the `set` operations will return the object back so methods can be chained.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
```php
|
||||
$field = new TextField(..);
|
||||
@ -270,10 +273,10 @@ with the particular button. In the previous example, clicking the 'Another Butto
|
||||
* The `Form` instance.
|
||||
* The `Controller` instance.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
If the `$action` method cannot be found on any of those or is marked as `private` or `protected`, an error will be
|
||||
thrown.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
The `$action` method takes two arguments:
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Form Validation
|
||||
summary: Validate form data through the server side validation API.
|
||||
icon: check-square
|
||||
---
|
||||
|
||||
# Form Validation
|
||||
|
||||
@ -57,11 +60,11 @@ class PageController extends ContentController
|
||||
In this example we will be required to input a value for `Name` and a valid email address for `Email` before the
|
||||
`doSubmitForm` method is called.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Each individual [FormField](api:SilverStripe\Forms\FormField) instance is responsible for validating the submitted content through the
|
||||
[FormField::validate()](api:SilverStripe\Forms\FormField::validate()) method. By default, this just checks the value exists. Fields like `EmailField` override
|
||||
`validate` to check for a specific format.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Subclasses of `FormField` can define their own version of `validate` to provide custom validation rules such as the
|
||||
above example with the `Email` validation. The `validate` method on `FormField` takes a single argument of the current
|
||||
@ -82,9 +85,9 @@ public function validate($validator)
|
||||
The `validate` method should return `true` if the value passes any validation and `false` if SilverStripe should trigger
|
||||
a validation error on the page. In addition a useful error message must be set on the given validator.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
You can also override the entire `Form` validation by subclassing `Form` and defining a `validate` method on the form.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Say we need a custom `FormField` which requires the user input a value in a `TextField` between 2 and 5. There would be
|
||||
two ways to go about this:
|
||||
@ -273,9 +276,9 @@ call `setValidator` easily. However, a `DataObject` can provide its' own `Valida
|
||||
`getCMSValidator()` method. The CMS interfaces such as [LeftAndMain](api:SilverStripe\Admin\LeftAndMain), [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) and [GridField](api:SilverStripe\Forms\GridField\GridField) will
|
||||
respect the provided `Validator` and handle displaying error and success responses to the user.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Again, custom error messages can be provided through the `FormField`
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
```php
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Form Templates
|
||||
summary: Customize the generated HTML for a FormField or an entire Form.
|
||||
icon: file-code
|
||||
---
|
||||
|
||||
# Form Templates
|
||||
|
||||
@ -18,22 +21,22 @@ $field->setTemplate('MyCustomTextField');
|
||||
|
||||
To override the template for CMS forms, the custom templates should be located in **/app/templates**. Front-end form templates can be located in **/app/templates** or in the active theme's **/templates** directory.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
It's recommended to copy the contents of the template you're going to replace and use that as a start. For instance, if
|
||||
you want to create a `MyCustomFormTemplate` copy the contents of `Form.ss` to a `MyCustomFormTemplate.ss` file and
|
||||
modify as you need.
|
||||
|
||||
*The default Form.ss can be found in `/vendor/silverstripe/framework/templates/SilverStripe/Forms/Includes/`*
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
By default, Form and Fields follow the SilverStripe Template convention and are rendered into templates of the same
|
||||
class name (i.e EmailField will attempt to render into `EmailField.ss` and if that isn't found, `TextField.ss` or
|
||||
finally `FormField.ss`).
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
While you can override all templates using normal view inheritance (i.e defining a `Form.ss`) other modules may rely on
|
||||
the core template structure. It is recommended to use `setTemplate` and unique templates for specific forms.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
For [FormField](api:SilverStripe\Forms\FormField) instances, there are several other templates that are used on top of the main `setTemplate`.
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Form Security
|
||||
summary: Ensure Forms are secure against Cross-Site Request Forgery attacks, bots and other malicious intent.
|
||||
icon: shield-alt
|
||||
---
|
||||
|
||||
# Form Security
|
||||
|
||||
@ -13,10 +16,10 @@ SilverStripe protect users against [Cross-Site Request Forgery](https://www.owas
|
||||
random string generated by [SecurityToken](api:SilverStripe\Security\SecurityToken) to identify the particular user request vs a third-party forging fake
|
||||
requests.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
For more information on Cross-Site Request Forgery, consult the [OWASP](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
|
||||
website.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
The `SecurityToken` automatically added looks something like:
|
||||
|
||||
@ -47,10 +50,10 @@ $form = new Form(..);
|
||||
$form->disableSecurityToken();
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Do not disable the SecurityID for forms that perform some modification to the users session. This will open your
|
||||
application up to `CSRF` security holes.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Strict Form Submission
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Form Transformations
|
||||
summary: Provide read-only and disabled views of your Form data.
|
||||
icon: random
|
||||
---
|
||||
|
||||
# Read-only and Disabled Forms
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Tabbed Forms
|
||||
summary: Find out how CMS interfaces use jQuery UI tabs to provide nested FormFields.
|
||||
---
|
||||
|
||||
# Tabbed Forms
|
||||
|
||||
@ -7,17 +9,17 @@ SilverStripe's [FormScaffolder](api:SilverStripe\Forms\FormScaffolder) can autom
|
||||
CMS and other scaffolded interfaces, it will output [TabSet](api:SilverStripe\Forms\TabSet) and [Tab](api:SilverStripe\Forms\Tab) objects and use jQuery Tabs to split
|
||||
parts of the data model.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
All interfaces within the CMS such as [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) and [LeftAndMain](api:SilverStripe\Admin\LeftAndMain) use tabbed interfaces by default.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
When dealing with tabbed forms, modifying the fields in the form has a few differences. Each [Tab](api:SilverStripe\Forms\Tab) will be given a
|
||||
name, and normally they all exist under the `Root` [TabSet](api:SilverStripe\Forms\TabSet).
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
[TabSet](api:SilverStripe\Forms\TabSet) instances can contain child [Tab](api:SilverStripe\Forms\Tab) and further [TabSet](api:SilverStripe\Forms\TabSet) instances, however the CMS UI will only
|
||||
display up to two levels of tabs in the interface.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Adding a field to a tab
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Common FormField type subclasses
|
||||
summary: A table containing a list of the common FormField subclasses.
|
||||
---
|
||||
|
||||
# Common FormField type subclasses
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: DateField
|
||||
summary: How to format and use the DateField class.
|
||||
---
|
||||
|
||||
# DateField
|
||||
|
||||
@ -52,9 +54,9 @@ DateField::create('MyDate')
|
||||
->setDateFormat('dd/MM/yyyy');
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details).
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
|
||||
## Min and Max Dates
|
||||
@ -90,9 +92,9 @@ $dateField->setDescription(_t(
|
||||
$dateField->setAttribute('placeholder', $dateField->getDateFormat());
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Fields scaffolded through [DataObject::scaffoldCMSFields()](api:SilverStripe\ORM\DataObject::scaffoldCMSFields()) automatically have a description attached to them.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## API Documentation
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Rich-text editing (WYSIWYG)
|
||||
summary: SilverStripe's use and configuration of TinyMCE html editor.
|
||||
summary: Silverstripe CMS's use and configuration of TinyMCE html editor.
|
||||
icon: file-code
|
||||
---
|
||||
|
||||
# Rich-text editing (WYSIWYG)
|
||||
|
||||
@ -83,14 +86,14 @@ in the framework (and the `cms` module in case you've got that installed).
|
||||
There can be multiple configs, which should always be created / accessed using [HtmlEditorConfig::get()](api:SilverStripe\Forms\HTMLEditor\HtmlEditorConfig::get()). You can
|
||||
then set the currently active config using `set_active()`.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
</div>
|
||||
[info]
|
||||
[/info]
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Currently the order in which the `_config.php` files are executed depends on the module directory names. Execution
|
||||
order is alphabetical, so if you set a TinyMCE option in the `aardvark/_config.php`, this will be overridden in
|
||||
`vendor/silverstripe/framework/admin/_config.php` and your modification will disappear.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Adding and removing capabilities
|
||||
|
||||
@ -107,11 +110,11 @@ use SilverStripe\Forms\HTMLEditor\HtmlEditorConfig;
|
||||
HtmlEditorConfig::get('cms')->enablePlugins('media');
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
This utilities the TinyMCE's `PluginManager::load` function under the hood (check the
|
||||
[TinyMCE documentation on plugin loading](http://www.tinymce.com/wiki.php/API3:method.tinymce.AddOnManager.load) for
|
||||
details).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Plugins and advanced themes can provide additional buttons that can be added (or removed) through the
|
||||
configuration. Here is an example of adding a `ssmacron` button after the `charmap` button:
|
||||
@ -130,11 +133,11 @@ Buttons can also be removed:
|
||||
HtmlEditorConfig::get('cms')->removeButtons('tablecontrols', 'blockquote', 'hr');
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Internally [HtmlEditorConfig](api:SilverStripe\Forms\HTMLEditor\HtmlEditorConfig) uses the TinyMCE's `theme_advanced_buttons` option to configure these. See the
|
||||
[TinyMCE documentation of this option](http://www.tinymce.com/wiki.php/Configuration:theme_advanced_buttons_1_n)
|
||||
for more details.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### Setting options
|
||||
|
||||
@ -162,10 +165,10 @@ HtmlEditorConfig::get('cms')->setOption(
|
||||
);
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
The default setting for the CMS's `extended_valid_elements` we are overriding here can be found in
|
||||
`vendor/silverstripe/admin/_config.php`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Writing custom plugins
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: GridField
|
||||
summary: How to use the GridField class for managing tabular data.
|
||||
icon: table
|
||||
---
|
||||
|
||||
# GridField
|
||||
|
||||
@ -13,14 +16,14 @@ use SilverStripe\Forms\GridField\GridField;
|
||||
$field = new GridField($name, $title, $list);
|
||||
```
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
GridField can only be used with `$list` data sets that are of the type `SS_List` such as `DataList` or `ArrayList`.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
[GridField](api:SilverStripe\Forms\GridField\GridField) powers the automated data UI of [ModelAdmin](api:SilverStripe\Admin\ModelAdmin). For more information about `ModelAdmin` see the
|
||||
[Customizing the CMS](/developer_guides/customising_the_admin_interface) guide.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Each `GridField` is built from a number of components grouped into the [GridFieldConfig](api:SilverStripe\Forms\GridField\GridFieldConfig). Without any components,
|
||||
a `GridField` has almost no functionality. The `GridFieldConfig` instance and the attached [GridFieldComponent](api:SilverStripe\Forms\GridField\GridFieldComponent) are
|
||||
@ -201,15 +204,15 @@ $gridField->setConfig($config);
|
||||
Similar to `GridFieldConfig_Base` with the addition support of the ability to view a `GridFieldDetailForm` containing
|
||||
a read-only view of the data record.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The data row show must be a `DataObject` subclass. The fields displayed in the read-only view come from
|
||||
`DataObject::getCMSFields()`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The `DataObject` class displayed must define a `canView()` method that returns a boolean on whether the user can view
|
||||
this record.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
```php
|
||||
@ -228,15 +231,15 @@ $gridField->setConfig($config);
|
||||
|
||||
Similar to `GridFieldConfig_RecordViewer` with the addition support to edit or delete each of the records.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The data row show must be a `DataObject` subclass. The fields displayed in the edit view come from
|
||||
`DataObject::getCMSFields()`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Permission control for editing and deleting the record uses the `canEdit()` and `canDelete()` methods on the
|
||||
`DataObject` object.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
```php
|
||||
@ -428,10 +431,10 @@ class MyAreaComponent implements GridField_HTMLProvider
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Please note that in templates, you'll need to escape the dollar sign on `\$DefineFragment`. These are specially
|
||||
processed placeholders as opposed to native template syntax.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Now you can add other components into this area by returning them as an array from your
|
||||
[GridFieldComponent::getHTMLFragments()](api:SilverStripe\Forms\GridField\GridFieldComponent::getHTMLFragments()) implementation:
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Field Types
|
||||
summary: More information about some of the core form fields
|
||||
---
|
||||
# Field Types
|
||||
|
||||
[CHILDREN]
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to Encapsulate Forms
|
||||
summary: Learn how to move a form from a controller into its own class definition.
|
||||
iconBrand: wpforms
|
||||
---
|
||||
|
||||
# How to Encapsulate Forms
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to Create Lightweight Form
|
||||
summary: Create a simple search form with Silverstripe CMS
|
||||
iconBrand: wpforms
|
||||
---
|
||||
|
||||
# How to Create Lightweight Form
|
||||
|
||||
@ -48,8 +52,8 @@ public function SearchForm()
|
||||
`SearchForm.ss` will be executed within the scope of the `Form` object so has access to any of the methods and
|
||||
properties on [Form](api:SilverStripe\Forms\Form) such as `$Fields` and `$Actions`.
|
||||
|
||||
<div class="notice">
|
||||
[notice]
|
||||
To understand more about Scope or the syntax for custom templates, read the [Templates](../../templates) guide.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
|
||||
---
|
||||
title: Create a GridField Component
|
||||
summary: Customise your GridField with a variety of add-ons.
|
||||
icon: table
|
||||
---
|
||||
A single component often uses a number of interfaces.
|
||||
|
||||
### GridField_HTMLProvider
|
||||
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Create a GridField action provider
|
||||
summary: Handle custom actions on your GridField
|
||||
---
|
||||
# How to add a custom action to a GridField row
|
||||
|
||||
You can add an action to the row(s) of a [GridField](/developer_guides/forms/field_types/gridfield), such as the built in edit or delete actions.
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Simple contact form
|
||||
summary: Create a form that submits a message via email
|
||||
iconBrand: wpforms
|
||||
---
|
||||
|
||||
# How to make a simple contact form
|
||||
|
||||
In this how-to, we'll explain how to set up a specific page type
|
||||
@ -119,12 +125,12 @@ class ContactPageController extends PageController
|
||||
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
Caution: This form is prone to abuse by spammers,
|
||||
since it doesn't enforce a rate limitation, or checks for bots.
|
||||
We recommend to use a validation service like the ["recaptcha" module](http://www.silverstripe.org/recaptcha-module/)
|
||||
for better security.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
Any function that receives a form submission takes two arguments: the data passed to the form as an indexed array, and the form itself. In order to extract the data, you can either use functions on the form object to get the fields and query their values, or just use the raw data in the array. In the example above, we used the array, as it's the easiest way to get data without requiring the form fields to perform any special transformations.
|
||||
|
||||
|
6
docs/en/02_Developer_Guides/03_Forms/How_Tos/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Forms
|
||||
|
||||
[CHILDREN]
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Forms
|
||||
summary: Capture user information through Forms. This guide will work through how to create SilverStripe forms, adding and modifying fields and how to handle form submissions.
|
||||
introduction: This guide will work through how to create SilverStripe forms, adding and modifying fields and how to handle form submissions.
|
||||
iconBrand: wpforms
|
||||
---
|
||||
|
||||
The [Form](api:SilverStripe\Forms\Form) class provides a way to create interactive forms in your web application with very little effort.
|
||||
SilverStripe handles generating the correct semantic HTML markup for the form and each of the fields, as well as the
|
||||
@ -10,7 +13,7 @@ framework for dealing with submissions and validation.
|
||||
|
||||
## FormField Documentation
|
||||
|
||||
[CHILDREN Folder="Fields"]
|
||||
[CHILDREN Folder="Field_types"]
|
||||
|
||||
## How to's
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Configuration API
|
||||
summary: SilverStripe's YAML based Configuration API for setting runtime configuration.
|
||||
summary: Silverstripe CMS's YAML based Configuration API for setting runtime configuration.
|
||||
icon: laptop-code
|
||||
---
|
||||
|
||||
# Configuration API
|
||||
|
||||
@ -15,9 +18,9 @@ properties API:
|
||||
- Configuration is normally set once during initialization and then not changed.
|
||||
- Configuration is normally set by a knowledgeable technical user, such as a developer, not the end user.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
For providing content editors or CMS users a place to manage configuration see the [SiteConfig](siteconfig) module.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Configuration Properties
|
||||
|
||||
@ -139,10 +142,10 @@ echo implode(', ', MyClass::config()->option_one);
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
There is no way currently to restrict read or write access to any configuration property, or influence/check the values
|
||||
being read or written.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Configuration Values
|
||||
|
||||
@ -173,11 +176,11 @@ Class\With\Array\Config:
|
||||
- If the value is not an array, the highest priority value is used without any attempt to merge
|
||||
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The exception to this is "false-ish" values - empty arrays, empty strings, etc. When merging a non-false-ish value with
|
||||
a false-ish value, the result will be the non-false-ish value regardless of priority. When merging two false-ish values
|
||||
the result will be the higher priority false-ish value.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
The locations that configuration values are taken from in highest -> lowest priority order are:
|
||||
|
||||
@ -188,10 +191,10 @@ order, where the item that is latest is highest priority)
|
||||
- The composite configuration value of the parent class of this class
|
||||
- Any static set on an "additional static source" class (such as an extension) named the same as the name of the property
|
||||
|
||||
<div class="notice">
|
||||
[notice]
|
||||
It is an error to have mixed types of the same named property in different locations. An error will not necessarily
|
||||
be raised due to optimizations in the lookup code.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Configuration Masks
|
||||
|
||||
@ -214,18 +217,18 @@ bitwise `|` operator.
|
||||
|
||||
## Configuration YAML Syntax and Rules
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
As of Silverstripe 4, YAML files can no longer be placed any deeper than 2 directories deep. As this was an unintended bug, this change will only affect you if you nest your modules deeper than the top level of your project.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
Each module can have a directory immediately underneath the main module directory called `_config/`. Inside this
|
||||
directory you can add YAML files that contain values for the configuration system.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The name of the files within the applications `_config` directly are arbitrary. Our examples use
|
||||
`app/_config/app.yml` but you can break this file down into smaller files, or clearer patterns like `extensions.yml`,
|
||||
`email.yml` if you want. For add-on's and modules, it is recommended that you name them with `<module_name>.yml`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
The structure of each YAML file is a series of headers and values separated by YAML document separators.
|
||||
|
||||
@ -242,9 +245,9 @@ SilverStripe\Control\Director:
|
||||
---
|
||||
```
|
||||
|
||||
<div class="info">
|
||||
[info]
|
||||
If there is only one set of values the header can be omitted.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Each value section of a YAML file has:
|
||||
|
||||
@ -311,10 +314,10 @@ after value sections with a name of `rootroutes`. However because `\*` has three
|
||||
|
||||
In this case `\*` means "every value section _except_ ones that have a fragment name of rootroutes".
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
It is possible to create chains that are unsolvable. For instance, A must be before B, B must be before C, C must be
|
||||
before A. In this case you will get an error when accessing your site.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Exclusionary rules
|
||||
|
||||
@ -371,11 +374,11 @@ Only:
|
||||
---
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
When you have more than one rule for a nested fragment, they're joined like
|
||||
`FRAGMENT_INCLUDED = (ONLY && ONLY) && !(EXCEPT && EXCEPT)`.
|
||||
That is, the fragment will be included if all Only rules match, except if all Except rules match.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Unit tests
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: SiteConfig
|
||||
summary: Content author configuration through the SiteConfig module.
|
||||
icon: laptop-code
|
||||
---
|
||||
|
||||
# SiteConfig
|
||||
|
||||
@ -72,10 +75,10 @@ Silverstripe\SiteConfig\SiteConfig:
|
||||
- CustomSiteConfig
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
After adding the class and the YAML change, make sure to rebuild your database by visiting http://example.com/dev/build.
|
||||
You may also need to reload the screen with a `?flush=1` i.e http://example.com/admin/settings?flush=1.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
You can define as many extensions for `SiteConfig` as you need. For example, if you're developing a module and want to
|
||||
provide the users a place to configure settings then the `SiteConfig` panel is the place to go it.
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Environment Variables
|
||||
summary: Site configuration variables such as database connection details, environment type and remote login information.
|
||||
icon: dollar-sign
|
||||
---
|
||||
|
||||
# Environment Variables
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Configuration
|
||||
summary: SilverStripe provides several ways to store and modify your application settings. Learn about site wide settings and the YAML based configuration system.
|
||||
introduction: SilverStripe provides several ways to store and modify your application settings. Learn about site wide settings and the YAML based configuration system.
|
||||
icon: laptop-code
|
||||
---
|
||||
|
||||
[CHILDREN]
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Modules
|
||||
summary: Extend core functionality with modules.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Modules
|
||||
|
||||
@ -63,9 +66,9 @@ Composer is using [version constraints](https://getcomposer.org/doc/articles/ver
|
||||
To lock down to a specific version, branch or commit, read up on
|
||||
["lock" files](http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file).
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
After you add or remove modules, make sure you rebuild the database, class and configuration manifests by going to http://yoursite.com/dev/build?flush=1
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Publishing your own SilverStripe module
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Extensions
|
||||
summary: Extensions and DataExtensions let you modify and augment objects transparently.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Extensions and DataExtensions
|
||||
|
||||
@ -10,10 +13,10 @@ trait applied within core, modules or even their own code to make it more reusab
|
||||
Extensions are defined as subclasses of either [DataExtension](api:SilverStripe\ORM\DataExtension) for extending a [DataObject](api:SilverStripe\ORM\DataObject) subclass or
|
||||
the [Extension](api:SilverStripe\Core\Extension) class for non DataObject subclasses (such as [Controller](api:SilverStripe\Control\Controller))
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
For performance reasons a few classes are excluded from receiving extensions, including `ViewableData`
|
||||
and `RequestHandler`. You can still apply extensions to descendants of these classes.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
**app/code/extensions/MyMemberExtension.php**
|
||||
|
||||
@ -36,9 +39,9 @@ class MyMemberExtension extends DataExtension
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Convention is for extension class names to end in `Extension`. This isn't a requirement but makes it clearer
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
After this class has been created, it does not yet apply it to any object. We need to tell SilverStripe what classes
|
||||
we want to add the `MyMemberExtension` too. To activate this extension, add the following via the [Configuration API](../configuration).
|
||||
@ -173,9 +176,9 @@ class MyMemberExtension extends DataExtension
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The `$validator` parameter is passed by reference, as it is an object.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Another common example of when you will want to modify a method is to update the default CMS fields for an object in an
|
||||
extension. The `CMS` provides a `updateCMSFields` Extension Hook to tie into.
|
||||
@ -207,10 +210,10 @@ class MyMemberExtension extends DataExtension
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
If you're providing a module or working on code that may need to be extended by other code, it should provide a *hook*
|
||||
which allows an Extension to modify the results.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
```php
|
||||
@ -269,10 +272,10 @@ callback to be executed immediately before and after `extend()` is called on ext
|
||||
This is useful in many cases where working with modules such as `Translatable` which operate on `DataObject` fields
|
||||
that must exist in the `FieldList` at the time that `$this->extend('UpdateCMSFields')` is called.
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Please note that each callback is only ever called once, and then cleared, so multiple extensions to the same function
|
||||
require that a callback is registered each time, if necessary.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Example: A class that wants to control default values during object initialization. The code needs to assign a value
|
||||
if not specified in `self::$defaults`, but before extensions have been called:
|
||||
@ -293,9 +296,9 @@ public function __construct()
|
||||
|
||||
Example 2: User code can intervene in the process of extending cms fields.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
This method is preferred to disabling, enabling, and calling field extensions manually.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
```php
|
||||
@ -341,12 +344,12 @@ class CustomisedSomeExtension extends SomeExtension
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Please note that modifications such as this should be done in YAML configuration only. It is not recommended
|
||||
to use `Config::modify()->set()` to adjust the implementation class name of an extension after the configuration
|
||||
manifest has been loaded, and may not work consistently due to the "extra methods" cache having already been
|
||||
populated.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Related Lessons
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Shortcodes
|
||||
summary: Flexible content embedding
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Shortcodes
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Injector
|
||||
summary: Introduction to using Dependency Injection within SilverStripe.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Injector
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Aspects
|
||||
summary: Introduction to using aspect-oriented programming with SilverStripe.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Aspects
|
||||
|
||||
@ -10,9 +13,9 @@ Aspect oriented programming is the idea that some logic abstractions can be appl
|
||||
> functions from the main program's business logic. It aims to increase modularity by allowing the separation of
|
||||
> cross-cutting concerns, forming a basis for aspect-oriented software development.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
[Wikipedia](http://en.wikipedia.org/wiki/Aspect-oriented_programming) provides a much more in-depth explanation.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
In the context of the SilverStripe [Dependency Injector](injector), Aspects are achieved thanks to PHP's `__call` magic
|
||||
method combined with the `Proxy` Design Pattern.
|
||||
@ -38,10 +41,10 @@ specific database server, whereas all read queries can be handled by slave serve
|
||||
|
||||
A simplified implementation might look like the following.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
This doesn't cover all cases used by SilverStripe so is not a complete solution, more just a guide to how it would be
|
||||
used.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
**app/code/MySQLWriteDbAspect.php**
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Custom Templates
|
||||
summary: Override templates from core and modules in your application
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Custom Templates
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to Publish a SilverStripe module
|
||||
summary: Have you created some work you think others can use? Turn it into a module and share it.
|
||||
icon: rocket
|
||||
---
|
||||
|
||||
# How to Publish a SilverStripe module.
|
||||
|
||||
@ -86,9 +90,9 @@ Say you have a module which supports SilverStripe 3.0. A new release of this mod
|
||||
in SilverStripe 3.1. In this case, you would create a new branch for the 3.0 compatible code base of your module. This
|
||||
allows you to continue fixing bugs on this older release branch.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
As a convention, the `master` branch of your module should always work with the `master` branch of SilverStripe.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Other branches should be created on your module as needed if they're required to support specific SilverStripe releases.
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to Create a Google Maps Shortcode
|
||||
summary: Learn how to embed a Google map in the WYSIWYG editor with a simple shortcode
|
||||
icon: map
|
||||
---
|
||||
|
||||
# How to Create a Google Maps Shortcode
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Track member logins
|
||||
summary: Keep a log in the database of who logs in and when
|
||||
icon: user-friends
|
||||
---
|
||||
# Howto: Track Member Logins
|
||||
|
||||
Sometimes its good to know how active your users are,
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Extending Silverstripe
|
||||
|
||||
[CHILDREN]
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Extending SilverStripe
|
||||
summary: Understand the ways to modify the built-in functionality through Extensions, Subclassing and Dependency Injection.
|
||||
introduction: SilverStripe is easily extensible to meet custom application requirements. This guide covers the wide range of API's to modify built-in functionality and make your own code easily extensible.
|
||||
icon: code
|
||||
---
|
||||
|
||||
No two applications are ever going to be the same and SilverStripe is built with this in mind. The core framework
|
||||
includes common functionality and default behaviors easily complemented with add-ons such as modules, widgets and
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Unit and Integration Testing
|
||||
summary: Test models, database logic and your object methods.
|
||||
---
|
||||
|
||||
# Unit and Integration Testing
|
||||
|
||||
@ -36,28 +38,28 @@ class PageTest extends SapphireTest
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Tests for your application should be stored in the `app/tests` directory. Test cases for add-ons should be stored in
|
||||
the `(modulename)/tests` directory.
|
||||
|
||||
Test case classes should end with `Test` (e.g `PageTest`) and test methods must start with `test` (e.g `testMyMethod`).
|
||||
|
||||
Ensure you [import](http://php.net/manual/en/language.namespaces.importing.php#example-252) any classes you need for the test, including `SilverStripe\Dev\SapphireTest` or `SilverStripe\Dev\FunctionalTest`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
A SilverStripe unit test is created by extending one of two classes, [SapphireTest](api:SilverStripe\Dev\SapphireTest) or [FunctionalTest](api:SilverStripe\Dev\FunctionalTest).
|
||||
|
||||
[SapphireTest](api:SilverStripe\Dev\SapphireTest) is used to test your model logic (such as a `DataObject`), and [FunctionalTest](api:SilverStripe\Dev\FunctionalTest) is used when
|
||||
you want to test a `Controller`, `Form` or anything that requires a web page.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
`FunctionalTest` is a subclass of `SapphireTest` so will inherit all of the behaviors. By subclassing `FunctionalTest`
|
||||
you gain the ability to load and test web pages on the site.
|
||||
|
||||
`SapphireTest` in turn, extends `PHPUnit_Framework_TestCase`. For more information on `PHPUnit_Framework_TestCase` see
|
||||
the [PHPUnit](http://www.phpunit.de) documentation. It provides a lot of fundamental concepts that we build on in this
|
||||
documentation.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Test Databases and Fixtures
|
||||
|
||||
@ -65,15 +67,15 @@ SilverStripe tests create their own database when the test starts and fixture fi
|
||||
connection details you provide for the main website. The new `ss_tmp` database does not copy what is currently in your
|
||||
application database. To provide seed data use a [Fixture](fixtures) file.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
As the test runner will create new databases for the tests to run, the database user should have the appropriate
|
||||
permissions to create new databases on your server.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
The test database is rebuilt every time one of the test methods is run and is removed afterwards. If the test is interrupted, the database will not be removed. Over time, you may have several hundred test
|
||||
databases on your machine. To get rid of them, run `sake dev/tasks/CleanupTestDatabasesTask`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Custom PHPUnit Configuration
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Functional Testing
|
||||
summary: Test controllers, forms and HTTP responses.
|
||||
---
|
||||
|
||||
# Functional Testing
|
||||
|
||||
@ -90,9 +92,9 @@ Assert that the most recently queried page contains a number of content tags spe
|
||||
selector will be applied to the HTML of the most recent page. The content of every matching tag will be examined. The
|
||||
assertion fails if one of the expectedMatches fails to appear.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
`&nbsp;` characters are stripped from the content; make sure that your assertions take this into account.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### assertExactHTMLMatchBySelector
|
||||
```php
|
||||
@ -105,9 +107,9 @@ Assert that the most recently queried page contains a number of content tags spe
|
||||
selector will be applied to the HTML of the most recent page. The full HTML of every matching tag will be examined. The
|
||||
assertion fails if one of the expectedMatches fails to appear.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
`&nbsp;` characters are stripped from the content; make sure that your assertions take this into account.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Related Documentation
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Behavior Testing
|
||||
summary: Describe how your application should behave in plain text and run tests in a browser.
|
||||
---
|
||||
|
||||
# Behavior Testing
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Fixtures
|
||||
summary: Populate test databases with fake seed data.
|
||||
---
|
||||
|
||||
# Fixtures
|
||||
|
||||
@ -126,19 +128,19 @@ seen by the fields prefixed with `=>`.
|
||||
Each one of our Players has a relationship to a Team, this is shown with the `Team` field for each `Player` being set
|
||||
to `=>Team.` followed by a team name.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Take the player John in our example YAML, his team is the Hurricanes which is represented by `=>Team.hurricanes`. This
|
||||
sets the `has_one` relationship for John with with the `Team` object `hurricanes`.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
Note that we use the name of the relationship (Team), and not the name of the
|
||||
database field (TeamID).
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
Also be aware the target of a relationship must be defined before it is referenced, for example the `hurricanes` team must appear in the fixture file before the line `Team: =>Team.hurricanes`.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
This style of relationship declaration can be used for any type of relationship (i.e `has_one`, `has_many`, `many_many`).
|
||||
|
||||
@ -180,10 +182,10 @@ $team->write();
|
||||
$team->Players()->add($john);
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
As the YAML fixtures will call `write`, any `onBeforeWrite()` or default value logic will be executed as part of the
|
||||
test.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### Fixtures for namespaced classes
|
||||
|
||||
@ -201,9 +203,9 @@ MyProject\Model\Team:
|
||||
Players: =>MyProject\Model\Player.john
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
If your tests are failing and your database has table names that follow the fully qualified class names, you've probably forgotten to implement `private static $table_name = 'Player';` on your namespaced class. This property was introduced in SilverStripe 4 to reduce data migration work. See [DataObject](api:SilverStripe\ORM\DataObject) for an example.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### Defining many_many_extraFields
|
||||
|
||||
@ -277,9 +279,9 @@ While manually defined fixtures provide full flexibility, they offer very little
|
||||
Alternatively, you can use the [FixtureFactory](api:SilverStripe\Dev\FixtureFactory) class, which allows you to set default values, callbacks on object
|
||||
creation, and dynamic/lazy value setting.
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
`SapphireTest` uses `FixtureFactory` under the hood when it is provided with YAML based fixtures.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
The idea is that rather than instantiating objects directly, we'll have a factory class for them. This factory can have
|
||||
*blueprints* defined on it, which tells the factory how to instantiate an object of a specific type. Blueprints need a
|
||||
@ -306,10 +308,10 @@ $obj = $factory->createObject('Team', 'hurricanes', [
|
||||
]);
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
It is important to remember that fixtures are referenced by arbitrary identifiers ('hurricanes'). These are internally
|
||||
mapped to their database identifiers.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
After we've created this object in the factory, `getId` is used to retrieve it by the identifier.
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: Testing Glossary
|
||||
summary: All the jargon you need to be a bonafide testing guru
|
||||
---
|
||||
|
||||
<dl>
|
||||
<dt>Assertion<dd>A predicate statement that must be true when a test runs.
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: How to write a SapphireTest
|
||||
summary: Learn the basics of unit testing in Silverstripe
|
||||
---
|
||||
|
||||
# How to write a SapphireTest
|
||||
|
||||
@ -48,17 +51,17 @@ Firstly we define a static `$fixture_file`, this should point to a file that rep
|
||||
represented as a YAML [Fixture](../fixtures). When our test is run, the data from this file will be loaded into a test
|
||||
database and discarded at the end of the test.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
The `fixture_file` property can be path to a file, or an array of strings pointing to many files. The path must be
|
||||
absolute from your website's root folder.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
The second part of our class is the `testURLGeneration` method. This method is our test. When the test is executed,
|
||||
methods prefixed with the word `test` will be run.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
The test database is rebuilt every time one of these methods is run.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Inside our test method is the `objFromFixture` method that will generate an object for us based on data from our fixture
|
||||
file. To identify to the object, we provide a class name and an identifier. The identifier is specified in the YAML file
|
||||
@ -69,9 +72,9 @@ The final part of our test is an assertion command, `assertEquals`. An assertion
|
||||
in our test methods (in this case we are testing if two values are equal). A test method can have more than one
|
||||
assertion command, and if any one of these assertions fail, so will the test method.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
For more information on PHPUnit's assertions see the [PHPUnit manual](http://www.phpunit.de/manual/current/en/api.html#api.assert).
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Related Documentation
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: How to write a FunctionalTest
|
||||
summary: Expand your testing capabilities with integrations tests
|
||||
---
|
||||
|
||||
# How to Write a FunctionalTest
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to use a FixtureFactory
|
||||
summary: Provide context to your tests with database fixtures
|
||||
icon: industry
|
||||
---
|
||||
|
||||
# How to use a FixtureFactory
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: How to test emails within unit tests
|
||||
summary: Test email functionality without ever hitting an inbox
|
||||
icon: envelope
|
||||
---
|
||||
|
||||
# Testing Email within Unit Tests
|
||||
|
||||
|
6
docs/en/02_Developer_Guides/06_Testing/How_Tos/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Testing
|
||||
|
||||
[CHILDREN]
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: Testing
|
||||
summary: Deploy robust applications by bundling Unit and Behavior tests with your application code and modules.
|
||||
---
|
||||
|
||||
# Unit and Integration Testing
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Environment Types
|
||||
summary: Configure your SilverStripe environment to define how your web application behaves.
|
||||
icon: exclamation-circle
|
||||
---
|
||||
|
||||
# Environment Types
|
||||
|
||||
@ -14,11 +17,11 @@ When developing your websites, adding page types or installing modules you shoul
|
||||
you will see full error back traces and view the development tools without having to be logged in as an administrator
|
||||
user.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
**dev mode should not be enabled long term on live sites for security reasons**. In dev mode by outputting back traces
|
||||
of function calls a hacker can gain information about your environment (including passwords) so you should use dev mode
|
||||
on a public server very carefully.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Test Mode
|
||||
|
||||
@ -48,9 +51,9 @@ When using CGI/FastCGI with Apache, you will have to add the `RewriteRule .* - [
|
||||
|
||||
All error messages are suppressed from the user and the application is in it's most *secure* state.
|
||||
|
||||
<div class="alert">
|
||||
[alert]
|
||||
Live sites should always run in live mode. You should not run production websites in dev mode.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
## Checking Environment Type
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Logging and Error Handling
|
||||
summary: Trap, fire and report diagnostic logs, user exceptions, warnings and errors.
|
||||
icon: exclamation-circle
|
||||
---
|
||||
|
||||
# Logging and Error Handling
|
||||
|
||||
@ -249,11 +252,11 @@ SilverStripe\Core\Injector\Injector:
|
||||
Body: "The website server has not been able to respond to your request"
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
In addition to SilverStripe-integrated logging, it is advisable to fall back to PHP's native logging functionality. A
|
||||
script might terminate before it reaches the SilverStripe error handling, for example in the case of a fatal error. Make
|
||||
sure `log_errors` and `error_log` in your PHP ini file are configured.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Replacing default implementations
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
title: URL Variable tools
|
||||
summary: Useful debugging tools you can use right in the browser
|
||||
---
|
||||
# URL Variable Tools
|
||||
|
||||
## Introduction
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Template debugging
|
||||
summary: Track down which template rendered a piece of html
|
||||
icon: bug
|
||||
---
|
||||
|
||||
# Debugging templates
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Debugging
|
||||
summary: Learn how to identify errors in your application and best practice for logging application errors.
|
||||
|
||||
icon: bug
|
||||
---
|
||||
# Debugging
|
||||
|
||||
SilverStripe can be a large and complex framework to debug, but there are ways to make debugging less painful. In this
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Partial Caching
|
||||
summary: Cache SilverStripe templates to reduce database queries.
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
# Partial Caching
|
||||
|
||||
@ -76,10 +79,10 @@ or edited:
|
||||
<% cached 'categorylist', $List('Category').max('LastEdited'), $List('Category').count() %>
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Note the use of both `.max('LastEdited')` and `.count()` - this takes care of both the case where an object has been
|
||||
edited since the cache was last built, and also when an object has been deleted since the cache was last built.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
We can also calculate aggregates on relationships. The logic for that can get a bit complex, so we can extract that on
|
||||
to the controller so it's not cluttering up our template.
|
||||
@ -231,10 +234,10 @@ could also write the last example as:
|
||||
<% end_cached %>
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Currently a nested cache block can not be contained within an if or loop block. The template engine will throw an error
|
||||
letting you know if you've done this. You can often get around this using aggregates or by un-nesting the block.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
Failing example:
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Caching
|
||||
summary: Optimise performance by caching expensive processes
|
||||
icon: tachometer-alt
|
||||
---
|
||||
# Caching
|
||||
|
||||
## Overview
|
||||
@ -39,12 +44,12 @@ SilverStripe\Core\Injector\Injector:
|
||||
namespace: "myCache"
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Please note that if you have the `silverstripe/versioned` module installed (automatically installed by the
|
||||
`silverstripe/cms` module), caches will automatically be segmented by current “stage”. This ensures that
|
||||
any content written to the cache in the _draft_ reading mode isn’t accidentally exposed in the _live_ reading mode.
|
||||
Please read the [versioned cache segmentation](#versioned-cache-segmentation) section for more information.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
Cache objects are instantiated through a [CacheFactory](SilverStripe\Core\Cache\CacheFactory),
|
||||
which determines which cache adapter is used (see "Adapters" below for details).
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: HTTP Cache Headers
|
||||
summary: Set the correct HTTP cache headers for your responses.
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
# HTTP Cache Headers
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Profiling
|
||||
summary: Identify bottlenecks within your application.
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
# Profiling
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Static Publishing
|
||||
summary: Export your web pages as static HTML and serve the web like it's 1999.
|
||||
---
|
||||
|
||||
# Static Publishing
|
||||
|
||||
@ -7,10 +9,10 @@ One of the best ways to get the top performance out of SilverStripe is to bypass
|
||||
time, connecting to the database and formatting your templates. This is only appropriate approach on web pages that
|
||||
have completely static content.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
If you want to cache part of a page, or your site has interactive elements such as forms, then
|
||||
[Partial Caching](partial_caching) is more suitable.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
By publishing the page as HTML it's possible to run SilverStripe from behind a corporate firewall, on a low performance
|
||||
server or serve millions of hits an hour without expensive hardware.
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Resource Usage
|
||||
summary: Manage SilverStripe's memory footprint and CPU usage.
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
# Resource Usage
|
||||
|
||||
@ -10,18 +13,18 @@ These limits are defined through `memory_limit` and `max_execution_time` in the
|
||||
overwritten through `ini_set()`, unless PHP is running with the [Suhoshin Patches](http://www.hardened-php.net/)
|
||||
or in "[safe mode](http://php.net/manual/en/features.safe-mode.php)".
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Most shared hosting providers will have maximum values that can't be altered.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
For certain tasks like synchronizing a large `assets/` folder with all file and folder entries in the database, more
|
||||
resources are required temporarily. In general, we recommend running resource intensive tasks through the
|
||||
[command line](../cli), where configuration defaults for these settings are higher or even unlimited.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
SilverStripe can request more resources through `Environment::increaseMemoryLimitTo()` and
|
||||
`Environment::increaseTimeLimitTo()` functions.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
```php
|
||||
use SilverStripe\Core\Environment;
|
||||
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Performance
|
||||
summary: Make your applications faster by learning how to write more scalable code and ways to cache your important information.
|
||||
introduction: Make your applications faster by learning how to write more scalable code and ways to cache your important information.
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
The following guide describes the common ways to speed your SilverStripe website up. The general rules for getting
|
||||
the best performance out of SilverStripe include running the latest versions of PHP alongside a
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Members
|
||||
summary: Learn how logged in users are managed in Silverstripe CMS
|
||||
icon: user
|
||||
---
|
||||
|
||||
# Member
|
||||
|
||||
@ -26,10 +30,10 @@ if( $member = Security::getCurrentUser() ) {
|
||||
|
||||
## Subclassing
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
This is the least desirable way of extending the [Member](api:SilverStripe\Security\Member) class. It's better to use [DataExtension](api:SilverStripe\ORM\DataExtension)
|
||||
(see below).
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
You can define subclasses of [Member](api:SilverStripe\Security\Member) to add extra fields or functionality to the built-in membership system.
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Access Control
|
||||
summary: Restrict CMS access to specific groups of users
|
||||
icon: user-lock
|
||||
---
|
||||
# Access Control and Page Security
|
||||
|
||||
There is a fairly comprehensive security mechanism in place for SilverStripe. If you want to add premium content to your
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Permissions
|
||||
summary: Customise the permission system in Silverstripe
|
||||
icon: lock
|
||||
---
|
||||
# User Permissions
|
||||
|
||||
## Introduction
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Authentication
|
||||
summary: Explains SilverStripe's Authentication options and custom authenticators.
|
||||
icon: users-cog
|
||||
---
|
||||
|
||||
# Authentication
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Security
|
||||
summary: Learn how to minimise vulnerabilities in your code
|
||||
icon: user-secret
|
||||
---
|
||||
# Security
|
||||
|
||||
## Introduction
|
||||
@ -99,10 +104,10 @@ $members = Member::get()->where(['"Name" = ?' => $_GET['name']]);
|
||||
$members = Member::get()->where(sprintf('"Name" = %s', Convert::raw2sql($_GET['name'], true)));
|
||||
```
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
It is NOT good practice to "be sure" and convert the data passed to the functions above manually. This might
|
||||
result in *double escaping* and alters the actually saved data (e.g. by adding slashes to your content).
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Manual escaping
|
||||
|
||||
@ -201,10 +206,10 @@ XSS (Cross-Site-Scripting). With some basic guidelines, you can ensure your outp
|
||||
displaying a blog post in HTML from a trusted author, or escaping a search parameter from an untrusted visitor before
|
||||
redisplaying it).
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Note: SilverStripe templates do not remove tags, please use [strip_tags()](http://php.net/strip_tags) for this purpose
|
||||
or [sanitize](http://htmlpurifier.org/) it correctly.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
See [http://shiflett.org/articles/foiling-cross-site-attacks](http://shiflett.org/articles/foiling-cross-site-attacks)
|
||||
for in-depth information about "Cross-Site-Scripting".
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Rate Limiting
|
||||
summary: SilverStripe's in built rate limiting features
|
||||
icon: tachometer-alt
|
||||
---
|
||||
|
||||
# Rate Limiting
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Personal Data
|
||||
summary: How the SilverStripe CMS deals with data privacy
|
||||
icon: user-ninja
|
||||
---
|
||||
|
||||
# Personal Data
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Security
|
||||
summary: This guide covers user authentication, the permission system and how to secure your code against malicious behaviors
|
||||
icon: user-shield
|
||||
---
|
||||
|
||||
# Security and User Authentication
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Email
|
||||
summary: Send HTML and plain text email from your SilverStripe application.
|
||||
icon: envelope-open
|
||||
---
|
||||
|
||||
# Email
|
||||
|
||||
@ -65,11 +69,11 @@ $email = new Email($from, $to, $subject, $body);
|
||||
$email->send();
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The default HTML template for emails is named `GenericEmail` and is located in `vendor/silverstripe/framework/templates/SilverStripe/Email/`.
|
||||
To customise this template, copy it to the `app/templates/Email/` folder or use `setHTMLTemplate` when you create the
|
||||
`Email` instance.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
|
||||
### Templates
|
||||
@ -106,10 +110,10 @@ if ($email->send()) {
|
||||
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
As we've added a new template file (`MyCustomEmail`) make sure you clear the SilverStripe cache for your changes to
|
||||
take affect.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
#### Custom plain templates
|
||||
|
||||
@ -143,10 +147,10 @@ SilverStripe\Control\Email\Email:
|
||||
support@example.com: 'Support team'
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Remember, setting a `from` address that doesn't come from your domain (such as the users email) will likely see your
|
||||
email marked as spam. If you want to send from another address think about using the `setReplyTo` method.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Redirecting Emails
|
||||
|
||||
@ -196,9 +200,9 @@ $email = new Email(...);
|
||||
$email->getSwiftMessage()->getHeaders()->addTextHeader('HeaderName', 'HeaderValue');
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
See this [Wikipedia](http://en.wikipedia.org/wiki/E-mail#Message_header) entry for a list of header names.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Disabling Emails
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: CSV Import
|
||||
summary: Load data into your Silverstripe database in bulk
|
||||
icon: upload
|
||||
---
|
||||
# Import CSV data
|
||||
|
||||
## Introduction
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: RSS Feed
|
||||
summary: Output records from your database as an RSS Feed.
|
||||
icon: rss
|
||||
---
|
||||
|
||||
# RSS Feed
|
||||
|
||||
@ -10,10 +13,10 @@ your current staff members, comments or any other custom [DataObject](api:Silver
|
||||
logical limitation here is that every item in the RSS-feed should be accessible through a URL on your website, so it's
|
||||
advisable to just create feeds from subclasses of [SiteTree](api:SilverStripe\CMS\Model\SiteTree).
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
If you wish to generate an RSS feed that contains a [DataObject](api:SilverStripe\ORM\DataObject), ensure you define a `AbsoluteLink` method on
|
||||
the object.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Usage
|
||||
|
||||
@ -99,9 +102,9 @@ class PageController extends ContentController
|
||||
DataObjects can be rendered in the feed as well, however, since they aren't explicitly [SiteTree](api:SilverStripe\CMS\Model\SiteTree) subclasses we
|
||||
need to include a function `AbsoluteLink` to allow the RSS feed to link through to the item.
|
||||
|
||||
<div class="info">
|
||||
[info]
|
||||
If the items are all displayed on a single page you may simply hard code the link to point to a particular page.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Take an example, we want to create an RSS feed of all the `Players` objects in our site. We make sure the `AbsoluteLink`
|
||||
method is defined and returns a string to the full website URL.
|
||||
@ -211,9 +214,9 @@ public function players()
|
||||
}
|
||||
```
|
||||
|
||||
<div class="warning">
|
||||
[warning]
|
||||
As we've added a new template (PlayersRss.ss) make sure you clear your SilverStripe cache.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
|
||||
## API Documentation
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Import CSV Data through a Controller
|
||||
summary: Data importing through the frontend
|
||||
icon: upload
|
||||
---
|
||||
|
||||
# Import CSV Data through a Controller
|
||||
|
||||
@ -75,7 +79,7 @@ class MyController extends Controller
|
||||
}
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
This interface is not secured, consider using [Permission::check()](api:SilverStripe\Security\Permission::check()) to limit the controller to users with certain
|
||||
access rights.
|
||||
</div>
|
||||
[/alert]
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: A custom CSVBulkLoader instance
|
||||
summary: Customise your data importing
|
||||
icon: upload
|
||||
---
|
||||
|
||||
# How to: A custom CSVBulkLoader instance
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Integration and Web Services
|
||||
|
||||
[CHILDREN]
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
summary: Integrate other web services within your application or make your SilverStripe data available.
|
||||
introduction: Integrate other web services within your application or make your SilverStripe data available.
|
||||
title: Integration and Web Services
|
||||
---
|
||||
|
||||
[CHILDREN]
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Scaffolding with SearchContext
|
||||
summary: Configure the search form within ModelAdmin using the SearchContext class.
|
||||
icon: search
|
||||
---
|
||||
|
||||
# SearchContext
|
||||
|
||||
@ -10,9 +13,9 @@ search parameters and an object class it acts on.
|
||||
The default output of a [SearchContext](api:SilverStripe\ORM\Search\SearchContext) is either a [SQLSelect](api:SilverStripe\ORM\Queries\SQLSelect) object for further refinement, or a
|
||||
[DataObject](api:SilverStripe\ORM\DataObject) instance.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
[SearchContext](api:SilverStripe\ORM\Search\SearchContext) is mainly used by [ModelAdmin](/developer_guides/customising_the_admin_interface/modeladmin).
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Usage
|
||||
|
||||
@ -74,15 +77,15 @@ class MyDataObject extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
See the [SearchFilter](../model/searchfilters) documentation for more information about filters to use such as the
|
||||
`GreaterThanFilter`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
In case you need multiple contexts, consider name-spacing your request parameters by using `FieldList->namespace()` on
|
||||
the `$fields` constructor parameter.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
### Generating a search form from the context
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Fulltext Search
|
||||
summary: Fulltext search allows sophisticated searching on text content.
|
||||
icon: search
|
||||
---
|
||||
|
||||
# FulltextSearchable
|
||||
|
||||
@ -7,11 +10,11 @@ Fulltext search allows advanced search criteria for searching words within a tex
|
||||
Fulltext search can be achieved using the built-in [MySQLDatabase](api:SilverStripe\ORM\Connect\MySQLDatabase) class a more powerful wrapper for Fulltext
|
||||
search is provided through a module.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
See the [FulltextSearch Module](https://github.com/silverstripe-labs/silverstripe-fulltextsearch/). This module provides
|
||||
a high level wrapper for running advanced search services such as Solr, Lucene or Sphinx in the backend rather than
|
||||
`MySQL` search.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Adding Fulltext Support to MySQLDatabase
|
||||
|
||||
@ -36,11 +39,11 @@ class MyDataObject extends DataObject
|
||||
|
||||
The [FulltextSearchable](api:SilverStripe\ORM\Search\FulltextSearchable) extension will add the correct `Fulltext` indexes to the data model.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
The [SearchForm](api:SilverStripe\CMS\Search\SearchForm) and [FulltextSearchable](api:SilverStripe\ORM\Search\FulltextSearchable) API's are currently hard coded to be specific to `Page` and `File`
|
||||
records and cannot easily be adapted to include custom `DataObject` instances. To include your custom objects in the
|
||||
default site search, have a look at those extensions and modify as required.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### Fulltext Filter
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Search
|
||||
summary: Provide your users with advanced search functionality.
|
||||
introduction: Give users the ability to search your applications. Fulltext search for Page Content (and other attributes like "Title") can be easily added to SilverStripe.
|
||||
---
|
||||
|
||||
[CHILDREN]
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: i18n
|
||||
summary: Display templates and PHP code in different languages based on the preferences of your website users.
|
||||
---
|
||||
|
||||
# i18n
|
||||
|
||||
@ -272,9 +274,9 @@ _t(__CLASS__ . '.GREETING', 'Welcome!');
|
||||
|
||||
#### Usage in Template Files
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
The preferred template syntax has changed somewhat since [version 2.x](http://doc.silverstripe.org/framework/en/2.4/topics/i18n#usage-2).
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
In `.ss` template files, instead of `_t(params)` the syntax `<%t params %>` is used. The syntax for passing parameters to the function is quite different to
|
||||
the PHP version of the function.
|
||||
@ -318,9 +320,9 @@ underscore function, and tell you about the created files and any possible entit
|
||||
If you want to run the text collector for just one module you can use the 'module' parameter:
|
||||
`http://localhost/dev/tasks/i18nTextCollectorTask/?module=cms`
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
You'll need to install PHPUnit to run the text collector (see [testing-guide](/developer_guides/testing)).
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
## Module Priority
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: File management
|
||||
summary: Learn how to work with File and Image records
|
||||
icon: file-signature
|
||||
---
|
||||
|
||||
# File management
|
||||
|
||||
@ -9,14 +12,14 @@ Management of files within the CMS is provided via the [silverstripe/asset-admin
|
||||
module. This is a rich and user friendly interface supporting most basic file operations, as well as
|
||||
control over the publishing and security of files.
|
||||
|
||||
![asset admin](_images/asset-admin-demo.png)
|
||||
![asset admin](/_images/asset-admin-demo.png)
|
||||
|
||||
## UploadField
|
||||
|
||||
If you have the [silverstripe/asset-admin](https://github.com/silverstripe/silverstripe-asset-admin)
|
||||
module installed then this provides a powerful component [api:SilverStripe\AssetAdmin\Forms\UploadField].
|
||||
|
||||
![upload field](_images/upload-field.png)
|
||||
![upload field](/_images/upload-field.png)
|
||||
|
||||
You can add it to a page as below:
|
||||
|
||||
@ -250,7 +253,7 @@ class Page extends SiteTree
|
||||
}
|
||||
```
|
||||
|
||||
See [Versioned: Ownership](/developer_guides/model/versioned#ownership) for details.
|
||||
See [Versioned: Ownership](/developer_guides/model/versioning#ownership) for details.
|
||||
|
||||
### Avoid exclusive relationships
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
summary: Learn how to crop and resize images in templates and PHP code
|
||||
---
|
||||
|
||||
# Image
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: File security
|
||||
summary: Manage access permission to assets
|
||||
icon: lock
|
||||
---
|
||||
|
||||
# File Security
|
||||
|
||||
@ -72,12 +76,12 @@ Most commonly this is through the "Access to Files section" permission.
|
||||
Custom implementations (e.g. APIs or custom file viewers) can have
|
||||
further restrictions in your project.
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
When implenting your own `canView()` logic through [extensions](/developer_guides/extending/extensions),
|
||||
existing unprotected files are not retroactively moved to the protected asset store.
|
||||
While those new permissions are honoured in the CMS, protected files through custom `canView()`
|
||||
can still be downloaded through a public URL until a `write()` operation is triggered on them.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Asset stores
|
||||
|
||||
@ -214,10 +218,10 @@ $object->SecretFile->protectFile();
|
||||
$object->PublicFile->publishFile();
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
One thing to note is that all variants of a single file will be treated as
|
||||
a single entity for access control, so specific variants cannot be individually controlled.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## How file access is protected
|
||||
|
||||
@ -327,11 +331,11 @@ SilverStripe\Assets\File:
|
||||
- xzip
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Any file not included in this config, or in the default list of extensions, will be blocked from
|
||||
any requests to the assets directory. Invalid files will be blocked regardless of whether they
|
||||
exist or not, and will not invoke any PHP processes.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Configuring: Protected file headers {#protected_file_headers}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: File storage
|
||||
summary: Describes the persistence layer of files
|
||||
icon: hdd
|
||||
---
|
||||
|
||||
# File storage
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: File migration
|
||||
summary: Manage migration of legacy files to the new database structure
|
||||
icon: compress-arrows-alt
|
||||
---
|
||||
|
||||
# File migration
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Files
|
||||
summary: Upload, manage and manipulate files and images.
|
||||
introduction: Upload, manage and manipulate files and images.
|
||||
icon: folder-open
|
||||
---
|
||||
|
||||
# Files
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: ModelAdmin
|
||||
summary: Create admin UI's for managing your data records.
|
||||
---
|
||||
|
||||
# ModelAdmin
|
||||
|
||||
@ -9,10 +11,10 @@ searchables list and edit views of [DataObject](api:SilverStripe\ORM\DataObject)
|
||||
It uses the framework's knowledge about the model to provide sensible defaults, allowing you to get started in a couple
|
||||
of lines of code, while still providing a solid base for customization.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
The interface is mainly powered by the [GridField](api:SilverStripe\Forms\GridField\GridField) class ([documentation](../forms/field_types/gridfield)), which can
|
||||
also be used in other areas of your application.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
Let's assume we want to manage a simple product listing as a sample data model: A product can have a name, price, and
|
||||
a category.
|
||||
@ -85,9 +87,9 @@ class MyAdmin extends ModelAdmin
|
||||
This will automatically add a new menu entry to the SilverStripe Admin UI entitled `My Product Admin` and logged in
|
||||
users will be able to upload and manage `Product` and `Category` instances through http://yoursite.com/admin/products.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
After defining these classes, make sure you have rebuilt your SilverStripe database and flushed your cache.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
## Permissions
|
||||
|
||||
@ -95,9 +97,9 @@ Each new `ModelAdmin` subclass creates its' own [permission code](../security),
|
||||
`CMS_ACCESS_MyAdmin`. Users with access to the Admin UI will need to have this permission assigned through
|
||||
`admin/security/` or have the `ADMIN` permission code in order to gain access to the controller.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
For more information on the security and permission system see the [Security Documentation](../security)
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
The [DataObject](api:SilverStripe\ORM\DataObject) API has more granular permission control, which is enforced in [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) by default.
|
||||
Available checks are `canEdit()`, `canCreate()`, `canView()` and `canDelete()`. Models check for administrator
|
||||
@ -172,9 +174,9 @@ class Product extends DataObject
|
||||
}
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
[SearchContext](../search/searchcontext) documentation has more information on providing the search functionality.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
## Displaying Results
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: CMS Architecture
|
||||
summary: An overview of the code architecture of the CMS
|
||||
icon: sitemap
|
||||
---
|
||||
# CMS Architecture
|
||||
|
||||
## Introduction
|
||||
|
@ -1,4 +1,7 @@
|
||||
---
|
||||
title: Admin Layout
|
||||
summary: Add interactivity enhancements to the admin with Javascript
|
||||
---
|
||||
|
||||
# CMS layout
|
||||
|
||||
@ -34,17 +37,17 @@ This causes the framework to:
|
||||
to the layout manager)
|
||||
* trigger `redraw` on children which also cascades deeper into the hierarchy (this is framework activity)
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Caveat: `layout` is also triggered when a DOM element is replaced with AJAX in `LeftAndMain::handleAjaxResponse`. In
|
||||
this case it is triggered on the parent of the element being replaced so jLayout has a chance to rebuild its algorithms.
|
||||
Calling the top level `layout` is not enough as it will wrongly descend down the detached element's hierarchy.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Caveat: invocation order of the `redraws` is crucial here, generally going from innermost to outermost elements. For
|
||||
example, the tab panels have be applied in the CMS form before the form itself is layouted with its sibling panels to
|
||||
avoid incorrect dimensions.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
![Layout variations](../../_images/cms-architecture.png)
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Preview
|
||||
summary: How content previews work in the CMS
|
||||
---
|
||||
|
||||
# CMS preview
|
||||
|
||||
## Overview
|
||||
@ -26,12 +31,12 @@ first segment has to match current _LeftAndMain_-derived class (e.g.
|
||||
|
||||
We use `ss.preview` entwine namespace for all preview-related entwines.
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Caveat: `SilverStripeNavigator` and `CMSPreviewable` interface currently only
|
||||
support SiteTree objects that are _Versioned_. They are not general enough for
|
||||
using on any other DataObject. That pretty much limits the extendability of the
|
||||
feature.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Configuration and Defaults
|
||||
|
||||
@ -170,13 +175,13 @@ internal states of the layout. You can reach it by calling:
|
||||
$('.cms-container').entwine('.ss').getLayoutOptions().mode;
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
Caveat: the `.preview-mode-selector` appears twice, once in the preview and
|
||||
second time in the CMS actions area as `#preview-mode-dropdown-in-cms`. This is
|
||||
done because the user should still have access to the mode selector even if
|
||||
preview is not visible. Currently CMS Actions are a separate area to the preview
|
||||
option selectors, even if they try to appear as one horizontal bar.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Preview API
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: WYSIWYG Styles
|
||||
summary: Add custom CSS properties to the rich-text editor.
|
||||
icon: text-width
|
||||
---
|
||||
|
||||
# WYSIWYG Styles
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Javascript Development
|
||||
summary: Advanced documentation about writing and customizing javascript within SilverStripe.
|
||||
iconBrand: js
|
||||
---
|
||||
|
||||
# Javascript Development
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: React, Redux, and GraphQL
|
||||
summary: Learn how to extend and customise the technologies we use for application state and client-rendered UI.
|
||||
iconBrand: react
|
||||
---
|
||||
|
||||
# Introduction to the "React" layer
|
||||
|
||||
@ -15,12 +18,12 @@ There are some several members of this ecosystem that all work together to provi
|
||||
|
||||
All of these pillars of the frontend application can be customised, giving you more control over how the admin interface looks, feels, and behaves.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
These technologies underpin the future of SilverStripe CMS development, but their current implementation is
|
||||
_experimental_. Our APIs are not expected to change drastically between releases, but they are excluded from
|
||||
our [semantic versioning](https://semver.org) commitments for the time being. Any breaking changes will be
|
||||
clearly signalled in release notes.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
First, a brief summary of what each of these are:
|
||||
|
||||
@ -241,16 +244,16 @@ Services can then be fetched using their respective `.get()` methods.
|
||||
const MyComponent = Injector.component.get('MyComponent');
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
Because of the unique structure of the `form` middleware, you cannot register new services to `Injector.form`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
Overwriting components by calling `register()` multiple times for the same
|
||||
service name is discouraged, and will throw an error. Should you really need to do this,
|
||||
you can pass `{ force: true }` as the third argument to the `register()` function.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
|
||||
## Transforming services using middleware
|
||||
@ -337,12 +340,12 @@ Injector.transform(
|
||||
{ after: '*' }
|
||||
);
|
||||
```
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
This flag can only be used once per transformation.
|
||||
The following are not allowed:
|
||||
* `{ before: ['*', 'something-else'] }`
|
||||
* `{ after: '*', before: 'something-else' }`
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
## Injector context
|
||||
|
||||
@ -598,14 +601,14 @@ API using several helper methods, including:
|
||||
* `addFieldClass(fieldName:string, cssClassName:string)`
|
||||
* `removeFieldClass(fieldName:string, cssClassName:string)`
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
For a complete list of props that are available to update on a `Field` object,
|
||||
see http://redux-form.com/6.8.0/docs/api/Field.md/#props-you-can-pass-to-field-
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
It is critical that you end series of mutation calls with `getState()`.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
In addition to mutation methods, several readonly methods are available on `FormSchemaManager` to read the current form state, including:
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: CMS alternating button
|
||||
summary: Add an "active" and "neutral" state to the CMS buttons
|
||||
---
|
||||
|
||||
# How to implement an alternating button
|
||||
|
||||
## Introduction
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: CMS form field help text
|
||||
summary: Add help text to the form fields in the CMS
|
||||
icon: question
|
||||
---
|
||||
# How to Show Help Text on CMS Form Fields
|
||||
|
||||
Sometimes you need to express more context for a form field
|
||||
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Customise the CMS Menu
|
||||
summary: Make custom changes to the left hand menu in the CMS
|
||||
---
|
||||
# How to customise the CMS Menu
|
||||
|
||||
## Adding an administration panel
|
||||
|
@ -1,3 +1,6 @@
|
||||
---
|
||||
title: Customise the CMS pages list
|
||||
---
|
||||
# Howto: Customize the Pages List in the CMS
|
||||
|
||||
The pages "list" view in the CMS is a powerful alternative to visualizing
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Customise the CMS tree
|
||||
summary: Learn how to add custom UI elements to the CMS page navigation
|
||||
icon: sitemap
|
||||
---
|
||||
|
||||
# How to customise the CMS tree
|
||||
|
||||
## Overview
|
||||
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Customising React components
|
||||
summary: Learn how to use Injector to override React-rendered form fields
|
||||
---
|
||||
# Customising React Components
|
||||
|
||||
In this tutorial, we'll customise some form elements rendered with React to have some new features.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Customising React forms
|
||||
summary: Use Injector to add customisations to React-rendered forms
|
||||
---
|
||||
|
||||
# Customising React Forms
|
||||
|
||||
Forms that are rendered with React use the [ReduxForm](http://redux-form.com) library and are based on schema definitions that come from the server. To customise these forms, you can apply middleware that updates the schema or applies validation.
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Customise site reports
|
||||
summary: Creating your own custom data or content reports.
|
||||
---
|
||||
|
||||
# Customise site reports
|
||||
|
||||
## Introduction
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Extend the CMS interface
|
||||
summary: Customise the UI of the CMS backend
|
||||
---
|
||||
|
||||
# How to extend the CMS interface
|
||||
|
||||
## Introduction
|
||||
@ -232,9 +237,9 @@ We can also easily create new drop-up menus by defining new tabs within the
|
||||
$fields->addFieldToTab('ActionMenus.MyDropUp', FormAction::create('minor', 'Minor action in a new drop-up'));
|
||||
```
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
Empty tabs will be automatically removed from the `FieldList` to prevent clutter.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
To make the actions more user-friendly you can also use alternating buttons as
|
||||
detailed in the [CMS Alternating Button](cms_alternating_button)
|
||||
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Extending an existing ModelAdmin
|
||||
summary: ModelAdmin interfaces that come with the core can be customised easily
|
||||
---
|
||||
## Extending existing ModelAdmin
|
||||
|
||||
Sometimes you'll work with ModelAdmins from other modules. To customise these interfaces, you can always subclass. But there's
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: How To's
|
||||
---
|
||||
# How To's: Customising the Admin Interface
|
||||
|
||||
[CHILDREN]
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Customising the Admin Interface
|
||||
summary: Extend the admin view to provide custom behavior or new features for CMS and admin users.
|
||||
introduction: The Admin interface can be extended to provide additional functionality to users and custom interfaces for managing data.
|
||||
iconBrand: react
|
||||
---
|
||||
|
||||
The Admin interface is bundled within the SilverStripe Framework but is most commonly used in conjunction with the `cms`
|
||||
module. The main class for displaying the interface is a specialized [Controller](api:SilverStripe\Control\Controller) called [LeftAndMain](api:SilverStripe\Admin\LeftAndMain), named
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Flushable
|
||||
summary: Allows a class to define it's own flush functionality.
|
||||
---
|
||||
|
||||
# Flushable
|
||||
|
||||
@ -10,11 +12,11 @@ Allows a class to define it's own flush functionality, which is triggered when `
|
||||
implementors of [Flushable](api:SilverStripe\Core\Flushable).
|
||||
|
||||
|
||||
<div class="notice">
|
||||
[notice]
|
||||
Flushable implementers might also be triggered automatically on deploy if you have `SS_FLUSH_ON_DEPLOY` [environment
|
||||
variable](../configuration/environment_variables) defined. In that case even if you don't manually pass `flush=1` parameter, the first request after deploy
|
||||
will still be calling `Flushable::flush` on those entities.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
|
||||
## Usage
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Manifests
|
||||
summary: Manage caches of file path maps and other expensive information
|
||||
---
|
||||
|
||||
# Manifests
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: App Object and Kernel
|
||||
summary: Provides bootstrapping and entrypoint to the SilverStripe application
|
||||
---
|
||||
|
||||
# Kernel
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Execution pipeline
|
||||
summary: An overview of the steps involved in delivering a SilverStripe web page.
|
||||
icon: route
|
||||
---
|
||||
|
||||
# Execution Pipeline
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Command Line Interface
|
||||
summary: Automate SilverStripe, run Cron Jobs or sync with other platforms through the Command Line Interface.
|
||||
introduction: Automate SilverStripe, run Cron Jobs or sync with other platforms through the Command Line Interface.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
SilverStripe can call [Controllers](../controllers) through a command line interface (CLI) just as easily as through a
|
||||
web browser. This functionality can be used to automate tasks with cron jobs, run unit tests, or anything else that
|
||||
@ -14,21 +17,21 @@ cd your-webroot/
|
||||
php vendor/silverstripe/framework/cli-script.php dev/build
|
||||
```
|
||||
|
||||
<div class="notice">
|
||||
[notice]
|
||||
Your command line php version is likely to use a different configuration as your webserver (run `php -i` to find out
|
||||
more). This can be a good thing, your CLI can be configured to use higher memory limits than you would want your website
|
||||
to have.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Sake - SilverStripe Make
|
||||
|
||||
Sake is a simple wrapper around `cli-script.php`. It also tries to detect which `php` executable to use if more than one
|
||||
are available. It is accessible via `vendor/bin/sake`.
|
||||
|
||||
<div class="info" markdown='1'>
|
||||
[info]
|
||||
If you are using a Debian server: Check you have the php-cli package installed for sake to work. If you get an error
|
||||
when running the command php -v, then you may not have php-cli installed so sake won't work.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
### Installation
|
||||
|
||||
@ -39,9 +42,9 @@ cd your-webroot/
|
||||
sudo ./vendor/bin/sake installsake
|
||||
```
|
||||
|
||||
<div class="warning">
|
||||
[warning]
|
||||
This currently only works on UNIX like systems, not on Windows.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Configuration
|
||||
|
||||
@ -74,10 +77,10 @@ sake dev/
|
||||
sake dev/build "flush=1"
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
You have to run "sake" with the same system user that runs your web server,
|
||||
otherwise "flush" won't be able to clean the cache properly.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
It can also be handy if you have a long running script..
|
||||
|
||||
@ -130,9 +133,9 @@ sake -start MyProcess
|
||||
sake -stop MyProcess
|
||||
```
|
||||
|
||||
<div class="notice">
|
||||
[notice]
|
||||
`sake` stores `pid` and log files in the site root directory.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## Arguments
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Cookies
|
||||
summary: A set of static methods for manipulating PHP cookies.
|
||||
icon: cookie-bite
|
||||
---
|
||||
|
||||
# Cookies
|
||||
## Accessing and Manipulating Cookies
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Sessions
|
||||
summary: A set of static methods for manipulating PHP sessions.
|
||||
icon: user
|
||||
---
|
||||
|
||||
# Sessions
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
---
|
||||
title: Cookies and Sessions
|
||||
summary: Save state information using the Cookie class and the Session class.
|
||||
introduction: Both the Cookie and Session classes can be used to preserve certain data across subsequent page requests.
|
||||
icon: cookie
|
||||
---
|
||||
|
||||
[CHILDREN]
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Developer Guides
|
||||
introduction: The following guides take a more detailed look into the core concepts and code examples for building SilverStripe applications.
|
||||
---
|
||||
|
||||
In each guide you'll find reference documentation followed by a collection of short and informal How-to's which contain
|
||||
snippets of code to use in your own projects.
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Upgrading to SilverStripe 4
|
||||
introduction: Upgrade your project SilverStripe 4 and keep it up to date with the latest fixes, security patches and new features.
|
||||
summary: Upgrade your project SilverStripe 4 and keep it up to date with the latest fixes, security patches and new features.
|
||||
---
|
||||
|
||||
# Upgrading a SilverStripe 3 project to SilverStripe 4
|
||||
|
||||
@ -74,9 +76,9 @@ Before you begin the upgrade process, make sure you meet these pre-requisites.
|
||||
* Backup your database content.
|
||||
* Backup your codebase (use version control if possible).
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Never update a website on the live server. Get it working on a development copy first!
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Install composer
|
||||
|
||||
@ -121,9 +123,9 @@ Each command in the upgrader has somewhat different arguments. However, most of
|
||||
* `--write` which tells the upgrader to apply changes to your code base
|
||||
* `--root-dir` which can be use to explicitly specify the root of your project. If this is not specified then the current working directory is assumed to be the root of the project.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Sample upgrader commands in this guide assume your working directory is the root of your SilverStripe project. You'll need to use the `--root-dir` flag if that's not the case.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
#### Install the upgrader globally with composer
|
||||
|
||||
@ -906,9 +908,9 @@ class ProductService
|
||||
}
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Avoid using `static::class` or `parent::class` to retrieve translated string. It will retrieve unpredictable values bases on the class inheritance.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
If your template files contain translatable strings, they also need to be updated to referenced the namespaced classes.
|
||||
For example, `<%t Member.SINGULARNAME 'Member' %>` would become `<%t SilverStripe\Security\Member.SINGULARNAME 'Member' %>`.
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Upgrading a module
|
||||
introduction: Upgrade your module to be compatible with SilverStripe 4 and make it easy for your users to upgrade.
|
||||
summary: Upgrade your module to be compatible with SilverStripe 4 and make it easy for your users to upgrade.
|
||||
---
|
||||
|
||||
# Upgrading a module to be compatible with SilverStripe 4
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Upgrading
|
||||
introduction: The following guides will help you upgrade your project or module to SilverStripe 4.
|
||||
summary: The following guides will help you upgrade your project or module to SilverStripe 4.
|
||||
---
|
||||
|
||||
The following guides will help you upgrade your project or module to SilverStripe 4. Upgrading a module is very similar to upgrading a Project. The module upgrade guide assumes familiarity with the project upgrade guide.
|
||||
|
||||
@ -64,9 +66,9 @@ Before you begin the upgrade process, make sure you meet these pre-requisites.
|
||||
* Backup your database content.
|
||||
* Backup your codebase (use version control if possible).
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Never update a website on the live server. Get it working on a development copy first!
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Install composer
|
||||
|
||||
@ -111,9 +113,9 @@ Each command in the upgrader has somewhat different arguments. However, most of
|
||||
|
||||
You can run `upgrade-code help` to get more information about the upgrader or `upgrade-code help command-name` to information about a specific command.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
Sample upgrader commands in this guide assume your working directory is the root of your SilverStripe project. You'll need to use the `--root-dir` flag if that's not the case.
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
#### Install the upgrader globally with composer
|
||||
|
||||
@ -339,7 +341,7 @@ The most typical reason for a conflict is that the maintainer of a module hasn't
|
||||
|
||||
If the maintainer of the module is in the process of upgrading to SilverStripe 4, a development version of the module might be available. In some cases, it can be worthwhile to look up the repository of the module or to reach out to the maintainer.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
If you're going to install development version of third party modules, you should consider adding the following entries to your `composer.json` file.
|
||||
|
||||
```json
|
||||
@ -350,7 +352,7 @@ If you're going to install development version of third party modules, you shoul
|
||||
// ...
|
||||
}
|
||||
```
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
To resolve a conflict you can either:
|
||||
* fork the affected module and upgrade it yourself. Don't forget to send a pull request to the original module!
|
||||
@ -359,11 +361,11 @@ To resolve a conflict you can either:
|
||||
|
||||
To integrate a third party module in your project, remove it from your `composer.json` file and from your `.gitignore` file. Then track the module's codebase in your project source control. You'll need to upgrade the module's code to be compatible with SilverStripe 4.
|
||||
|
||||
<div class="info" markdown="1">
|
||||
[info]
|
||||
If you're taking the time to upgrade a third party module, consider doing a pull request against the original project so other developers can benefit from your work or releasing your fork as a seperate module.
|
||||
|
||||
[Learn about how to publish a SilverStripe module](/developer_guides/extending/how_tos/publish_a_module)
|
||||
</div>
|
||||
[/info]
|
||||
|
||||
### Finalising your dependency upgrade
|
||||
|
||||
@ -814,6 +816,7 @@ $translation = _t(CMSMain::class .'.ACCESS', "Access to ''{title}'' section", ['
|
||||
```
|
||||
|
||||
If you're calling `_t()` to retrieve a translation for the current class, you can also use `__CLASS__` or `self::class`. For example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace App\Web\Services;
|
||||
@ -830,9 +833,9 @@ class ProductService
|
||||
}
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Avoid using `static::class` or `parent::class` to retrieve translated string. It will retrieve unpredictable values bases on the class inheritance.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
If your template files contain translatable strings, they also need to be updated to referenced the namespaced classes.
|
||||
For example, `<%t Member.SINGULARNAME 'Member' %>` would become `<%t SilverStripe\Security\Member.SINGULARNAME 'Member' %>`.
|
||||
|
@ -371,7 +371,7 @@ version generates its own manifest cache. However, if that's not the case, you m
|
||||
time with cache generation timestamp. This effectively eliminates the possibility for the manifest cache to be incompatible
|
||||
with the deployed app.
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
[alert]
|
||||
WARNING! If you do not deploy your application as a whole, but rather update its files in place with `rsync`, `ssh`
|
||||
or `FTP`, you should consider triggering CLI based `flush` manually on every such deploy (e.g. with sake).
|
||||
Otherwise, you may end up with your application cache to be incompatible with its source code, which would make things
|
||||
@ -381,7 +381,7 @@ In that case you may consider using `SS_FLUSH_ON_DEPLOY`. Depending on your depl
|
||||
that gets modified on every deploy update so that the framework will automatically perform `flush` for you.
|
||||
<br />
|
||||
The best practice is not to reuse the application manifest cache between deploys.
|
||||
</div>
|
||||
[/alert]
|
||||
|
||||
### New GridField detail form actions {#better-buttons}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Changelogs
|
||||
introduction: Key information on new features and improvements in each version.
|
||||
hideChildren: true
|
||||
---
|
||||
|
||||
Keep up to date with new releases by reading [SilverStripe Forums](https://forum.silverstripe.org/c/releases),
|
||||
and our [blog posts](http://silverstripe.org/blog/tag/release).
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Bug Reports
|
||||
summary: Report bugs or problems with SilverStripe, feature requests or other issues.
|
||||
icon: bug
|
||||
---
|
||||
|
||||
# Contributing Issues and Opinions
|
||||
|
||||
@ -38,13 +41,13 @@ problem can collaborate with you to develop a fix.
|
||||
|
||||
## Feature Requests
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
Please don't file "feature requests" as Github issues. If there's a new feature
|
||||
you'd like to see in SilverStripe, you either need to write it yourself (and
|
||||
[submit a pull request](/contributing/code/#step-by-step-from-forking-to-sending-the-pull-request) or convince somebody else to
|
||||
write it for you. Any "wishlist" type issues without code attached can be
|
||||
expected to be closed as soon as they're reviewed.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
In order to gain interest and feedback in your feature, we encourage you to
|
||||
present it to the community through the [community channels](https://www.silverstripe.org/community).
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Contributing Code
|
||||
summary: Fix bugs and add new features to help make SilverStripe better.
|
||||
icon: code
|
||||
---
|
||||
|
||||
# Contributing Code - Submitting Bugfixes and Enhancements
|
||||
|
||||
@ -14,17 +17,17 @@ For other modules, our [add-ons site](https://addons.silverstripe.org/add-ons/)
|
||||
If you are modifying CSS or JavaScript files in core modules, you'll need to regenerate some files.
|
||||
Please check out our [client-side build tooling](build_tooling) guide for details.
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
[hint]
|
||||
Note: By supplying code to the SilverStripe core team in patches, tickets and pull requests, you agree to assign copyright of that code to SilverStripe Limited, on the condition that SilverStripe Limited releases that code under the BSD license.
|
||||
|
||||
We ask for this so that the ownership in the license is clear and unambiguous, and so that community involvement doesn't stop us from being able to continue supporting these projects. By releasing this code under a permissive license, this copyright assignment won't prevent you from using the code in any way you see fit.
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
## Step-by-step: From forking to sending the pull request
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
**Note:** Please adjust the commands below to the version of SilverStripe that you're targeting.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
1. Create a [fork](https://help.github.com/articles/about-forks/) of the module you want to contribute to (listed on [github.com/silverstripe/](https://github.com/silverstripe/)).
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Build tooling
|
||||
summary: The tools we use to compile our frontend code
|
||||
icon: tools
|
||||
---
|
||||
|
||||
# Client-side build tooling
|
||||
|
||||
Core JavaScript, CSS, and thirdparty dependencies are managed with the build tooling
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Request for comment
|
||||
summary: Our approach to decision-making around impactful changes to the product
|
||||
icon: comments
|
||||
---
|
||||
|
||||
# Request for comment (RFC)
|
||||
|
||||
## Why RFCs?
|
||||
|
@ -1,4 +1,8 @@
|
||||
---
|
||||
title: Release process
|
||||
summary: Describes the process followed for "core" releases.
|
||||
iconBrand: git-alt
|
||||
---
|
||||
|
||||
# Release Process
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Making a SilverStripe core release
|
||||
summary: Development guide for core contributors to build and publish a new release
|
||||
iconBrand: github-alt
|
||||
---
|
||||
|
||||
# Making a SilverStripe core release
|
||||
|
||||
@ -99,10 +102,10 @@ exactly the same for these.
|
||||
Standard practice is to produce a pre-release for any patched modules on the security
|
||||
forks, e.g. for cms and framework (see [silverstripe-security](https://github.com/silverstripe-security)).
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
Security issues are never disclosed until a public stable release containing this fix
|
||||
is available, or within a reasonable period of time of such a release.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### When receiving a report
|
||||
|
||||
@ -203,10 +206,10 @@ Note:
|
||||
* Test you can view the satis home page at `http://localhost/satis-security/public/`
|
||||
* When performing the release ensure you use `--repository=http://localhost/satis-security/public` (below)
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
[warning]
|
||||
It's important that you re-run `satis build` step after EVERY change that is pushed upstream; E.g. between
|
||||
each release, if making multiple releases.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
### Detailed CVE and CVSS Guidance
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Documentation
|
||||
summary: Writing guide for contributing to SilverStripe developer and CMS user help documentation.
|
||||
icon: file-alt
|
||||
---
|
||||
|
||||
# Contributing documentation
|
||||
|
||||
@ -18,9 +21,9 @@ page you want to edit. Alternatively, locate the appropriate .md file in the
|
||||
* After editing the documentation, describe your changes in the "commit summary" and "extended description" fields below then press "Commit Changes".
|
||||
* After committing you changes, you will see a form to submit a Pull Request: "[pull requests](http://help.github.com/pull-requests/)". You should be able to adjust the version to which your documentation changes apply before submitting the form. Any changes submitted in a pull request will be sent to the core committers for approval.
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
You should make your changes in the lowest branch they apply to. For instance, if you fix a spelling issue that you found in the 3.2 documentation, submit your fix to that branch in Github and it'll be copied to the master (4.0) version of the documentation automatically. *Don't submit multiple pull requests*.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Editing on your computer
|
||||
|
||||
@ -30,9 +33,9 @@ If you prefer to edit content on your local machine, you can "[fork](http://help
|
||||
|
||||
The documentation is kept alongside the source code in the `docs/` subfolder of any SilverStripe module, framework or CMS folder.
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
If you submit a new feature or an API change, we strongly recommend that your patch includes updates to the necessary documentation. This helps prevent our documentation from getting out of date.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
## Repositories
|
||||
|
||||
@ -85,40 +88,40 @@ documenting, there shouldn't be any "frequently asked questions" left.
|
||||
There are several built-in block styles for highlighting a paragraph of text. Please use these graphical elements
|
||||
sparingly.
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
"Tip box": A tip box is great for adding, deepening or accenting information in the main text. They can be used for background knowledge, or to provide links to further information (ie, a "see also" link).
|
||||
</div>
|
||||
[/hint]
|
||||
|
||||
Code for a Tip box:
|
||||
|
||||
```
|
||||
<div class="hint" markdown='1'>
|
||||
[hint]
|
||||
...
|
||||
</div>
|
||||
[/hint]
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
"Notification box": A notification box is good for technical notifications relating to the main text. For example, notifying users about a deprecated feature.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
Code for a Notification box:
|
||||
|
||||
```
|
||||
<div class="notice" markdown='1'>
|
||||
[notice]
|
||||
...
|
||||
</div>
|
||||
[/notice]
|
||||
```
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
"Warning box": A warning box is useful for highlighting a severe bug or a technical issue requiring a user's attention. For example, suppose a rare edge case sometimes leads to a variable being overwritten incorrectly. A warning box can be used to alert the user to this case so they can write their own code to handle it.
|
||||
</div>
|
||||
[/warning]
|
||||
|
||||
Code for a Warning box:
|
||||
|
||||
```
|
||||
<div class="warning" markdown='1'>
|
||||
[warning]
|
||||
...
|
||||
</div>
|
||||
[/warning]
|
||||
```
|
||||
|
||||
See [markdown extra documentation](http://michelf.com/projects/php-markdown/extra/#html) for more restrictions
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Translations
|
||||
summary: Translate interface components like button labels into multiple languages.
|
||||
icon: globe
|
||||
---
|
||||
|
||||
# Contributing Translations
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Implement Internationalisation
|
||||
summary: Implement SilverStripe's internationalisation system in your own modules.
|
||||
icon: globe
|
||||
---
|
||||
|
||||
# Implementing Internationalisation
|
||||
|
||||
@ -80,9 +83,9 @@ git add lang/*
|
||||
git commit -m "Updated translations"
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
[notice]
|
||||
You can download your work right from Transifex in order to speed up the process for your desired language.
|
||||
</div>
|
||||
[/notice]
|
||||
|
||||
## JavaScript Translations
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Core committers
|
||||
summary: The team of contributors that has merge access to our open source repositories
|
||||
icon: users
|
||||
---
|
||||
|
||||
# Core Committers
|
||||
The Core Committers team is reviewed approximately annually, new members are added based on quality contributions to SilverStipe code and outstanding community participation.
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Code of conduct
|
||||
summary: How to be a high-performing, helpful member of our community
|
||||
icon: handshake
|
||||
---
|
||||
# SilverStripe community code of conduct
|
||||
|
||||
These guidelines aim to be an aspirational ideal for how we should behave when interacting in the SilverStripe developer community and to aid in building great open source software.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Coding conventions
|
||||
summary: The style guidelines we follow in all of our open source code
|
||||
icon: code
|
||||
---
|
||||
# Coding Conventions
|
||||
|
||||
* [PHP Coding Conventions](php_coding_conventions)
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: Javascript coding conventions
|
||||
summary: The Javascript style guidelines we follow in our open source software
|
||||
iconBrand: js
|
||||
---
|
||||
|
||||
# JavaScript Coding Conventions
|
||||
|
||||
## Overview
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: CSS coding conventions
|
||||
summary: The CSS style guidelines we follow in our open source software
|
||||
iconBrand: css3
|
||||
---
|
||||
# CSS and SCSS Coding Conventions
|
||||
|
||||
## Overview
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
title: PHP coding conventions
|
||||
summary: The code style guidelines we use in our open source software
|
||||
iconBrand: php
|
||||
---
|
||||
# PHP Coding Conventions
|
||||
|
||||
This document provides guidelines for code formatting and documentation
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Contributing
|
||||
introduction: Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts.
|
||||
summary: Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts.
|
||||
icon: heart
|
||||
---
|
||||
|
||||
## House rules for everybody contributing to SilverStripe
|
||||
* Read over the SilverStripe Community [Code of Conduct](code_of_conduct)
|
||||
|
Before (image error) Size: 327 KiB After (image error) Size: 327 KiB |
Before (image error) Size: 88 KiB |
Before (image error) Size: 140 KiB |
Before (image error) Size: 33 KiB |
Before (image error) Size: 109 KiB |
Before (image error) Size: 5.0 KiB |
Before (image error) Size: 4.4 KiB |
Before (image error) Size: 3.5 KiB |
Before (image error) Size: 36 KiB |
Before (image error) Size: 35 KiB |
@ -1,435 +0,0 @@
|
||||
/* Global Resetting */
|
||||
html{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:url(../images/body_bg.gif) repeat;
|
||||
}
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 62.5%;
|
||||
/* reset font-sizes to 1em == 10px */
|
||||
}
|
||||
* {
|
||||
font-size: 1em;
|
||||
/* reset font-sizes to 1em == 10px */
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family:Verdana,Helvetica,sans-serif;
|
||||
list-style:none;
|
||||
}
|
||||
a img{
|
||||
border:0;
|
||||
}
|
||||
.clear{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
/* Layout CSS */
|
||||
#Main {
|
||||
margin:20px auto;
|
||||
width:900px;
|
||||
}
|
||||
#Header {
|
||||
background:url(../images/blueback.gif) bottom left repeat-x;
|
||||
border-left:1px solid #ccc;
|
||||
border-right:1px solid #ccc;
|
||||
clear:left;
|
||||
}
|
||||
#Header h1 {
|
||||
color:#fff;
|
||||
font-size:1.5em;
|
||||
line-height:4.5em;
|
||||
padding-left:20px;
|
||||
}
|
||||
#Menu1 {
|
||||
padding:10px 50px 0;
|
||||
}
|
||||
#Menu1 li {
|
||||
float:left;
|
||||
margin-left:2px;
|
||||
background:url(../images/menu1_right.gif) no-repeat right top;
|
||||
}
|
||||
#Menu1 li.current,
|
||||
#Menu1 li.section {
|
||||
background:url(../images/menu1_right_on.gif) no-repeat right top;
|
||||
}
|
||||
#Menu1 li a {
|
||||
display:block;
|
||||
color:#fff;
|
||||
font-weight:bold;
|
||||
font-size:1.1em;
|
||||
text-decoration:none;
|
||||
padding:5px 15px;
|
||||
background:url(../images/menu1_left.gif) no-repeat left top;
|
||||
}
|
||||
#Menu1 li a:hover {
|
||||
color:#d2ebff;
|
||||
}
|
||||
#Menu1 li.current a,
|
||||
#Menu1 li.section a {
|
||||
background:url(../images/menu1_left_on.gif) no-repeat left top;
|
||||
color:#d2ebff;
|
||||
}
|
||||
|
||||
#ContentContainer {
|
||||
background:#f5f5f5 url(../images/ss_watermark.gif) bottom left no-repeat;
|
||||
padding-top:20px;
|
||||
padding-bottom:20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#Banner {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#Menu2 {
|
||||
margin-left: 20px;
|
||||
width: 17em;
|
||||
float:left;
|
||||
background:#f0f0f0;
|
||||
border:1px solid #ddd;
|
||||
padding:10px 10px 10px 10px;
|
||||
}
|
||||
#Menu2 li {
|
||||
padding-left:15px;
|
||||
background:url(../images/menu2_arrow.gif) no-repeat left center;
|
||||
}
|
||||
#Menu2 a {
|
||||
color:#333;
|
||||
font-weight:bold;
|
||||
font-size:1.1em;
|
||||
line-height:1.6em;
|
||||
text-decoration:none;
|
||||
}
|
||||
#Menu2 a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
#Menu2 li.current a,
|
||||
#Menu2 li.section a {
|
||||
color:#0083C8;
|
||||
}
|
||||
|
||||
#Content {
|
||||
float: left;
|
||||
margin: 0px 20px;
|
||||
width:70%;
|
||||
}
|
||||
|
||||
div.breadcrumbs {
|
||||
margin-bottom:10px;
|
||||
font-size:1em;
|
||||
color:#666;
|
||||
}
|
||||
div.breadcrumbs a {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#Footer {
|
||||
background:#015581;
|
||||
clear:both;
|
||||
text-align:right;
|
||||
padding-right:20px;
|
||||
border:1px solid #ccc;
|
||||
border-top:0;
|
||||
}
|
||||
#Footer span {
|
||||
color:#ccc;
|
||||
font-size:1.1em;
|
||||
line-height:2em;
|
||||
font-weight:bold;
|
||||
padding-left:20px;
|
||||
background:url(../images/ss_logo.gif) no-repeat;
|
||||
}
|
||||
#Footer a {
|
||||
color:#fff;
|
||||
}
|
||||
#Footer a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
/* The rest of this file is for the second tutorial */
|
||||
#NewsList,
|
||||
#StaffList {
|
||||
background:#f0f0f0;
|
||||
border:1px dotted #ccc;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#NewsList li,
|
||||
#StaffList li {
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
#NewsList li.newsDateTitle span {
|
||||
color:#666;
|
||||
line-height:2em;
|
||||
}
|
||||
#NewsList li.newsDateTitle a {
|
||||
font-size:1.3em;
|
||||
font-weight:bold;
|
||||
color:#0083C8;
|
||||
text-decoration:none;
|
||||
padding-left:20px;
|
||||
background:url(../images/treeicons/news-file.gif) no-repeat left center;
|
||||
}
|
||||
#NewsList li.newsDateTitle a:hover {
|
||||
border-bottom:1px dotted #0083C8;
|
||||
}
|
||||
|
||||
#NewsList li.newsSummary {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
#NewsList li.newsSummary span {
|
||||
font-size:1.1em;
|
||||
line-height:1.5em;
|
||||
color:#333;
|
||||
}
|
||||
#NewsList li.newsSummary a.readMoreLink {
|
||||
color:#0083C8;
|
||||
text-decoration:none;
|
||||
}
|
||||
#NewsList li.newsSummary a.readMoreLink:hover {
|
||||
border-bottom:1px dotted #0083C8;
|
||||
}
|
||||
|
||||
div.newsDetails {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
div.newsDetails p {
|
||||
color:#666;
|
||||
margin:0;
|
||||
font-size:1em;
|
||||
}
|
||||
|
||||
div.pageComments {
|
||||
background:#f0f0f0;
|
||||
border:1px dotted #ccc;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#StaffList .staffname {
|
||||
clear: both;
|
||||
padding-left: 60px;
|
||||
height: 1.2em;
|
||||
}
|
||||
|
||||
#StaffList .staffphoto {
|
||||
float: left;
|
||||
margin-left: 3px;
|
||||
margin-top: -1.2em;
|
||||
}
|
||||
#StaffList .staffphoto img {
|
||||
border:1px solid #AAA;
|
||||
}
|
||||
|
||||
#StaffList .staffdescription {
|
||||
margin-left: 60px;
|
||||
margin-bottom:30px;
|
||||
}
|
||||
|
||||
#StaffPhoto {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#StaffPhoto img {
|
||||
border:1px solid #AAA;
|
||||
}
|
||||
|
||||
#PageComments {
|
||||
list-style:none;
|
||||
background:#e9e9e9;
|
||||
border:1px solid #ccc;
|
||||
border-bottom:0;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
#PageComments li {
|
||||
list-style:none;
|
||||
padding:5px;
|
||||
margin:0;
|
||||
font-size:1em;
|
||||
border-bottom:1px dotted #bbb;
|
||||
}
|
||||
#PageComments li p span {
|
||||
font-style:italic;
|
||||
}
|
||||
#PageComments a.deletelink {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
|
||||
#PageNumbers {
|
||||
font-weight:bold;
|
||||
color:#333;
|
||||
font-size:1.1em;
|
||||
text-align:center;
|
||||
padding:5px;
|
||||
border:1px solid #ddd;
|
||||
background:#e9e9e9;
|
||||
}
|
||||
#PageNumbers * {
|
||||
padding:0 5px;
|
||||
line-height:1.5em;
|
||||
}
|
||||
#PageNumbers a {
|
||||
color:#0083C8;
|
||||
text-decoration:none;
|
||||
}
|
||||
#PageNumbers a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
#BrowserPoll {
|
||||
width: 200px;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
#BrowserPoll h2 {
|
||||
color:#0083C8;
|
||||
font-size:1.2em;
|
||||
}
|
||||
#BrowserPoll ul {
|
||||
margin: 0;
|
||||
}
|
||||
#BrowserPoll li {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
#BrowserPoll .browser {
|
||||
color:#333;
|
||||
line-height:1.5em;
|
||||
font-size:1.1em;
|
||||
}
|
||||
#BrowserPoll .bar {
|
||||
background-color: #015581;
|
||||
}
|
||||
#BrowserPoll form {
|
||||
width:100%;
|
||||
}
|
||||
#BrowserPoll form fieldset{
|
||||
border:0;
|
||||
}
|
||||
#BrowserPoll .message {
|
||||
color:red;
|
||||
background:#ddd;
|
||||
border:1px solid #ccc;
|
||||
padding:5px;
|
||||
margin:5px;
|
||||
}
|
||||
#BrowserPoll span.message {
|
||||
width: 100%;
|
||||
}
|
||||
#BrowserPoll form div {
|
||||
margin-top:10px;
|
||||
width:100%;
|
||||
}
|
||||
#BrowserPoll form label {
|
||||
font-size:1.1em;
|
||||
color:#333;
|
||||
}
|
||||
#BrowserPoll form label.left {
|
||||
float:left;
|
||||
}
|
||||
#BrowserPoll form label.FormHeading {
|
||||
font-size:1.3em;
|
||||
color:#ff7200;
|
||||
font-weight:bold;
|
||||
}
|
||||
#BrowserPoll form input.text,
|
||||
#BrowserPoll form textarea,
|
||||
#BrowserPoll form select {
|
||||
width:100%;
|
||||
color:#000;
|
||||
background:#f8f8f8;
|
||||
border:1px solid #aaa;
|
||||
padding:3px;
|
||||
}
|
||||
|
||||
#BrowserPoll form input.numeric {
|
||||
width:20px;
|
||||
background:#f0f0f0;
|
||||
border:1px solid #aaa;
|
||||
padding:3px;
|
||||
color:#000;
|
||||
margin-right:4px;
|
||||
}
|
||||
#BrowserPoll form input.year {
|
||||
width:35px;
|
||||
}
|
||||
#BrowserPoll form p.btn-toolbar {
|
||||
text-align:right;
|
||||
padding:0 22px 15px 0;
|
||||
}
|
||||
#BrowserPoll form p.btn-toolbar input {
|
||||
padding:2px;
|
||||
}
|
||||
#BrowserPoll form ul.optionset {
|
||||
padding-top: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
#BrowserPoll form ul.optionset li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
#Header form {
|
||||
float:right;
|
||||
width:160px;
|
||||
margin:25px 25px 0px 25px;
|
||||
}
|
||||
#Header form * {
|
||||
display:inline !important;
|
||||
}
|
||||
#Header form div {
|
||||
}
|
||||
#Header form input.text {
|
||||
width:110px;
|
||||
color:#000;
|
||||
background:#f0f0f0;
|
||||
border:1px solid #aaa;
|
||||
padding:3px;
|
||||
}
|
||||
#Header form input.action {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.searchResults h2 {
|
||||
font-size:2.2em;
|
||||
font-weight:normal;
|
||||
color:#0083C8;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
.searchResults p.searchQuery {
|
||||
color:#333;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.searchResults ul#SearchResults li {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
ul#SearchResults p {
|
||||
font-size:1.1em;
|
||||
font-weight:normal;
|
||||
line-height:2em;
|
||||
color:#333;
|
||||
}
|
||||
ul#SearchResults a.searchResultHeader {
|
||||
font-size:1.3em;
|
||||
font-weight:bold;
|
||||
color:#0083C8;
|
||||
text-decoration:none;
|
||||
margin:20px 0 8px 0;
|
||||
padding-left:20px;
|
||||
background:url(../images/treeicons/search-file.gif) no-repeat left center;
|
||||
}
|
||||
ul#SearchResults a {
|
||||
text-decoration:none;
|
||||
color:#0083C8;
|
||||
}
|
||||
ul#SearchResults a:hover {
|
||||
border-bottom:1px dotted #0083C8;
|
||||
}
|
Before (image error) Size: 37 KiB |
Before (image error) Size: 13 KiB |
Before (image error) Size: 18 KiB |
Before (image error) Size: 6.3 KiB |
Before (image error) Size: 32 KiB |
Before (image error) Size: 7.0 KiB |
Before (image error) Size: 9.2 KiB |
Before (image error) Size: 9.2 KiB |
Before (image error) Size: 65 KiB |
Before (image error) Size: 15 KiB |
Before (image error) Size: 170 B |
Before (image error) Size: 782 B |
Before (image error) Size: 50 KiB |
Before (image error) Size: 7.2 KiB |
Before (image error) Size: 173 B |
Before (image error) Size: 176 B |
Before (image error) Size: 170 B |
Before (image error) Size: 34 KiB |
Before (image error) Size: 52 KiB |
Before (image error) Size: 33 KiB |
Before (image error) Size: 21 KiB |
Before (image error) Size: 32 KiB |
Before (image error) Size: 43 KiB |
Before (image error) Size: 15 KiB |
Before (image error) Size: 21 KiB |
Before (image error) Size: 26 KiB |
Before (image error) Size: 8.7 KiB |
Before (image error) Size: 17 KiB |
Before (image error) Size: 4.7 KiB |
Before (image error) Size: 18 KiB |
Before (image error) Size: 9.8 KiB |
Before (image error) Size: 62 KiB |
Before (image error) Size: 104 KiB |
Before (image error) Size: 36 KiB |
Before (image error) Size: 60 KiB |
Before (image error) Size: 44 KiB |
Before (image error) Size: 30 KiB |
Before (image error) Size: 82 KiB |
Before (image error) Size: 83 KiB |
Before (image error) Size: 75 KiB |
Before (image error) Size: 32 KiB |
Before (image error) Size: 16 KiB |
Before (image error) Size: 120 KiB |
Before (image error) Size: 40 KiB |
Before (image error) Size: 46 KiB |
Before (image error) Size: 47 KiB |
Before (image error) Size: 26 KiB |
Before (image error) Size: 44 KiB |
Before (image error) Size: 15 KiB |
Before (image error) Size: 70 KiB |
Before (image error) Size: 37 KiB |
Before (image error) Size: 41 KiB |
Before (image error) Size: 34 KiB |
Before (image error) Size: 78 KiB |
Before (image error) Size: 32 KiB |
Before (image error) Size: 48 KiB |
Before (image error) Size: 86 KiB |
Before (image error) Size: 65 KiB |
Before (image error) Size: 47 KiB |
Before (image error) Size: 86 KiB |
Before (image error) Size: 27 KiB After (image error) Size: 27 KiB |
Before (image error) Size: 108 KiB |
Before (image error) Size: 142 KiB |
Before (image error) Size: 106 KiB |
Before (image error) Size: 101 KiB |
Before (image error) Size: 109 KiB |
Before (image error) Size: 102 KiB |
Before (image error) Size: 116 KiB |
Before (image error) Size: 154 KiB |
Before (image error) Size: 5.3 KiB |
Before (image error) Size: 4.3 KiB |
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: SilverStripe Documentation
|
||||
introduction: Welcome to the SilverStripe Developer Documentation. This website is aimed at website developers looking to learn how to build and manage web applications with the SilverStripe Framework.
|
||||
summary: Welcome to the SilverStripe Developer Documentation. This website is aimed at website developers looking to learn how to build and manage web applications with the SilverStripe Framework.
|
||||
---
|
||||
|
||||
## Getting Started with SilverStripe
|
||||
|
||||
|