Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Unverified Commit f228bc45 authored by Francesco's avatar Francesco Committed by GitHub
Browse files

Merge pull request #68 from openeuropa/OEL-1017

OEL-1017: [oe_whitelabel] Style the news content type.
parents 71425085 3fc38c69
No related branches found
No related tags found
No related merge requests found
Showing
with 500 additions and 12 deletions
......@@ -107,4 +107,4 @@ matrix:
- lowest
- highest
PHP_VERSION:
- 7.3
- 7.4
......@@ -6,29 +6,34 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": ">=7.3",
"php": ">=7.4",
"cweagans/composer-patches": "^1.7",
"drupal/core": "^8.9 || ^9.1",
"drupal/core": "^8.9 || ^9.2",
"openeuropa/oe_bootstrap_theme": "0.1.202202072010"
},
"require-dev": {
"composer/installers": "^1.11",
"drupal/core-composer-scaffold": "^8.9 || ^9.1",
"drupal/config_devel": "~1.2",
"drupal/better_exposed_filters": "^5.0",
"drupal/config_devel": "~1.2",
"drupal/core-composer-scaffold": "^8.9 || ^9.2",
"drupal/ctools": "^3.7",
"drupal/drupal-extension": "~4.1",
"drupal/file_link": "^2.0.4",
"drupal/pathauto": "^1.8",
"drupal/search_api": "^1.21",
"drupal/search_api_autocomplete": "^1.5",
"drush/drush": "^10.3",
"openeuropa/code-review": "1.7",
"easyrdf/easyrdf": "1.0.0 as 0.9.1",
"egulias/email-validator": "^2.1.22 || ^3.0",
"openeuropa/code-review": "^1.7 || ^2.0",
"openeuropa/composer-artifacts": "~0.1",
"openeuropa/drupal-core-require-dev": "^8.9 || ^9.1",
"openeuropa/drupal-core-require-dev": "^8.9 || ^9.2",
"openeuropa/oe_authentication": "^1.4",
"openeuropa/oe_corporate_blocks": "^4.4",
"openeuropa/oe_multilingual": "^1.9",
"openeuropa/oe_starter_content": "1.x-dev",
"openeuropa/task-runner-drupal-project-symlink": "^1.0",
"phpspec/prophecy-phpunit": "^1 || ^2",
"easyrdf/easyrdf": "1.0.0 as 0.9.1",
"drupal/search_api": "^1.21",
"drupal/search_api_autocomplete": "^1.5"
"phpspec/prophecy-phpunit": "^1 || ^2"
},
"scripts": {
"post-install-cmd": "./vendor/bin/run drupal:site-setup",
......@@ -38,6 +43,10 @@
"drupal":{
"type": "composer",
"url": "https://packages.drupal.org/8"
},
"openeuropa/oe_starter_content": {
"type": "git",
"url": "https://github.com/openeuropa/oe_starter_content"
}
},
"extra": {
......@@ -56,6 +65,12 @@
"web-root": "./build"
}
},
"_readme": [
"Explicit minimum version requirement of drupal/ctools module due to D9.2 compatability.",
"Explicit requirement for drupal/file_link due to https://www.drupal.org/project/file_link/issues/3147517. It can be removed when oe_media requires version 2.0.4 or above.",
"Explicit requirement for drupal/pathauto due to D9.2 compatability according to https://www.drupal.org/node/2979476.",
"Explicit requirement for egulias/email-validator due to https://www.drupal.org/project/drupal/issues/3061074#comment-14300579. It can be removed when Drupal core 9.2 support is droppped."
],
"installer-paths": {
"build/core": [
"type:drupal-core"
......
version: '2'
services:
web:
image: fpfis/httpd-php-dev:7.3
image: fpfis/httpd-php-dev:7.4
working_dir: /var/www/html
ports:
- 8080:8080
......
# OpenEuropa Whitelabel News
\ No newline at end of file
langcode: en
status: true
dependencies: { }
id: oe_whitelabel_news_date
label: 'OE Whitelabel News date'
locked: false
pattern: 'd F Y'
langcode: en
status: true
dependencies:
config:
- field.field.node.oe_news.body
- field.field.node.oe_news.oe_featured_media
- field.field.node.oe_news.oe_publication_date
- field.field.node.oe_news.oe_summary
- node.type.oe_news
module:
- datetime
- text
- user
id: node.oe_news.full
targetEntityType: node
bundle: oe_news
mode: full
content:
body:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 12
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
oe_featured_media:
type: entity_reference_entity_view
label: hidden
settings:
view_mode: default
link: false
third_party_settings: { }
weight: 10
region: content
oe_publication_date:
type: datetime_default
label: hidden
settings:
timezone_override: ''
format_type: oe_whitelabel_news_date
third_party_settings: { }
weight: 13
region: content
oe_summary:
type: basic_string
label: hidden
settings: { }
third_party_settings: { }
weight: 11
region: content
hidden:
langcode: true
search_api_excerpt: true
langcode: en
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
- field.field.node.oe_news.body
- field.field.node.oe_news.oe_featured_media
- field.field.node.oe_news.oe_publication_date
- field.field.node.oe_news.oe_summary
- node.type.oe_news
module:
- datetime
- text
- user
id: node.oe_news.teaser
targetEntityType: node
bundle: oe_news
mode: teaser
content:
body:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 12
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
oe_featured_media:
type: entity_reference_entity_view
label: hidden
settings:
view_mode: default
link: false
third_party_settings: { }
weight: 10
region: content
oe_publication_date:
type: datetime_default
label: hidden
settings:
timezone_override: ''
format_type: oe_whitelabel_news_date
third_party_settings: { }
weight: 13
region: content
oe_summary:
type: basic_string
label: hidden
settings: { }
third_party_settings: { }
weight: 11
region: content
hidden:
langcode: true
search_api_excerpt: true
name: OpenEuropa Whitelabel News
type: module
description: Companion module to OE News providing styling to nodes.
package: OpenEuropa Whitelabel Theme
core_version_requirement: ^8.9 || ^9.2
dependencies:
- oe_whitelabel:oe_whitelabel_helper
- oe_starter_content:oe_starter_content_news
config_devel:
install:
- core.date_format.oel_whitelabel_news_date.yml
- core.entity_view_display.node.oe_news.full.yml
- core.entity_view_display.node.oe_news.teaser.yml
<?php
/**
* @file
* OE Whitelabel theme News.
*/
declare(strict_types = 1);
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\media\MediaInterface;
use Drupal\media\Plugin\media\Source\Image;
use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalPhotoSource;
use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
/**
* Implements template_preprocess_node() for the News node type.
*/
function oe_whitelabel_news_preprocess_node__oe_news(&$variables) {
if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
return;
}
/** @var \Drupal\node\NodeInterface $node */
$node = $variables['node'];
// Bail out if there is no media present.
if ($node->get('oe_featured_media')->isEmpty()) {
return;
}
/** @var \Drupal\media\Entity\Media $media */
$media = $node->get('oe_featured_media')->entity;
if (!$media instanceof MediaInterface) {
// The media entity is not available anymore, bail out.
return;
}
// Retrieve the correct media translation.
/** @var \Drupal\media\Entity\Media $media */
$media = \Drupal::service('entity.repository')->getTranslationFromContext($media, $node->language()->getId());
// Caches are handled by the formatter usually. Since we are not rendering
// the original render arrays, we need to propagate our caches to the
// paragraph template.
$cacheability = CacheableMetadata::createFromRenderArray($variables);
$cacheability->addCacheableDependency($media);
// Run access checks on the media entity.
$access = $media->access('view', $variables['user'], TRUE);
$cacheability->addCacheableDependency($access);
if (!$access->isAllowed()) {
$cacheability->applyTo($variables);
return;
}
// Get the media source.
$source = $media->getSource();
$is_image = $source instanceof MediaAvPortalPhotoSource || $source instanceof Image;
// If it's not an image and not a video, bail out.
if (!$is_image) {
$cacheability->applyTo($variables);
return;
}
$thumbnail = $media->get('thumbnail')->first();
$variables['image'] = ImageValueObject::fromImageItem($thumbnail);
if ($variables['view_mode'] == 'teaser') {
$variables['image'] = ['#markup' => $variables['image']->getSource()];
}
$cacheability->applyTo($variables);
}
{#
/**
* @file
* Theme override for field oe-publication-date.
*/
#}
{% if label_hidden %}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% else %}
{{ label }}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% endif %}
\ No newline at end of file
{#
/**
* @file
* News full display.
*/
#}
<article{{attributes}}>
{{ pattern('content_banner', {
background: 'gray',
title: label,
content: content.oe_summary,
image: image,
meta: [
content.oe_publication_date,
]
}) }}
<div class="container mt-md-4-75 mt-4">
<div class="row">
<div class="col-12 col-lg-10 col-xl-9 col-xxl-8 mb-4">
{{ content.body }}
</div>
</div>
</div>
</article>
{#
/**
* @file
* Search result template.
*/
#}
{% set _title %}
<a class="text-underline-hover" href="{{ url }}">{{ label }}</a>
{% endset %}
{% set _content %}
<span class="text-muted text-nowrap me-4-5">{{ content.oe_publication_date }}</span>
{% endset %}
<article{{attributes}}>
{{ pattern('card', {
variant: 'search',
title: _title,
text: content.oe_summary,
image: image,
content: _content
}) }}
</article>
<?php
declare(strict_types = 1);
namespace Drupal\Tests\oe_whitelabel\Functional;
use Symfony\Component\DomCrawler\Crawler;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
use Drupal\media\Entity\Media;
use Drupal\file\Entity\File;
use Drupal\Tests\TestFileCreationTrait;
/**
* Tests that the News content type renders correctly.
*/
class ContentNewsRenderTest extends WhitelabelBrowserTestBase {
use MediaTypeCreationTrait;
use TestFileCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'oe_whitelabel_news',
];
/**
* A node to be rendered in different display views.
*
* @var \Drupal\node\NodeInterface
*/
protected $node;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Create a sample image media entity to be embedded.
File::create([
'uri' => $this->getTestFiles('image')[0]->uri,
])->save();
$media_image = Media::create([
'bundle' => 'image',
'name' => 'Starter Image test',
'oe_media_image' => [
[
'target_id' => 1,
'alt' => 'Starter Image test alt',
'title' => 'Starter Image test title',
],
],
]);
$media_image->save();
// Create a News node.
/** @var \Drupal\node\Entity\Node $node */
$node = \Drupal::entityTypeManager()
->getStorage('node')
->create([
'type' => 'oe_news',
'title' => 'Test news node',
'oe_summary' => 'http://www.example.org is a web page',
'body' => 'News body',
'oe_publication_date' => [
'value' => '2022-02-09T20:00:00',
],
'uid' => 1,
'status' => 1,
]);
$node->set('oe_featured_media', [$media_image]);
$node->save();
$this->node = $node;
}
/**
* Tests that the News page renders correctly in full display.
*/
public function testNewsRenderingFull(): void {
// Build node full view.
$builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$build = $builder->view($this->node, 'full');
$render = $this->container->get('renderer')->renderRoot($build);
$crawler = new Crawler((string) $render);
// Assert content banner title.
$content_banner = $crawler->filter('.bcl-content-banner');
$this->assertEquals(
'Test news node',
trim($content_banner->filter('.card-title')->text())
);
// Assert content banner image.
$image = $content_banner->filter('img');
$this->assertCount(1, $image);
$this->assertCount(1, $image->filter('.card-img-top'));
$this->assertStringContainsString(
'image-test.png',
trim($image->attr('src'))
);
$this->assertEquals('Starter Image test alt',
$image->attr('alt')
);
// Assert content banner publication date.
$this->assertEquals(
'10 February 2022',
trim($content_banner->filter('.card-body > div.my-4')->text())
);
// Assert content banner summary.
$this->assertEquals(
'http://www.example.org is a web page',
trim($content_banner->filter('.oe-news__oe-summary')->text())
);
// Assert the news content.
$this->assertEquals(
'News body',
trim($crawler->filter('.oe-news__body')->text())
);
}
/**
* Tests that the News page renders correctly in teaser display.
*/
public function testNewsRenderingTeaser(): void {
// Build node teaser view.
$builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$build = $builder->view($this->node, 'teaser');
$render = $this->container->get('renderer')->renderRoot($build);
$crawler = new Crawler((string) $render);
// Assert content banner title.
$this->assertEquals(
'Test news node',
trim($crawler->filter('h5.card-title')->text())
);
// Assert content banner image.
$image = $crawler->filter('img');
$this->assertCount(1, $image);
$this->assertCount(1, $image->filter('.card-img-top'));
$this->assertStringContainsString(
'image-test.png',
trim($image->attr('src'))
);
// Assert content banner content.
$this->assertEquals(
'http://www.example.org is a web page',
trim($crawler->filter('p.card-text')->text())
);
// Assert content banner publication date.
$this->assertEquals(
'10 February 2022',
trim($crawler->filter('div.card-body > span.text-muted')->text())
);
}
}
<?php
declare(strict_types = 1);
namespace Drupal\Tests\oe_whitelabel\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Base class for testing content types.
*/
abstract class WhitelabelBrowserTestBase extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Enable and set OpenEuropa Theme as default.
\Drupal::service('theme_installer')->install(['oe_whitelabel']);
\Drupal::configFactory()
->getEditable('system.theme')
->set('default', 'oe_whitelabel')
->save();
// Rebuild the ui_pattern definitions to collect the ones provided by
// oe_whitelabel itself.
\Drupal::service('plugin.manager.ui_patterns')->clearCachedDefinitions();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment