SlideShare a Scribd company logo
Drupal 8 Every Day: An Intro to Developing With Drupal 8
Drupal 8 Every Day
An Intro to Developing With Drupal 8
Erin Marchak
● Acquia Certified Front End Specialist, and Developer
● dgo.to/@emarchak
Geoff Appleby
● Acquia Certified Developer
● dgo.to/@gapple
● Persistent Login & drupalreleasedate.com
1. Unboxing
2. Installation
3. Configuration Management
a. Development Workflow
b. Export
c. Import
4. Development
a. Module Generation
b. Page Controllers
c. Entity Bundles
d. Forms
5. Theming
a. Theme Generation
b. Twig Syntax
c. Debugging
d. Including Assets
Unboxing
Unboxing Drupal 8
New Features
Configuration Management
Twig replaces PHPTemplate
PHPUnit supplements SimpleTest
Responsive base theme & admin
Fast by Default
New modules in core
Requirements
Minimum
PHP 5.5.9
MySQL 5.5.3
Recommended
PHP 5.6.5
APCu
New file structure
Core is now in ./core
Modules are now in ./modules
Profiles are now in ./profiles
Themes are now in ./themes
Drupal Console
Interactive console
Scaffolding
Site Management
What about Drush?
curl -LSs http://drupalconsole.com/installer | php
Installation
Site Install - site:new
Site Install - site:install
Configuration Management
ProductionDevelopment
Active
Storage
Active
Storage
Code Repository
Sync Storage
ImportExport
Configuration Management
Move database settings to settings.local.php
Uncomment include() statement
Set config sync directory in settings.php
$config_directories[CONFIG_SYNC_DIRECTORY] = __DIR__ . '/config';
cp example.gitignore .gitignore
git add -f sites/default/settings.php
mkdir sites/default/config
Configuration Management - Export
Console creates an archive of YML files
drupal config:export
Drush outputs YML files directly to the sync directory
drush config-export
Drupal 8 Every Day: An Intro to Developing With Drupal 8
Configuration Management - Import
Console imports an archive of YML files
drupal config:import [file name]
Drush imports YML files directly from the sync directory
drush config-import
Development
Development - Generate a Custom Module
Development - Generate a Page Controller
Development - ./photography.routing.yml
photography.gallery_controller_gallery:
path: '/photography'
defaults:
_controller: 'DrupalphotographyControllerGalleryController::gallery'
_title: 'Photography Gallery'
requirements:
_permission: 'access content'
photography.order_form:
path: '/photography/order'
defaults:
_form: 'DrupalphotographyFormOrderForm'
_title: 'Photo Order Form'
requirements:
_permission: 'access content'
Development - ./src/Controller/GalleryController.php
/**
* @file
* Contains DrupalphotographyControllerGalleryController.
*/
namespace DrupalphotographyController;
use DrupalCoreControllerControllerBase;
/**
* Class GalleryController.
*
* @package DrupalphotographyController
*/
class GalleryController extends ControllerBase {
/**
* Helper function to load all published photographs.
*/
public function loadAllPhotos($bundle_type = 'photograph') {...}
/**
* Gallery display.
*/
public function gallery() {...}
}
Development - Generate an Entity Bundle
Development - GalleryController->loadAllPhotos()
/**
* Helper function to load all published photographs.
*
* @param string $bundle_type
* @return DrupalCoreEntityEntityInterface[]
* Array of node objects keyed by nid.
*/
public function loadAllPhotos($bundle_type = 'photograph') {
// Return the entity manager service and load the the storage instance for nodes.
// That way we have access to the enity api while keeping our controller lean.
$storage = $this->entityManager()->getStorage('node');
// loadByProperties() allows us to query and load entities in one line!
return $storage->loadByProperties(array(
'type' => $bundle_type,
'status' => 1,
));
}
Development - GalleryController->gallery()
/**
* Gallery display.
*/
public function gallery() {
$langcode = $this->languageManager()->getCurrentLanguage('language');
$photographs = $this->loadAllPhotos();
$view_mode = 'teaser';
$gallery = array();
// Loop through the loaded photograph node objects and output their rendered result into a list.
$viewBuilder = $this->entityManager->getViewBuilder('node');
foreach ($photographs as $photograph) {
$gallery[] = $viewBuilder->view($photograph, $view_mode);
}
// If the gallery is empty, we should apologise.
if (empty($gallery)) {...}
// Return an item list of photographs for our gallery.
return [
'#theme' => 'item_list',
'#items' => $gallery,
];
}
Development - ./src/Form/OrderForm.php
/**
* @file
* Contains DrupalphotographyFormOrderForm.
*/
namespace DrupalphotographyForm;
use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
/**
* Class OrderForm.
*
* @package DrupalphotographyForm
*/
class OrderForm extends FormBase {
public function getFormId() {...}
public function buildForm(array $form, FormStateInterface $form_state) {...}
protected function validPostalCode(string $postal_code) {...}
public function validateForm(array &$form, FormStateInterface $form_state) {...}
public function submitForm(array &$form, FormStateInterface $form_state) {...}
}
Development - ./Tests/src/OrderFormTests.php
/**
* @file
* Contains DrupalphotographyTestsOrderFormTest.
*/
namespace DrupalphotographyTests;
use DrupalTestsUnitTestCase;
use DrupalphotographyFormOrderForm;
/**
* Tests validation of postal codes.
*
* @group photography
*/
class OrderFormTest extends UnitTestCase {
...
/**
* Test valid postal codes.
*/
public function testPostalCodeValid() {...}
/**
* Test invalid postal codes.
*/
public function testPostalCodeInvalid() {...}
Theming
Theming with Twig - generate:theme
Twig Syntax
PHPTemplate Twig
<?php print $variable ?> {{ variable }}
<?php if (condition): ?> {% if condition %}
<?php foreach ($users as $user):
?>
{% for user in users %}
<?php print t(“string”) ?> {{ “string”|t }}
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
node.isPromoted() ? 'node--promoted',
node.isSticky() ? 'node--sticky',
not node.isPublished() ? 'node--unpublished',
view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
]
%}
{{ attach_library('classy/node') }}
<article{{ attributes.addClass(classes) }}>
{{ title_prefix }}
{% if not page %}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
<div{{ content_attributes.addClass('node__content') }}>
{{ content }}
</div>
</article>
Twig Debug
sites/default/services.yml
parameters:
twig.config:
debug: true
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
* block--bartik-main-menu.html.twig
* block--system-menu-block--main.html.twig
x block--system-menu-block.html.twig
* block--system.html.twig
* block.html.twig
-->
<!-- BEGIN OUTPUT from 'core/themes/bartik/templates/block--system-menu-block.html.twig' -->
<nav role="navigation"
aria-labelledby="block-bartik-main-menu-menu"
id="block-bartik-main-menu"
class="contextual-region block block-menu navigation menu--main">
Adding CSS
portfolio.libraries.yml
global-styling:
version: 1.x
css:
theme:
css/portfolio-global.css: {}
portfolio.info.yml
libraries:
- portfolio/global-styling
Questions or Comments? We’d love to hear from you!
twitter.com/emarchak
twitter.com/gappleca
twitter.com/myplanetHQ
We can also help with your Drupal projects.
We know how to nudge the big wigs to give D8 a chance.
Extra pair of hands to plug in and help out.
That’s all, folks!
Thank you
Resources
Github Repository https://github.com/gapple/drupal-8-every-day
Database Dump https://drive.google.com/file/d/0B-PTT5Vfuw18RTdId2poQUFNR1E/view
Drupal Console https://www.drupal.org/project/console
Theming Guide https://www.drupal.org/theme-guide/8
CMI Documentation https://www.drupal.org/documentation/administer/config

