Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Craft 3

Intro to Craft 3

A look at the new features coming in Craft CMS 3

Brandon Kelly

April 26, 2017
Tweet

More Decks by Brandon Kelly

Other Decks in Technology

Transcript

  1. 1. Security & Performance

    View full-size slide

  2. Modern Tech Stack
    — PHP 7
    — Yii 2
    — Guzzle 6
    — Twig 2
    — OpenSSL

    View full-size slide

  3. Average time (milliseconds)
    taken to load the Happy Lager
    homepage over 100 requests

    View full-size slide

  4. Seconds taken to load 5,000
    entries at once

    View full-size slide

  5. Memory (MB) consumed when
    loading 5,000 entries at once

    View full-size slide

  6. Craft is now a Composer
    dependency right alongside other
    project dependencies.

    View full-size slide

  7. Craft is now a Composer
    dependency right alongside other
    project dependencies.
    > composer require \
    craftcms/cms:^3.0.0-beta.1

    View full-size slide

  8. There’s also a Composer project
    you can use as a starting point.
    > composer create-project \
    craftcms/craft \
    my_project \
    --stability beta

    View full-size slide

  9. The default project structure has changed a bit.
    Old New
    craft/app/ vendor/craftcms/cms/
    craft/config/ config/
    craft/storage/ storage/
    craft/templates/ templates/
    public/ web/

    View full-size slide

  10. Craft is on GitHub.

    View full-size slide

  11. Craft is on GitHub.

    View full-size slide

  12. Live on the bleeding edge.
    > composer require \
    craftcms/cms:"dev-develop as 3.0.0-beta.99"

    View full-size slide

  13. 3. Multi-Site

    View full-size slide

  14. Sites are like locales, except…
    — you give them a custom name and handle
    — they have language, but they are not defined by it
    — multiple sites can share the same language
    — fields can be translated per-site, per-language,
    or even something custom

    View full-size slide

  15. When should you use Multi-Site?
    ! "
    Multi-lingual sites Different orgs
    Sister sites No shared content
    Landing pages

    View full-size slide

  16. 4. Internationalization

    View full-size slide

  17. Internationalization improvements in Craft 3:
    — Craft uses the Intl extension when available.
    — Fallback data for all the locales is available at
    github.com/craftcms/locales
    — Support for PostgreSQL !
    — Translation categories

    View full-size slide

  18. Image Editor

    View full-size slide

  19. Image Editor

    View full-size slide

  20. Volumes
    — Asset Sources are called “Volumes” now
    — Plugins can supply custom volume types
    — User photos are stored as assets now, and you
    choose which volume

    View full-size slide

  21. 6. Utilities

    View full-size slide

  22. 6. Utilities

    View full-size slide

  23. 6. Utilities

    View full-size slide

  24. 6. Utilities

    View full-size slide

  25. 6. Utilities

    View full-size slide

  26. 6. Utilities

    View full-size slide

  27. 6. Utilities

    View full-size slide

  28. 6. Utilities

    View full-size slide

  29. 6. Utilities

    View full-size slide

  30. 6. Utilities

    View full-size slide

  31. 7. Content Migrations

    View full-size slide

  32. Craft can now manage migrations that are specific to
    your project.
    > ./craft migrate/create create_new_field

    View full-size slide

  33. Content migrations are stored in
    a migrations/ folder within your
    Craft project.

    View full-size slide

  34. use craft\db\Migration;
    use craft\fields\PlainText;
    class m170331_030925_create_new_field extends Migration
    {
    public function safeUp()
    {
    $field = new PlainText();
    $field->groupId = 1;
    $field->name = 'Address';
    $field->handle = 'address';
    $field->multiline = true;
    \Craft::$app->fields->saveField($field);
    }
    }

    View full-size slide

  35. Content migrations have access to the full set of Craft
    APIs, so you can do whatever you want in them.

    View full-size slide

  36. 8. Templating

    View full-size slide

  37. Element Queries

    View full-size slide

  38. ElementQuery is the new ElementCriteriaModel.

    View full-size slide

  39. ElementQuery is the new ElementCriteriaModel.
    Still works the same, for the most part.
    {% set entries = craft.entries()
    .section('news')
    .limit(10) %}

    View full-size slide

  40. ElementQuery is the new ElementCriteriaModel.
    Still works the same, for the most part.
    {% set entries = craft.entries()
    .section('news')
    .limit(10) %}
    But way, way more powerful.

    View full-size slide

  41. A few functions have changed.
    Old New
    find() all()
    first() one()
    order() orderBy()
    total() count()

    View full-size slide

  42. Lots of new functions have been introduced.
    Name Purpose
    select(columns) override the SELECT
    addSelect(columns) add more columns to the
    SELECT

    View full-size slide

  43. Lots of new functions have been introduced.
    Name Purpose
    where(condition) override the WHERE
    andWhere(condition) add an AND condition to the
    WHERE
    orWhere(condition) add an OR condition to the
    WHERE

    View full-size slide

  44. Lots of new functions have been introduced.
    Name Purpose
    innerJoin(table) add an INNER JOIN
    leftJoin(table) add a LEFT JOIN
    rightJoin(table) add a RIGHT JOIN

    View full-size slide

  45. Lots of new functions have been introduced.
    Name Purpose
    asArray() return raw data arrays
    rather than Element
    models
    indexBy(column) indexes returned values by
    a column’s value

    View full-size slide

  46. Lots of new functions have been introduced.
    Name Returns
    column() first column’s values
    pairs() key/value pairs
    scalar() first value of first column
    exists() if there are any results

    View full-size slide

  47. Lots of new functions have been introduced.
    Name Returns
    sum(column) sum value
    average(column) average value
    min(column) smallest value
    max(column) largest value

    View full-size slide

  48. Lots of new functions have been introduced.
    Name Returns
    batch(size) lazy-loaded batched
    results
    each(size) iterator for all results, but
    lazy-loaded in batches
    behind the scenes

    View full-size slide

  49. Example: get entries, indexed by their IDs
    {% set entriesById = craft.entries()
    .section('news')
    .indexBy('elements.id')
    .all() %}

    View full-size slide

  50. Example: get entry titles, indexed by their IDs
    {% set titlesById = craft.entries()
    .section('news')
    .select('elements.id, content.title')
    .pairs() %}

    View full-size slide

  51. Example: get the average value for a custom field
    {% set averageAge = craft.users()
    .andWhere('field_age is not null')
    .average('field_age') %}

    View full-size slide

  52. Example: load users in lazy-loaded batches
    {% for user in craft.users().each() %}
    {{ user.name }}
    {% endfor %}

    View full-size slide

  53. You can output the raw SQL query to be executed:
    {% set q = craft.entries().section('news') %}
    {{ q.getRawSql() }}

    View full-size slide

  54. You can output the raw SQL query to be executed:
    {% set q = craft.entries().section('news') %}
    {{ q.getRawSql() }}
    Output:
    SELECT `elements`.`id`,
    `elements`.`fieldLayoutId`,
    `elements`.`uid`, ...

    View full-size slide

  55. Templates can access Craft’s application instance
    anywhere with craft.app.

    View full-size slide

  56. Example: access a config value
    {% if craft.app.config.general.devMode %}
    Craft is running in Dev Mode!
    {% endif %}

    View full-size slide

  57. Example: loop through all the sections
    {% set sections = craft.app
    .sections.getAllSections() %}
    {% for section in sections %}
    {{ section.name }}
    {% endfor %}

    View full-size slide

  58. 9. Debug Toolbar

    View full-size slide

  59. 10. Configuration

    View full-size slide

  60. Define environment-specific variables in a .env file that
    doesn’t get committed to Git.
    DB_SERVER="localhost"
    DB_USER="homestead"
    DB_PASSWORD="secret"
    DB_DATABASE="happylager"

    View full-size slide

  61. Ways to define environment-specific settings:
    — Per-environment configs
    — PHP dotenv environment variables
    — environmentVariables

    View full-size slide

  62. Ways to define environment-specific settings:
    — Per-environment configs
    — PHP dotenv environment variables
    — environmentVariables

    View full-size slide

  63. Site URLs can be defined per-environment using
    the siteUrl config setting in config/general.php.
    return [
    '*' => [],
    '.dev' => [
    'siteUrl' => 'http://site.dev',
    ],
    '.com' => [
    'siteUrl' => '//site.com',
    ],
    ],
    ];

    View full-size slide

  64. Volume settings can be overridden in
    config/volumes.php.
    return [
    'userPhotos' => [
    'path' => getenv('PHOTOS_PATH'),
    'url' => getenv('PHOTOS_URL'),
    ],
    ];

    View full-size slide

  65. All plugin settings can be overridden with config
    files now.

    View full-size slide

  66. You can set default Guzzle settings from
    config/guzzle.php.

    View full-size slide

  67. return [
    'headers' => ['Foo' => 'Bar'],
    'query' => ['testing' => '123'],
    'auth' => ['username', 'password'],
    'proxy' => 'tcp://localhost:80'
    ];

    View full-size slide

  68. You can override Craft’s core application configuration
    with config/app.php.

    View full-size slide

  69. return [
    'components' => [
    'mailer' => function() {
    $settings = Craft::$app->systemSettings->emailSettings;
    $settings->transportType = MailgunAdapter::class;
    $settings->transportSettings = [
    'domain' => 'foo.com',
    'apiKey' => 'key-xxxxxxxxxx',
    ];
    return MailerHelper::createMailer($settings);
    }
    ],
    ];

    View full-size slide

  70. Recap
    1. Security & Performance
    2. Composer
    3. Multi-Site
    4. Internationalization
    5. Assets
    6. Utilities
    7. Content Migrations
    8. Templating
    9. Debug Toolbar
    10. Configuration

    View full-size slide