This commit is contained in:
2026-04-06 10:40:29 +02:00
parent 6d4edce0bd
commit dcfd03e9ac
11 changed files with 447 additions and 1 deletions

View File

@@ -168,6 +168,25 @@ class BlogPost extends ObjectModel
);
}
/**
* Pobiera najnowsze aktywne wpisy (bez paginacji) do sekcji homepage.
*/
public static function getLatest($idLang, $limit = 3)
{
$limit = max(1, (int) $limit);
return Db::getInstance()->executeS(
'SELECT p.`id_post`, p.`thumbnail`, p.`date_add`,
pl.`title`, pl.`intro`, pl.`link_rewrite`
FROM `' . _DB_PREFIX_ . 'projectproblog_post` p
LEFT JOIN `' . _DB_PREFIX_ . 'projectproblog_post_lang` pl
ON p.`id_post` = pl.`id_post` AND pl.`id_lang` = ' . (int) $idLang . '
WHERE p.`active` = 1
ORDER BY p.`date_add` DESC
LIMIT ' . (int) $limit
);
}
/**
* Liczba wpisów (do paginacji).
*/

View File

@@ -49,7 +49,8 @@ class Projectproblog extends Module
return parent::install()
&& $this->installSql()
&& $this->installTabs()
&& $this->registerHook('moduleRoutes');
&& $this->registerHook('moduleRoutes')
&& $this->registerHook('displayHome');
}
protected function createImgDir()
@@ -195,6 +196,8 @@ class Projectproblog extends Module
public function hookModuleRoutes()
{
$this->ensureDisplayHomeHookRegistration();
return [
'module-projectproblog-list' => [
'controller' => 'list',
@@ -236,6 +239,21 @@ class Projectproblog extends Module
];
}
/**
* Zapewnia podpiecie hooka displayHome takze dla istniejacych instalacji.
*/
protected function ensureDisplayHomeHookRegistration()
{
$idHook = (int) Hook::getIdByName('displayHome');
if ($idHook <= 0) {
return;
}
if (!$this->isRegisteredInHook('displayHome')) {
$this->registerHook('displayHome');
}
}
/* ------------------------------------------------------------------ */
/* HELPERS — generowanie linków */
/* ------------------------------------------------------------------ */
@@ -266,4 +284,43 @@ class Projectproblog extends Module
$idLang
);
}
/* ------------------------------------------------------------------ */
/* HOMEPAGE HOOK */
/* ------------------------------------------------------------------ */
public function hookDisplayHome()
{
$idLang = (int) $this->context->language->id;
$posts = BlogPost::getLatest($idLang, 3);
if (empty($posts)) {
return '';
}
$base = $this->context->link->getBaseLink();
foreach ($posts as &$post) {
$post['thumbnail_url'] = $post['thumbnail']
? $base . 'modules/projectproblog/views/img/posts/' . $post['thumbnail']
: null;
$post['url'] = self::getPostUrl($post['link_rewrite'], $idLang);
}
unset($post);
if (isset($this->context->controller)) {
$this->context->controller->registerStylesheet(
'module-projectproblog-blog',
'modules/projectproblog/views/css/blog.css',
['media' => 'all', 'priority' => 200]
);
}
$this->context->smarty->assign([
'blog_home_title' => $this->l('Najnowsze na blogu'),
'blog_home_posts' => $posts,
'blog_url' => self::getBlogUrl($idLang),
]);
return $this->display(__FILE__, 'views/templates/hook/home.tpl');
}
}

View File

@@ -530,3 +530,60 @@
color: var(--blog-accent-dk);
text-decoration: underline;
}
/* ---- Homepage: zajawki bloga -------------------------------- */
#blog-home {
margin-top: 2.25rem;
margin-bottom: 2.5rem;
}
.blog-home__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
margin-bottom: 1rem;
}
.blog-home__title {
margin: 0;
font-size: 1.5rem;
font-weight: 700;
color: var(--blog-text);
line-height: 1.25;
}
.blog-home__all {
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--blog-accent);
text-decoration: none;
}
.blog-home__all:hover {
color: var(--blog-accent-dk);
text-decoration: underline;
}
.blog-grid--home .blog-grid-item--home {
width: 33.3333%;
}
@media (max-width: 991px) {
.blog-grid--home .blog-grid-item--home {
width: 50%;
}
}
@media (max-width: 575px) {
.blog-home__header {
flex-direction: column;
align-items: flex-start;
}
.blog-grid--home .blog-grid-item--home {
width: 100%;
}
}

View File

@@ -0,0 +1,50 @@
{**
* Project-Pro Blog - sekcja zajawkowa na homepage
*}
{if $blog_home_posts}
<section id="blog-home" class="container">
<div class="blog-home__header">
<h2 class="blog-home__title">{$blog_home_title|escape:'html':'UTF-8'}</h2>
<a class="blog-home__all" href="{$blog_url|escape:'html':'UTF-8'}">
{l s='Zobacz wszystkie wpisy' mod='projectproblog'}
</a>
</div>
<div class="blog-grid blog-grid--home">
{foreach from=$blog_home_posts item=post}
<div class="blog-grid-item blog-grid-item--home">
<article class="blog-card">
{if $post.thumbnail_url}
<a href="{$post.url|escape:'html':'UTF-8'}" class="blog-card__thumb">
<img src="{$post.thumbnail_url|escape:'html':'UTF-8'}"
alt="{$post.title|escape:'html':'UTF-8'}"
loading="lazy">
</a>
{/if}
<div class="blog-card__body">
<h3 class="blog-card__title">
<a href="{$post.url|escape:'html':'UTF-8'}">
{$post.title|escape:'html':'UTF-8'}
</a>
</h3>
{if $post.intro}
<div class="blog-card__intro">
{$post.intro|strip_tags|truncate:150:'...'}
</div>
{/if}
<div class="blog-card__footer">
<span class="blog-card__date">{$post.date_add|date_format:'%d.%m.%Y'}</span>
<a href="{$post.url|escape:'html':'UTF-8'}" class="blog-card__more">
{l s='Czytaj wiecej' mod='projectproblog'} &rsaquo;
</a>
</div>
</div>
</article>
</div>
{/foreach}
</div>
</section>
{/if}

View File

@@ -0,0 +1,4 @@
<?php
/**
* Silence is golden.
*/