More Related Content

PPTX
Laravel5 Introduction and essentials
PPT
Learn Dashing Widget in 90 minutes
PDF
Laravel 101
PPTX
Laravel Beginners Tutorial 1
PDF
Drupal 8 - Corso frontend development
ODP
Presentation laravel 5 4
PPTX
Laravel Beginners Tutorial 2
PPTX
Laravel5 Introduction and essentials
Learn Dashing Widget in 90 minutes
Laravel 101
Laravel Beginners Tutorial 1
Drupal 8 - Corso frontend development
Presentation laravel 5 4
Laravel Beginners Tutorial 2

What's hot (20)

PPTX
Laravel 5
PPTX
Workshop Laravel 5.2
PPTX
Laravel for Web Artisans
PPTX
10 Laravel packages everyone should know
PDF
Always up to date, testable and maintainable documentation with OpenAPI
PPTX
PDF
Laravel 5 In Depth
PPTX
Introduction to Laravel Framework (5.2)
PDF
Laravel presentation
PDF
Why Laravel?
PDF
Adventures in Laravel 5 SunshinePHP 2016 Tutorial
PPTX
Becoming A Drupal Master Builder
PDF
Laravel Design Patterns
PDF
Top laravel packages to install handpicked list from expert
PDF
Getting to know Laravel 5
PDF
Drupal 8 Services And Dependency Injection
PDF
What's New In Laravel 5
PDF
Bootstrat REST APIs with Laravel 5
PDF
Unit testing after Zend Framework 1.8
PDF
Introduction to CakePHP
Laravel 5
Workshop Laravel 5.2
Laravel for Web Artisans
10 Laravel packages everyone should know
Always up to date, testable and maintainable documentation with OpenAPI
Laravel 5 In Depth
Introduction to Laravel Framework (5.2)
Laravel presentation
Why Laravel?
Adventures in Laravel 5 SunshinePHP 2016 Tutorial
Becoming A Drupal Master Builder
Laravel Design Patterns
Top laravel packages to install handpicked list from expert
Getting to know Laravel 5
Drupal 8 Services And Dependency Injection
What's New In Laravel 5
Bootstrat REST APIs with Laravel 5
Unit testing after Zend Framework 1.8
Introduction to CakePHP
Ad

