Merge pull request #1 from peptiderepo/feature/list-layout

feat: switch article display from grid to list layout
This commit is contained in:
peptiderepo
2026-04-06 18:58:58 +07:00
committed by GitHub
2 changed files with 194 additions and 48 deletions

View File

@@ -75,7 +75,7 @@ class Peptide_News_Public {
public function render_shortcode( $atts ) {
$atts = shortcode_atts( array(
'count' => get_option( 'peptide_news_articles_count', 10 ),
'layout' => 'card', // card | compact | list
'layout' => 'list', // card | compact | list
), $atts, 'peptide_news' );
$articles = $this->get_articles( absint( $atts['count'] ) );
@@ -130,13 +130,14 @@ class Peptide_News_Public {
</a>
</h3>
<p class="pn-article-excerpt">
<?php
// Prefer AI summary over raw excerpt.
$display_text = ! empty( $article->ai_summary ) ? $article->ai_summary : $article->excerpt;
echo esc_html( $display_text );
?>
</p>
<?php
// Prefer AI summary over raw excerpt.
$display_text = ! empty( $article->ai_summary ) ? $article->ai_summary : ( $article->excerpt ?? '' );
if ( ! empty( $display_text ) ) : ?>
<p class="pn-article-excerpt">
<?php echo esc_html( $display_text ); ?>
</p>
<?php endif; ?>
<?php if ( ! empty( $article->author ) ) : ?>
<span class="pn-author">

View File

@@ -4,67 +4,212 @@
* Styles for the front-end display of peptide news articles.
*
* @since 1.0.0
* @since 1.2.2 Rewritten for list layout with thumbnail left / text right.
*/
/* Article grid / card layout */
.peptide-news-container {
display: grid;
gap: 1.5rem;
/* ── Feed container ────────────────────────────────────────────── */
.pn-news-feed {
display: flex;
flex-direction: column;
gap: 0;
max-width: 900px;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.article-card {
background: #fff;
border: 1px solid #e0e0e0;
padding: 1.25rem;
.pn-no-articles p {
text-align: center;
color: #666;
padding: 2rem 1rem;
font-size: 0.9375rem;
}
/* ── Individual article row ────────────────────────────────────── */
.pn-article {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 1.25rem;
padding: 1.25rem 0;
border-bottom: 1px solid #e8e8e8;
transition: background-color 0.15s ease;
}
.pn-article:last-child {
border-bottom: none;
}
.pn-article:hover {
background-color: #fafbfc;
}
/* ── Thumbnail (left column, fixed width) ──────────────────────── */
.pn-article-thumb {
flex: 0 0 160px;
width: 160px;
min-height: 100px;
overflow: hidden;
border-radius: 6px;
transition: box-shadow 0.2s ease;
}
.article-card:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
.pn-article-thumb a {
display: block;
line-height: 0;
}
.article-title {
font-size: 1.125rem;
font-weight: 600;
color: #1a1a1a;
margin: 0 0 0.5rem;
.pn-article-thumb img {
width: 100%;
height: 110px;
object-fit: cover;
border-radius: 6px;
transition: transform 0.2s ease;
}
.pn-article:hover .pn-article-thumb img {
transform: scale(1.03);
}
/* ── Content (right column, flexible) ──────────────────────────── */
.pn-article-content {
flex: 1;
min-width: 0;
}
/* ── Meta line (source · date) ─────────────────────────────────── */
.pn-article-meta {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.8rem;
color: #777;
margin-bottom: 0.35rem;
line-height: 1.4;
}
.article-title a {
color: inherit;
text-decoration: none;
.pn-source {
font-weight: 600;
color: #555;
text-transform: uppercase;
letter-spacing: 0.025em;
font-size: 0.7rem;
}
.article-title a:hover {
.pn-separator {
color: #ccc;
}
.pn-date {
color: #888;
}
/* ── Title ─────────────────────────────────────────────────────── */
.pn-article-title {
font-size: 1.05rem;
font-weight: 600;
line-height: 1.4;
margin: 0 0 0.4rem;
color: #1a1a2e;
}
.pn-article-title a {
color: inherit;
text-decoration: none;
transition: color 0.15s ease;
}
.pn-article-title a:hover {
color: #0073aa;
}
.article-meta {
font-size: 0.8125rem;
color: #666;
margin-bottom: 0.75rem;
.pn-article-title a:focus,
.pn-article-thumb a:focus {
outline: 2px solid #0073aa;
outline-offset: 2px;
}
.article-excerpt {
font-size: 0.9375rem;
/* ── Excerpt / AI summary ──────────────────────────────────────── */
.pn-article-excerpt {
font-size: 0.875rem;
line-height: 1.6;
color: #444;
}
.article-source {
display: inline-block;
font-size: 0.75rem;
background: #f0f0f0;
padding: 0.2rem 0.5rem;
border-radius: 3px;
color: #555;
margin: 0 0 0.5rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.article-thumbnail {
width: 100%;
height: auto;
border-radius: 4px;
margin-bottom: 0.75rem;
/* ── Author ────────────────────────────────────────────────────── */
.pn-author {
display: inline-block;
font-size: 0.775rem;
color: #888;
margin-bottom: 0.35rem;
}
.pn-author::before {
content: "By ";
font-style: italic;
}
/* ── Tags ──────────────────────────────────────────────────────── */
.pn-tags {
display: flex;
flex-wrap: wrap;
gap: 0.35rem;
margin-top: 0.25rem;
}
.pn-tag {
display: inline-block;
font-size: 0.7rem;
background: #f0f4f8;
color: #4a6fa5;
padding: 0.15rem 0.55rem;
border-radius: 12px;
line-height: 1.5;
font-weight: 500;
}
/* ── Compact layout override (for widgets) ─────────────────────── */
.pn-layout-compact .pn-article {
gap: 0.85rem;
padding: 0.75rem 0;
}
.pn-layout-compact .pn-article-thumb {
flex: 0 0 80px;
width: 80px;
min-height: 56px;
}
.pn-layout-compact .pn-article-thumb img {
height: 56px;
}
.pn-layout-compact .pn-article-title {
font-size: 0.9rem;
}
.pn-layout-compact .pn-article-excerpt,
.pn-layout-compact .pn-author,
.pn-layout-compact .pn-tags {
display: none;
}
/* ── Responsive: stack on small screens ────────────────────────── */
@media (max-width: 600px) {
.pn-article {
flex-direction: column;
gap: 0.75rem;
}
.pn-article-thumb {
flex: none;
width: 100%;
}
.pn-article-thumb img {
height: 180px;
}
}