mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-02 22:17:45 +00:00
Merge remote-tracking branch 'origin/issue159_page_acceuil' into testing-202401
This commit is contained in:
commit
ae6355e1e7
@ -38,8 +38,6 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font: 600 2rem/1 'Oswald', sans-serif;
|
|
||||||
text-transform: uppercase;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<li>
|
<li>
|
||||||
<h2>{{ props.item.title }}</h2>
|
<h2>{{ props.item.title }}</h2>
|
||||||
<time datetime="{{item.startDate.datetime}}">{{ $d(newsItemStartDate(), 'text') }}</time>
|
<time class="createdBy" datetime="{{item.startDate.datetime}}">{{ $d(newsItemStartDate(), 'text') }}</time>
|
||||||
<div class="content" v-if="shouldTruncate(item.content)">
|
<div class="content" v-if="shouldTruncate(item.content)">
|
||||||
<div v-html="prepareContent(item.content)"></div>
|
<div v-html="prepareContent(item.content)"></div>
|
||||||
<button class="btn btn-sm btn-show read-more" @click="() => openModal(item)">{{ $t('widget.news.readMore') }}</button>
|
<div class="float-end">
|
||||||
|
<button class="btn btn-sm btn-show read-more" @click="() => openModal(item)">{{ $t('widget.news.readMore') }}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" v-else>
|
<div class="content" v-else>
|
||||||
<div v-html="convertMarkdownToHtml(item.content)"></div>
|
<div v-html="convertMarkdownToHtml(item.content)"></div>
|
||||||
@ -16,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<p class="news-date">
|
<p class="news-date">
|
||||||
<span>{{ $d(newsItemStartDate(), 'short') }}</span>
|
<time class="createdBy" datetime="{{item.startDate.datetime}}">{{ $d(newsItemStartDate(), 'text') }}</time>
|
||||||
</p>
|
</p>
|
||||||
<div v-html="convertMarkdownToHtml(item.content)"></div>
|
<div v-html="convertMarkdownToHtml(item.content)"></div>
|
||||||
</template>
|
</template>
|
||||||
@ -30,8 +32,8 @@ import { marked } from 'marked';
|
|||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
import { DateTime, NewsItemType } from "../../../types";
|
import { DateTime, NewsItemType } from "../../../types";
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { defineProps, ref } from "vue";
|
import { ref } from "vue";
|
||||||
import {ISOToDatetime} from 'ChillMainAssets/chill/js/date';
|
import {ISOToDatetime} from '../../../chill/js/date';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -74,17 +76,13 @@ const shouldTruncate = (content: string): boolean => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const truncateContent = (content: string): string => {
|
const truncateContent = (content: string): string => {
|
||||||
console.log('max length', props.maxLength)
|
|
||||||
console.log('content', content)
|
|
||||||
let truncatedContent = content.slice(0, props.maxLength);
|
let truncatedContent = content.slice(0, props.maxLength);
|
||||||
console.log('truncated content', truncatedContent)
|
|
||||||
let linkDepth = 0;
|
let linkDepth = 0;
|
||||||
let linkStartIndex = -1;
|
let linkStartIndex = -1;
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
|
|
||||||
// Truncate if amount of lines are too many
|
// Truncate if amount of lines are too many
|
||||||
if (lines.length > props.maxLines && content.length < props.maxLength) {
|
if (lines.length > props.maxLines && content.length < props.maxLength) {
|
||||||
console.log('how many lines', lines.length)
|
|
||||||
const truncatedContent = lines.slice(0, props.maxLines).join('\n').trim();
|
const truncatedContent = lines.slice(0, props.maxLines).join('\n').trim();
|
||||||
return truncatedContent + '...';
|
return truncatedContent + '...';
|
||||||
}
|
}
|
||||||
@ -117,17 +115,33 @@ const truncateContent = (content: string): string => {
|
|||||||
truncatedContent = truncatedContent.slice(0, linkStartIndex) + `(${url})`;
|
truncatedContent = truncatedContent.slice(0, linkStartIndex) + `(${url})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('truncated content later on', truncatedContent)
|
|
||||||
|
|
||||||
truncatedContent += '...';
|
truncatedContent += '...';
|
||||||
|
|
||||||
return truncatedContent;
|
return truncatedContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const preprocess = (markdown: string): string => {
|
||||||
|
return markdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const postprocess = (html: string): string => {
|
||||||
|
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
|
||||||
|
if ('target' in node) {
|
||||||
|
node.setAttribute('target', '_blank');
|
||||||
|
node.setAttribute('rel', 'noopener noreferrer');
|
||||||
|
}
|
||||||
|
if (!node.hasAttribute('target') && (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
|
||||||
|
node.setAttribute('xlink:show', 'new');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return DOMPurify.sanitize(html);
|
||||||
|
}
|
||||||
|
|
||||||
const convertMarkdownToHtml = (markdown: string): string => {
|
const convertMarkdownToHtml = (markdown: string): string => {
|
||||||
|
marked.use({'hooks': {postprocess, preprocess}});
|
||||||
const rawHtml = marked(markdown);
|
const rawHtml = marked(markdown);
|
||||||
// console.log(rawHtml)
|
return rawHtml;
|
||||||
return DOMPurify.sanitize(rawHtml)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const prepareContent = (content: string): string => {
|
const prepareContent = (content: string): string => {
|
||||||
@ -162,36 +176,8 @@ h2 {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
padding: 5px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.read-more {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -2px;
|
|
||||||
right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news-date {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news-title {
|
.news-title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
time {
|
|
||||||
font-size: .8rem;
|
|
||||||
font-style: italic;
|
|
||||||
border-bottom: 1px dotted #333;
|
|
||||||
padding-bottom: .4rem;
|
|
||||||
margin-bottom: .5rem;
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -35,7 +35,6 @@ class NewsItemControllerTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void
|
public static function tearDownAfterClass(): void
|
||||||
@ -56,11 +55,11 @@ class NewsItemControllerTest extends WebTestCase
|
|||||||
|
|
||||||
public function generateNewsItemIds(): iterable
|
public function generateNewsItemIds(): iterable
|
||||||
{
|
{
|
||||||
/* $qb = $em->createQueryBuilder();
|
/* $qb = $em->createQueryBuilder();
|
||||||
$newsItems = $qb->select('n')->from(NewsItem::class, 'n')
|
$newsItems = $qb->select('n')->from(NewsItem::class, 'n')
|
||||||
->setMaxResults(2)
|
->setMaxResults(2)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult();*/
|
->getResult();*/
|
||||||
|
|
||||||
$this->setUp();
|
$this->setUp();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user