Similar to Drupal 8 Every Day: An Intro to Developing With Drupal 8 (20)

PDF
Drupal 8 - Core and API Changes
PPTX
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
PPTX
Migrate yourself. code -> module -> mind
PPTX
Drupal Camp Porto - Developing with Drupal: First Steps
PDF
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
PDF
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
PDF
Efficient development workflows with composer
PDF
Drupal8 for Symfony Developers (PHP Day Verona 2017)
PDF
Drupal8 simplepage v2
PDF
Web automation with #d8rules (European Drupal Days 2015)
PDF
Advanced moduledevelopment d6_slideshare
PDF
Drupal8 for Symfony developers - Dutch PHP
PDF
Drupal 8: A story of growing up and getting off the island
PDF
Staging Drupal 8 31 09 1 3
PDF
Drupal Flyover, CMS Expo
ZIP
Drupal Development
ODP
Migrations
PDF
Modernize Your Drupal Development
PDF
Lviv 2013 d7 vs d8
PDF
Symfony and Drupal 8
Drupal 8 - Core and API Changes
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Migrate yourself. code -> module -> mind
Drupal Camp Porto - Developing with Drupal: First Steps
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Efficient development workflows with composer
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 simplepage v2
Web automation with #d8rules (European Drupal Days 2015)
Advanced moduledevelopment d6_slideshare
Drupal8 for Symfony developers - Dutch PHP
Drupal 8: A story of growing up and getting off the island
Staging Drupal 8 31 09 1 3
Drupal Flyover, CMS Expo
Drupal Development
Migrations
Modernize Your Drupal Development
Lviv 2013 d7 vs d8
Symfony and Drupal 8
Ad

More from Acquia (20)

PDF
Acquia_Adcetera Webinar_Marketing Automation.pdf
PDF
Acquia Webinar Deck - 9_13 .pdf
PDF
Taking Your Multi-Site Management at Scale to the Next Level
PDF
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
PDF
May Partner Bootcamp 2022
PDF
April Partner Bootcamp 2022
PDF
How to Unify Brand Experience: A Hootsuite Story
PDF
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
PDF
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
PDF
September Partner Bootcamp
PDF
August partner bootcamp
PDF
July 2021 Partner Bootcamp
PDF
May Partner Bootcamp
PDF
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
PDF
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
PDF
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
PDF
April partner bootcamp deck cookieless future
PDF
How to enhance cx through personalised, automated solutions
PDF
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
PDF
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021
Acquia_Adcetera Webinar_Marketing Automation.pdf
Acquia Webinar Deck - 9_13 .pdf
Taking Your Multi-Site Management at Scale to the Next Level
CDP for Retail Webinar with Appnovation - Q2 2022.pdf
May Partner Bootcamp 2022
April Partner Bootcamp 2022
How to Unify Brand Experience: A Hootsuite Story
Using Personas to Guide DAM Results: How Life Time Pumped Up Their UX and CX
Improve Code Quality and Time to Market: 100% Cloud-Based Development Workflow
September Partner Bootcamp
August partner bootcamp
July 2021 Partner Bootcamp
May Partner Bootcamp
DRUPAL 7 END OF LIFE IS NEAR - MIGRATE TO DRUPAL 9 FAST AND EASY
Work While You Sleep: The CMO’s Guide to a 24/7/365 Lead Machine
Acquia webinar: Leveraging Drupal to Bury Your Sales Team In B2B Leads
April partner bootcamp deck cookieless future
How to enhance cx through personalised, automated solutions
DRUPAL MIGRATIONS AND DRUPAL 9 INNOVATION: HOW PAC-12 DELIVERED DIGITALLY FOR...
Customer Experience (CX): 3 Key Factors Shaping CX Redesign in 2021

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
cuic standard and advanced reporting.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Encapsulation theory and applications.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Machine learning based COVID-19 study performance prediction
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Electronic commerce courselecture one. Pdf
PPTX
sap open course for s4hana steps from ECC to s4
DOCX
The AUB Centre for AI in Media Proposal.docx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
cuic standard and advanced reporting.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Encapsulation theory and applications.pdf
Encapsulation_ Review paper, used for researhc scholars
Advanced methodologies resolving dimensionality complications for autism neur...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Diabetes mellitus diagnosis method based random forest with bat algorithm
Mobile App Security Testing_ A Comprehensive Guide.pdf
Spectral efficient network and resource selection model in 5G networks
Machine learning based COVID-19 study performance prediction
The Rise and Fall of 3GPP – Time for a Sabbatical?
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Electronic commerce courselecture one. Pdf
sap open course for s4hana steps from ECC to s4
The AUB Centre for AI in Media Proposal.docx

