35

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

  • Upload
    acquia

  • View
    1.970

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Drupal 8 Every Day: An Intro to Developing With Drupal 8
Page 2: Drupal 8 Every Day: An Intro to Developing With Drupal 8

Drupal 8 Every DayAn Intro to Developing With Drupal 8

Page 3: 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

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

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

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

Unboxing

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

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 structureCore is now in ./core

Modules are now in ./modules

Profiles are now in ./profiles

Themes are now in ./themes

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

Drupal Console

Interactive console

Scaffolding

Site Management

What about Drush?

curl -LSs http://drupalconsole.com/installer | php

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

Installation

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

Site Install - site:new

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

Site Install - site:install

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

Configuration Management

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

ProductionDevelopment

Active

Storage

Active

Storage

Code Repository

Sync Storage

ImportExport

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

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

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

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

Page 15: Drupal 8 Every Day: An Intro to Developing With Drupal 8
Page 16: 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

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

Development

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

Development - Generate a Custom Module

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

Development - Generate a Page Controller

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

Development - ./photography.routing.yml

photography.gallery_controller_gallery:path: '/photography'defaults:

_controller: '\Drupal\photography\Controller\GalleryController::gallery'_title: 'Photography Gallery'

requirements:_permission: 'access content'

photography.order_form:path: '/photography/order'defaults:

_form: '\Drupal\photography\Form\OrderForm'_title: 'Photo Order Form'

requirements:_permission: 'access content'

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

Development - ./src/Controller/GalleryController.php

/*** @file* Contains Drupal\photography\Controller\GalleryController.*/namespace Drupal\photography\Controller;

use Drupal\Core\Controller\ControllerBase;

/*** Class GalleryController.** @package Drupal\photography\Controller*/class GalleryController extends ControllerBase {

/*** Helper function to load all published photographs.*/public function loadAllPhotos($bundle_type = 'photograph') {...}

/*** Gallery display.*/public function gallery() {...}

}

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

Development - Generate an Entity Bundle

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

Development - GalleryController->loadAllPhotos()

/*** Helper function to load all published photographs.** @param string $bundle_type* @return \Drupal\Core\Entity\EntityInterface[]* 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,

));

}

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

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,

];}

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

Development - ./src/Form/OrderForm.php

/*** @file* Contains Drupal\photography\Form\OrderForm.*/namespace Drupal\photography\Form;

use Drupal\Core\Form\FormBase;use Drupal\Core\Form\FormStateInterface;

/*** Class OrderForm.** @package Drupal\photography\Form*/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) {...}

}

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

Development - ./Tests/src/OrderFormTests.php

/*** @file* Contains Drupal\photography\Tests\OrderFormTest.*/namespace Drupal\photography\Tests;

use Drupal\Tests\UnitTestCase;use Drupal\photography\Form\OrderForm;

/*** 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() {...}

}

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

Theming

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

Theming with Twig - generate:theme

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

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 }}

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

{%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>

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

Twig Debug

sites/default/services.ymlparameters:

twig.config:debug: true

<!-- THEME DEBUG --><!-- THEME HOOK: 'block' --><!-- FILE NAME SUGGESTIONS:

* block--bartik-main-menu.html.twig* block--system-menu-block--main.html.twigx 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">

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

Adding CSS

portfolio.libraries.ymlglobal-styling:

version: 1.xcss:

theme:css/portfolio-global.css: {}

portfolio.info.ymllibraries:

- portfolio/global-styling

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

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!

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

Thank you

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

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