Drupal 8 Every Day: An Intro to Developing With Drupal 8

  • 2. Drupal 8 Every Day An Intro to Developing With Drupal 8
  • 3. Erin Marchak ● Acquia Certified Front End Specialist, and Developer ● dgo.to/@emarchak Geoff Appleby ● Acquia Certified Developer ● dgo.to/@gapple ● Persistent Login & drupalreleasedate.com
  • 4. 1. Unboxing 2. Installation 3. Configuration Management a. Development Workflow b. Export c. Import 4. Development a. Module Generation b. Page Controllers c. Entity Bundles d. Forms 5. Theming a. Theme Generation b. Twig Syntax c. Debugging d. Including Assets
  • 6. Unboxing Drupal 8 New Features Configuration Management Twig replaces PHPTemplate PHPUnit supplements SimpleTest Responsive base theme & admin Fast by Default New modules in core Requirements Minimum PHP 5.5.9 MySQL 5.5.3 Recommended PHP 5.6.5 APCu New file structure Core is now in ./core Modules are now in ./modules Profiles are now in ./profiles Themes are now in ./themes
  • 7. Drupal Console Interactive console Scaffolding Site Management What about Drush? curl -LSs http://drupalconsole.com/installer | php
  • 9. Site Install - site:new
  • 10. Site Install - site:install
  • 13. Configuration Management Move database settings to settings.local.php Uncomment include() statement Set config sync directory in settings.php $config_directories[CONFIG_SYNC_DIRECTORY] = __DIR__ . '/config'; cp example.gitignore .gitignore git add -f sites/default/settings.php mkdir sites/default/config
  • 14. Configuration Management - Export Console creates an archive of YML files drupal config:export Drush outputs YML files directly to the sync directory drush config-export
  • 16. Configuration Management - Import Console imports an archive of YML files drupal config:import [file name] Drush imports YML files directly from the sync directory drush config-import
  • 18. Development - Generate a Custom Module
  • 19. Development - Generate a Page Controller
  • 20. Development - ./photography.routing.yml photography.gallery_controller_gallery: path: '/photography' defaults: _controller: 'DrupalphotographyControllerGalleryController::gallery' _title: 'Photography Gallery' requirements: _permission: 'access content' photography.order_form: path: '/photography/order' defaults: _form: 'DrupalphotographyFormOrderForm' _title: 'Photo Order Form' requirements: _permission: 'access content'
  • 21. Development - ./src/Controller/GalleryController.php /** * @file * Contains DrupalphotographyControllerGalleryController. */ namespace DrupalphotographyController; use DrupalCoreControllerControllerBase; /** * Class GalleryController. * * @package DrupalphotographyController */ class GalleryController extends ControllerBase { /** * Helper function to load all published photographs. */ public function loadAllPhotos($bundle_type = 'photograph') {...} /** * Gallery display. */ public function gallery() {...} }
  • 22. Development - Generate an Entity Bundle
  • 23. Development - GalleryController->loadAllPhotos() /** * Helper function to load all published photographs. * * @param string $bundle_type * @return DrupalCoreEntityEntityInterface[] * Array of node objects keyed by nid. */ public function loadAllPhotos($bundle_type = 'photograph') { // Return the entity manager service and load the the storage instance for nodes. // That way we have access to the enity api while keeping our controller lean. $storage = $this->entityManager()->getStorage('node'); // loadByProperties() allows us to query and load entities in one line! return $storage->loadByProperties(array( 'type' => $bundle_type, 'status' => 1, )); }
  • 24. Development - GalleryController->gallery() /** * Gallery display. */ public function gallery() { $langcode = $this->languageManager()->getCurrentLanguage('language'); $photographs = $this->loadAllPhotos(); $view_mode = 'teaser'; $gallery = array(); // Loop through the loaded photograph node objects and output their rendered result into a list. $viewBuilder = $this->entityManager->getViewBuilder('node'); foreach ($photographs as $photograph) { $gallery[] = $viewBuilder->view($photograph, $view_mode); } // If the gallery is empty, we should apologise. if (empty($gallery)) {...} // Return an item list of photographs for our gallery. return [ '#theme' => 'item_list', '#items' => $gallery, ]; }
  • 25. Development - ./src/Form/OrderForm.php /** * @file * Contains DrupalphotographyFormOrderForm. */ namespace DrupalphotographyForm; use DrupalCoreFormFormBase; use DrupalCoreFormFormStateInterface; /** * Class OrderForm. * * @package DrupalphotographyForm */ class OrderForm extends FormBase { public function getFormId() {...} public function buildForm(array $form, FormStateInterface $form_state) {...} protected function validPostalCode(string $postal_code) {...} public function validateForm(array &$form, FormStateInterface $form_state) {...} public function submitForm(array &$form, FormStateInterface $form_state) {...} }
  • 26. Development - ./Tests/src/OrderFormTests.php /** * @file * Contains DrupalphotographyTestsOrderFormTest. */ namespace DrupalphotographyTests; use DrupalTestsUnitTestCase; use DrupalphotographyFormOrderForm; /** * Tests validation of postal codes. * * @group photography */ class OrderFormTest extends UnitTestCase { ... /** * Test valid postal codes. */ public function testPostalCodeValid() {...} /** * Test invalid postal codes. */ public function testPostalCodeInvalid() {...}
  • 28. Theming with Twig - generate:theme
  • 29. Twig Syntax PHPTemplate Twig <?php print $variable ?> {{ variable }} <?php if (condition): ?> {% if condition %} <?php foreach ($users as $user): ?> {% for user in users %} <?php print t(“string”) ?> {{ “string”|t }}
  • 30. {% set classes = [ 'node', 'node--type-' ~ node.bundle|clean_class, node.isPromoted() ? 'node--promoted', node.isSticky() ? 'node--sticky', not node.isPublished() ? 'node--unpublished', view_mode ? 'node--view-mode-' ~ view_mode|clean_class, ] %} {{ attach_library('classy/node') }} <article{{ attributes.addClass(classes) }}> {{ title_prefix }} {% if not page %} <h2{{ title_attributes }}> <a href="{{ url }}" rel="bookmark">{{ label }}</a> </h2> {% endif %} {{ title_suffix }} <div{{ content_attributes.addClass('node__content') }}> {{ content }} </div> </article>
  • 31. Twig Debug sites/default/services.yml parameters: twig.config: debug: true <!-- THEME DEBUG --> <!-- THEME HOOK: 'block' --> <!-- FILE NAME SUGGESTIONS: * block--bartik-main-menu.html.twig * block--system-menu-block--main.html.twig x block--system-menu-block.html.twig * block--system.html.twig * block.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/bartik/templates/block--system-menu-block.html.twig' --> <nav role="navigation" aria-labelledby="block-bartik-main-menu-menu" id="block-bartik-main-menu" class="contextual-region block block-menu navigation menu--main">
  • 33. Questions or Comments? We’d love to hear from you! twitter.com/emarchak twitter.com/gappleca twitter.com/myplanetHQ We can also help with your Drupal projects. We know how to nudge the big wigs to give D8 a chance. Extra pair of hands to plug in and help out. That’s all, folks!
  • 35. Resources Github Repository https://github.com/gapple/drupal-8-every-day Database Dump https://drive.google.com/file/d/0B-PTT5Vfuw18RTdId2poQUFNR1E/view Drupal Console https://www.drupal.org/project/console Theming Guide https://www.drupal.org/theme-guide/8 CMI Documentation https://www.drupal.org/documentation/administer/config

Editor's Notes

  • #4: Mention Geoff’s modules! persistent login!
  • #5: Before we jump into it, we’re going to take a quick poll. At your company, are you guys planning on hopping on to D8? a) Yup, we’re planning on or are currently developing a D8 site b) Yes, we’re planning on or are currently migrating an existing site to D8 c) Nope not yet d) Enter your own response (Blank field)
  • #7: Twig: no php in templates, autoescape output Fast by Default: Improved caching (cache tags), Page Caching on by default, uses APCu when available (ChainedFastCache) New Modules: Views, field types, breakpoint + picture This new file structure adds simplicity for new developers. We’re no longer pointing people into a rabbit hole of files to get started developing. (/sites/all/modules and /sites/default/modules still work, and override /modules) PHP 5.5 still receives security fixes, but is the oldest supported version (7 will be out soon, with big performance improvements) APCu is automatically used for some caching when available A note to MAMP developers: versions prior to MAMP 3 don’t come with the minimum PHP version. Either expect to spend the time to roll your own, or upgrade.
  • #8: Drupal Console’s main functionality is assisting in development by generating snippets. Built on Symfony Console components, only supports D8 Compared to drush: No remote management (yet) Module / extension support may be better for drush Collaborating with drush to improve both projects
  • #11: Most of the console of the prompts have autocompletes and defaults, so it’s quite quick to get through the progress.
  • #12: Before we jump into it, we’re going to take a quick poll. Which CMS(s) is your company currently on? a) Drupal b) Other open-souce (Wordpress, Joomla etc.) c) A proprietary or in-house platform d) Enter your own response (Blank field)
  • #13: Active storage is in the database Changes made in UI are applied to active store By default the sync directory is within the site’s files directory; should be set to a version-controlled location Previously called “Staging”; may still be used in some older documentation Import/Export are all or nothing operations, replacing config in target location Merge tools are being improved Admin page allows comparing differences before import to active storage Sites can’t yet be setup directly from config files; database has to be synced between environments initially.
  • #14: Keep site specific or security conscious code out of settings.php (e.g. database config) site install creates a config directory with random name in files; want to replace with folder tracked in version control yml files are protected from public visibility by the web server
  • #15: Drush offers simplest workflow for now, by storing YML to sync directory
  • #19: drupal generate:module drupal console can generate module scaffolding quickly and efficiently. stuff that was previously done through the GUI can be performed entirely in the command line. it even allows you to include a composer.json file if you’re dependant on external libraries in your module. YAML: info, menu
  • #20: Create page controller If you wanted to load services (language manager, entity manager, entity query, etc.) you could pre-load them during the generation. I found, however that ControllerBase already had everything. drupalize.me’s Amber Matz said, “check your pantry to see if [you] already have it” before you start adding dependencies. A good IDE really helps inspecting your available methods and properties. console only generates simpletests right now, so unit tests will have to be included by hand (we’ll get into that later.)
  • #21: If your route needs a menu item, that needs to be defined separately in module_name.links.menu.yml defaults for routes can be: controller, form, entity view (finds entity in path and renders it), entity list (returns a list of entities) and entity form (edit for for entites) If you have a parameter in your path that you identity as the entity type (e.g. {node}), you can pre-load it in the controller. Route access can be permission or role defined, you can control the method (get/post) you can also control if the output is in json, html or both just from the routing.
  • #22: This is the contents of the controller. All of the structure was pre-generated except for loadAllPhotos() Namespace reflects the file location within the src directory. No dependency injection, no services, no complex construction. Since we’ll be loading the photos, we’ll need to create a content type.
  • #23: drupal config:export:content:type [content] --module=[module] generate basic bundles through drupal console, field configuration through the UI (it may change!)
  • #24: entity manager is available in the base Controller class already. Updated entity api allows us to quickly query and load entites. No need for multiple loops in custom code. Check the pantry before you shop!
  • #25: this is the action method that we defined in our router. language manager is available in the base Controller class already. getViewBuilder() creates an entity handler instance for your specific entity type. consistent entity handlers mean that entities will behave consistently, no need to know multiple process just to render two types of entities More things are entities in d8 (blocks, comments, nodes, users, taxonomies, etc.) render array stays the same.
  • #26: While the form is still a FAPI array, the form state is stored in a FormStateInterface object reading, creating and manipulating form data has become much easier. Type hinting is encouraged and expected in your methods. New HTML5 field widgets (url, tel, email, color, etc.), HTML5 input types (date, email, range, color, etc.), and HTML5 input attributes (placeholder, min, max, autocomplete, etc.). HTML5 form elements (progressbar) are en route No private methods because of the desire to keep things visible. Keeping something protected means that no one else can change up the values on the object arbitrarily. Given how extensible drupal is, they've chosen to keep all functions public or protected to allow developers to edit their code/output. This is not in the coding standard, but comes from discussions with core developers. The use of public properties is strongly discouraged, as it allows for unwanted side effects. It also exposes implementation-specific details, which in turn makes swapping out a class for another implementation (one of the key reasons to use objects) much harder. Properties should be considered internal to a class. Protected properties and methods should not use an underscore prefix.
  • #27: Running tests on my custom postal code validation function, since submit and validation unit tests already are covered. You must run PHPUnit from the /core directory PHPUnit can only find tests in ./Tests/src/Unit/*, whose class ends with “Test” and methods start with “test”. Examples of this test can be found in our code repository.
  • #28: Before we jump into it, we’re going to take a quick poll. 3. What is your biggest challenge to working with or adopting Drupal 8? a) Unported modules b) Switching to object orientated c) Bureaucracy from the big wigs d) Enter your own response (Blank field)
  • #29: like modules, the *.info now changed to *.info.yml *.theme instead of template.php Base Themes: Stable & Classy Stable provides basic HTML markup for complete control in a sub-theme Classy (the default) provides classic drupal wrapper classes (though much improved)
  • #30: Common components of a template are easily converted. Can output any object that can be converted to a string understands render arrays as well, so no need to call render() on children
  • #31: More control over output given to template files: templates are the norm, functions discouraged (Theme functions only used in performance sensitive areas) classes defined in templates instead of preprocess functions Arbitrary PHP is not allowed, but still many tools available Setting and manipulating variables Attributes is an object; methods are available
  • #32: Adds comments to show possible template file names, marks template in use, and provides full path to template file (helps differentiate between parent / child theme files) {{ dump() }} available to see all variables accessible within template
  • #33: {} allows defining a media property for each file Adding to *.info.yml will apply site-wide Can also be added within a twig template with {{ attach_library('theme/library') }}, or during preprocess phase using #attached property of render array element jQuery is not included by default, so must declare dependency in library definition. drupalSettings is also only included when necessary Inline Javascript no longer available through #attached / libraries Themes can place in template files Modules should convert to JS file; dynamic components should use drupalSettings