temaplte fixes in app and in plugin
This commit is contained in:
@@ -257,12 +257,16 @@ class WordPressAdapter(BaseAdapter):
|
||||
featured_image_url = image_url
|
||||
logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️ Featured image: {image_url[:80]}...")
|
||||
elif image.image_type == 'in_article' and image_url:
|
||||
is_featured = False # In-article images are never featured
|
||||
gallery_images.append({
|
||||
'url': image_url,
|
||||
'alt': getattr(image, 'alt', '') or '',
|
||||
'caption': getattr(image, 'caption', '') or ''
|
||||
'caption': getattr(image, 'caption', '') or '',
|
||||
'prompt': getattr(image, 'prompt', '') or '',
|
||||
'position': getattr(image, 'position', 0),
|
||||
'is_featured': is_featured
|
||||
})
|
||||
logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️ Gallery image {len(gallery_images)}")
|
||||
logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️ Gallery image {len(gallery_images)} (pos={getattr(image, 'position', 0)}, prompt={bool(getattr(image, 'prompt', ''))})")
|
||||
except Exception as e:
|
||||
logger.warning(f"[WordPressAdapter._publish_via_api_key] ⚠️ Could not load images: {e}")
|
||||
|
||||
|
||||
@@ -785,7 +785,7 @@ UNFOLD = {
|
||||
{"title": "System AI Settings", "icon": "tune", "link": lambda request: "/admin/system/systemaisettings/"},
|
||||
{"title": "AI Models", "icon": "model_training", "link": lambda request: "/admin/billing/aimodelconfig/"},
|
||||
{"title": "Credit Costs by Function", "icon": "calculate", "link": lambda request: "/admin/billing/creditcostconfig/"},
|
||||
{"title": "Account-Specific AI Settings", "icon": "account_circle", "link": lambda request: "/admin/system/aisettings/"},
|
||||
{"title": "Billing Configuration", "icon": "payments", "link": lambda request: "/admin/billing/billingconfiguration/"},
|
||||
{"title": "AI Task Logs", "icon": "history", "link": lambda request: "/admin/ai/aitasklog/"},
|
||||
],
|
||||
},
|
||||
@@ -814,7 +814,6 @@ UNFOLD = {
|
||||
{"title": "Module Settings", "icon": "view_module", "link": lambda request: "/admin/system/globalmodulesettings/"},
|
||||
{"title": "Author Profiles", "icon": "person_outline", "link": lambda request: "/admin/system/globalauthorprofile/"},
|
||||
{"title": "Strategies", "icon": "strategy", "link": lambda request: "/admin/system/globalstrategy/"},
|
||||
{"title": "Billing Configuration", "icon": "payments", "link": lambda request: "/admin/billing/billingconfiguration/"},
|
||||
],
|
||||
},
|
||||
# System Configuration
|
||||
@@ -823,8 +822,7 @@ UNFOLD = {
|
||||
"icon": "tune",
|
||||
"collapsible": True,
|
||||
"items": [
|
||||
{"title": "System Settings", "icon": "settings", "link": lambda request: "/admin/system/systemsettings/"},
|
||||
{"title": "Account Settings", "icon": "account_circle", "link": lambda request: "/admin/system/accountsettings/"},
|
||||
{"title": "Account Settings (All Settings)", "icon": "account_circle", "link": lambda request: "/admin/system/accountsettings/"},
|
||||
{"title": "User Settings", "icon": "person_search", "link": lambda request: "/admin/system/usersettings/"},
|
||||
{"title": "Module Settings", "icon": "view_module", "link": lambda request: "/admin/system/modulesettings/"},
|
||||
],
|
||||
|
||||
@@ -458,34 +458,70 @@ const ContentSectionBlock = ({
|
||||
|
||||
{/* Content layout with images */}
|
||||
<div className="flex flex-col gap-10">
|
||||
{/* Content before H3 */}
|
||||
{beforeH3 && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: beforeH3 }} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Image section - layout depends on aspect ratio and alignment */}
|
||||
{hasImage && (
|
||||
<div className="flex justify-center">
|
||||
<div className={getImageContainerClass()}>
|
||||
{/* Square images (left/right aligned) - content and image in same row */}
|
||||
{aspectRatio === 'square' && (imageAlign === 'left' || imageAlign === 'right') && hasImage ? (
|
||||
<div className={`flex ${imageAlign === 'right' ? 'flex-row' : 'flex-row-reverse'} gap-8 items-start`}>
|
||||
{/* Image side (48% width) */}
|
||||
<div className="w-[48%] flex-shrink-0">
|
||||
<SectionImageBlock image={image} loading={loading} heading={headingLabel} showPrompt={showDescription} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* H3 and remaining content */}
|
||||
{h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: h3AndAfter }} />
|
||||
</div>
|
||||
)}
|
||||
{/* Content side (48% width with auto remaining) */}
|
||||
<div className="flex-1">
|
||||
{/* Content before H3 */}
|
||||
{beforeH3 && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: beforeH3 }} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Fallback if no H3 structure found */}
|
||||
{!beforeH3 && !h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: section.bodyHtml }} />
|
||||
{/* H3 and remaining content */}
|
||||
{h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: h3AndAfter }} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Fallback if no H3 structure found */}
|
||||
{!beforeH3 && !h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: section.bodyHtml }} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Content before H3 */}
|
||||
{beforeH3 && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: beforeH3 }} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Landscape image - full width centered */}
|
||||
{hasImage && aspectRatio === 'landscape' && (
|
||||
<div className="flex justify-center">
|
||||
<div className={getImageContainerClass()}>
|
||||
<SectionImageBlock image={image} loading={loading} heading={headingLabel} showPrompt={showDescription} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* H3 and remaining content */}
|
||||
{h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: h3AndAfter }} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Fallback if no H3 structure found */}
|
||||
{!beforeH3 && !h3AndAfter && (
|
||||
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
|
||||
<div dangerouslySetInnerHTML={{ __html: section.bodyHtml }} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: IGNY8 WordPress Bridge
|
||||
* Plugin URI: https://igny8.com/igny8-wp-bridge
|
||||
* Description: Lightweight bridge plugin that connects WordPress to IGNY8 API for one-way content publishing.
|
||||
* Version: 1.2.6
|
||||
* Version: 1.2.7
|
||||
* Author: IGNY8
|
||||
* Author URI: https://igny8.com/
|
||||
* License: GPL v2 or later
|
||||
@@ -22,7 +22,7 @@ if (!defined('ABSPATH')) {
|
||||
}
|
||||
|
||||
// Define plugin constants
|
||||
define('IGNY8_BRIDGE_VERSION', '1.2.6');
|
||||
define('IGNY8_BRIDGE_VERSION', '1.2.7');
|
||||
define('IGNY8_BRIDGE_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('IGNY8_BRIDGE_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('IGNY8_BRIDGE_PLUGIN_FILE', __FILE__);
|
||||
|
||||
@@ -208,6 +208,8 @@ function igny8_parse_keywords($keywords) {
|
||||
* @return array Array of badges with 'text' and 'type' keys
|
||||
*/
|
||||
function igny8_get_section_badges($heading, $post_id) {
|
||||
static $used_keywords = [];
|
||||
|
||||
$badges = [];
|
||||
$heading_lower = strtolower($heading);
|
||||
|
||||
@@ -217,39 +219,44 @@ function igny8_get_section_badges($heading, $post_id) {
|
||||
$primary_kw = get_post_meta($post_id, '_igny8_primary_keyword', true);
|
||||
$secondary_kws = get_post_meta($post_id, '_igny8_secondary_keywords', true);
|
||||
|
||||
// Priority 1: Primary keyword
|
||||
if ($primary_kw && stripos($heading_lower, strtolower($primary_kw)) !== false) {
|
||||
// Priority 1: Primary keyword (if not used)
|
||||
if ($primary_kw && !in_array(strtolower($primary_kw), $used_keywords) && stripos($heading_lower, strtolower($primary_kw)) !== false) {
|
||||
$badges[] = ['text' => $primary_kw, 'type' => 'primary'];
|
||||
$used_keywords[] = strtolower($primary_kw);
|
||||
return $badges; // Return only 1 badge
|
||||
}
|
||||
|
||||
// Priority 2: Tags
|
||||
if ($tags && !is_wp_error($tags) && count($badges) < 2) {
|
||||
// Priority 2: Tags (if not used)
|
||||
if ($tags && !is_wp_error($tags)) {
|
||||
foreach ($tags as $tag) {
|
||||
if (stripos($heading_lower, strtolower($tag->name)) !== false) {
|
||||
if (!in_array(strtolower($tag->name), $used_keywords) && stripos($heading_lower, strtolower($tag->name)) !== false) {
|
||||
$badges[] = ['text' => $tag->name, 'type' => 'tag'];
|
||||
if (count($badges) >= 2) break;
|
||||
$used_keywords[] = strtolower($tag->name);
|
||||
return $badges; // Return only 1 badge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 3: Categories
|
||||
if ($categories && !is_wp_error($categories) && count($badges) < 2) {
|
||||
// Priority 3: Categories (if not used)
|
||||
if ($categories && !is_wp_error($categories)) {
|
||||
foreach ($categories as $cat) {
|
||||
if (stripos($heading_lower, strtolower($cat->name)) !== false) {
|
||||
if (!in_array(strtolower($cat->name), $used_keywords) && stripos($heading_lower, strtolower($cat->name)) !== false) {
|
||||
$badges[] = ['text' => $cat->name, 'type' => 'category'];
|
||||
if (count($badges) >= 2) break;
|
||||
$used_keywords[] = strtolower($cat->name);
|
||||
return $badges; // Return only 1 badge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 4: Secondary keywords
|
||||
if ($secondary_kws && count($badges) < 2) {
|
||||
// Priority 4: Secondary keywords (if not used)
|
||||
if ($secondary_kws) {
|
||||
$kw_array = is_array($secondary_kws) ? $secondary_kws : explode(',', $secondary_kws);
|
||||
foreach ($kw_array as $kw) {
|
||||
$kw = trim($kw);
|
||||
if (!empty($kw) && stripos($heading_lower, strtolower($kw)) !== false) {
|
||||
if (!empty($kw) && !in_array(strtolower($kw), $used_keywords) && stripos($heading_lower, strtolower($kw)) !== false) {
|
||||
$badges[] = ['text' => $kw, 'type' => 'keyword'];
|
||||
if (count($badges) >= 2) break;
|
||||
$used_keywords[] = strtolower($kw);
|
||||
return $badges; // Return only 1 badge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,6 +854,7 @@ function igny8_set_featured_image($post_id, $image_data) {
|
||||
*/
|
||||
function igny8_set_image_gallery($post_id, $gallery_images) {
|
||||
$attachment_ids = array();
|
||||
$imported_images = array(); // For _igny8_imported_images meta with full metadata
|
||||
|
||||
// Limit to 5 images
|
||||
$gallery_images = array_slice($gallery_images, 0, 5);
|
||||
@@ -875,6 +876,19 @@ function igny8_set_image_gallery($post_id, $gallery_images) {
|
||||
|
||||
if ($attachment_id) {
|
||||
$attachment_ids[] = $attachment_id;
|
||||
|
||||
// Build complete image metadata for template
|
||||
$position = is_array($image_data) ? ($image_data['position'] ?? 0) : 0;
|
||||
$caption = is_array($image_data) ? ($image_data['caption'] ?? '') : ''; // Use caption instead of prompt
|
||||
$is_featured = is_array($image_data) ? ($image_data['is_featured'] ?? false) : false;
|
||||
|
||||
$imported_images[] = array(
|
||||
'position' => intval($position),
|
||||
'attachment_id' => $attachment_id,
|
||||
'url' => wp_get_attachment_url($attachment_id),
|
||||
'prompt' => $caption, // Store caption in prompt field for template compatibility
|
||||
'is_featured' => $is_featured
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,6 +901,14 @@ function igny8_set_image_gallery($post_id, $gallery_images) {
|
||||
update_post_meta($post_id, '_gallery_images', $attachment_ids); // Generic
|
||||
}
|
||||
|
||||
// Store complete image metadata for IGNY8 template
|
||||
if (!empty($imported_images)) {
|
||||
update_post_meta($post_id, '_igny8_imported_images', $imported_images);
|
||||
|
||||
$log_prefix = "[" . get_option('igny8_site_id', 'N/A') . "-" . parse_url(site_url(), PHP_URL_HOST) . "]";
|
||||
Igny8_Logger::info("{$log_prefix} ✅ Saved _igny8_imported_images meta with " . count($imported_images) . " images (positions: " . implode(', ', array_column($imported_images, 'position')) . ")");
|
||||
}
|
||||
|
||||
return $attachment_ids;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,48 @@
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.igny8-meta-link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.igny8-meta-link:hover {
|
||||
opacity: 0.7;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.igny8-category-badge,
|
||||
.igny8-tag-badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: var(--igny8-border-radius-xs);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.igny8-category-badge {
|
||||
background: rgba(59, 130, 246, 0.15);
|
||||
color: rgba(29, 78, 216, 1);
|
||||
}
|
||||
|
||||
.igny8-category-badge:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.igny8-tag-badge {
|
||||
background: rgba(139, 92, 246, 0.15);
|
||||
color: rgba(109, 40, 217, 1);
|
||||
}
|
||||
|
||||
.igny8-tag-badge:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
.igny8-meta-icon {
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
@@ -235,29 +277,24 @@
|
||||
|
||||
/* === Featured Image === */
|
||||
.igny8-featured-image-block {
|
||||
background: var(--wp--preset--color--base, #ffffff);
|
||||
border: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: var(--igny8-border-radius);
|
||||
overflow: hidden;
|
||||
margin-bottom: var(--igny8-spacing);
|
||||
}
|
||||
|
||||
.igny8-image-card {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
border: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: var(--igny8-border-radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--wp--preset--color--base, #ffffff);
|
||||
box-shadow: 0 4px 20px -4px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.igny8-featured-header {
|
||||
padding: 2rem 2rem 1rem;
|
||||
}
|
||||
|
||||
.igny8-featured-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.2em;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.igny8-featured-image-wrapper {
|
||||
position: relative;
|
||||
.igny8-image-card img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.igny8-featured-image {
|
||||
@@ -268,28 +305,6 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.igny8-image-prompt {
|
||||
padding: 1.5rem 2rem;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.igny8-prompt-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.15em;
|
||||
opacity: 0.5;
|
||||
margin: 0 0 0.75rem 0;
|
||||
}
|
||||
|
||||
.igny8-prompt-text {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/* === Content Body === */
|
||||
.igny8-content-body {
|
||||
display: flex;
|
||||
@@ -318,6 +333,34 @@
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.igny8-intro-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
gap: 2rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.igny8-intro-toc {
|
||||
position: sticky;
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
.igny8-intro-content {
|
||||
font-size: 1.0625rem;
|
||||
line-height: 1.85;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@media (max-width: 968px) {
|
||||
.igny8-intro-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.igny8-intro-toc {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
.igny8-section-label {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
@@ -369,18 +412,14 @@
|
||||
}
|
||||
|
||||
.igny8-section-content {
|
||||
display: grid;
|
||||
gap: 2.5rem;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.igny8-section-content.igny8-has-image {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.igny8-section-content.igny8-has-image {
|
||||
grid-template-columns: 3fr 2fr;
|
||||
}
|
||||
.igny8-section-content::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* === Prose Styles === */
|
||||
@@ -420,6 +459,8 @@
|
||||
|
||||
.igny8-prose li {
|
||||
margin-bottom: 0.6rem;
|
||||
clear: both;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.igny8-prose a {
|
||||
@@ -491,12 +532,27 @@
|
||||
margin: 3rem 0;
|
||||
}
|
||||
|
||||
/* === In-Article Images === */
|
||||
.igny8-image-figure {
|
||||
/* =margin: 0;
|
||||
}
|
||||
|
||||
.igny8-image-figure.igny8-image-card {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
border: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: var(--igny8-border-radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--wp--preset--color--base, #ffffff);
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.igny8-image-square-right,
|
||||
.igny8-image-square-left {
|
||||
border: 2px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: var(--igny8-border-radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--wp--preset--color--base, #ffffff) hidden;
|
||||
background: var(--wp--preset--color--base, #ffffff);
|
||||
margin: 0;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@@ -521,17 +577,19 @@
|
||||
|
||||
/* Square image - Right aligned */
|
||||
.igny8-image-square-right {
|
||||
max-width: 50%;
|
||||
width: 48%;
|
||||
max-width: 48%;
|
||||
float: right;
|
||||
margin-left: 2rem;
|
||||
margin-left: 4%;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Square image - Left aligned */
|
||||
.igny8-image-square-left {
|
||||
max-width: 50%;
|
||||
width: 48%;
|
||||
max-width: 48%;
|
||||
float: left;
|
||||
margin-right: 2rem;
|
||||
margin-right: 4%;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
@@ -546,24 +604,12 @@
|
||||
|
||||
/* Widget placeholder */
|
||||
.igny8-widget-placeholder {
|
||||
clear: both;
|
||||
min-height: 200px;
|
||||
padding: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
border: 1px dashed rgba(0, 0, 0, 0.1);
|
||||
border-radius: var(--igny8-border-radius-sm);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.igny8-widget-placeholder.igny8-widgets-enabled {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.igny8-image-caption {
|
||||
padding: 1.25rem;
|
||||
clear: botrem;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
color: rgba(0, 0, 0, 0.7)
|
||||
|
||||
.igny8-caption-label {
|
||||
font-size: 0.7rem;
|
||||
|
||||
@@ -33,11 +33,37 @@ $reuse_pattern = [1, 0, 3, 2]; // Featured, Square1, Landscape2, Square2
|
||||
<div class="igny8-content-body">
|
||||
|
||||
<!-- Introduction (content before first H2) -->
|
||||
<?php if (!empty($parsed_content['intro'])): ?>
|
||||
<?php if (!empty($parsed_content['intro'])):
|
||||
// Generate TOC for intro section
|
||||
$toc_items = igny8_generate_table_of_contents($content);
|
||||
$min_headings = get_option('igny8_toc_min_headings', 3);
|
||||
$show_toc = count($toc_items) >= $min_headings;
|
||||
?>
|
||||
<section class="igny8-intro-section">
|
||||
<div class="igny8-section-label">Opening Narrative</div>
|
||||
<div class="igny8-prose">
|
||||
<?php echo $parsed_content['intro']; ?>
|
||||
<div class="igny8-intro-layout">
|
||||
<?php if ($show_toc): ?>
|
||||
<nav class="igny8-intro-toc">
|
||||
<div class="igny8-toc-header">
|
||||
<svg class="igny8-toc-icon" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M9 4.804A7.968 7.968 0 005.5 4c-1.255 0-2.443.29-3.5.804v10A7.969 7.969 0 015.5 14c1.669 0 3.218.51 4.5 1.385A7.962 7.962 0 0114.5 14c1.255 0 2.443.29 3.5.804v-10A7.968 7.968 0 0014.5 4c-1.255 0-2.443.29-3.5.804V12a1 1 0 11-2 0V4.804z"/>
|
||||
</svg>
|
||||
<h3>Table of Contents</h3>
|
||||
</div>
|
||||
<ol class="igny8-toc-list">
|
||||
<?php foreach ($toc_items as $item): ?>
|
||||
<li class="igny8-toc-item">
|
||||
<a href="#<?php echo esc_attr($item['id']); ?>" class="igny8-toc-link">
|
||||
<span class="igny8-toc-number"><?php echo $item['number']; ?></span>
|
||||
<span class="igny8-toc-text"><?php echo esc_html($item['text']); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<div class="igny8-intro-content">
|
||||
<?php echo $parsed_content['intro']; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
@@ -52,15 +78,13 @@ $reuse_pattern = [1, 0, 3, 2]; // Featured, Square1, Landscape2, Square2
|
||||
<span class="igny8-section-number"><?php echo $index + 1; ?></span>
|
||||
<div class="igny8-section-heading-wrapper">
|
||||
<?php
|
||||
// Get section badges based on keyword/tag matching
|
||||
// Get section badge (only 1, no repeats)
|
||||
$badges = igny8_get_section_badges($section['heading'], get_the_ID());
|
||||
if (!empty($badges)): ?>
|
||||
if (!empty($badges) && isset($badges[0])): ?>
|
||||
<div class="igny8-section-badges">
|
||||
<?php foreach ($badges as $badge_index => $badge): ?>
|
||||
<span class="igny8-section-badge <?php echo $badge_index === 0 ? 'igny8-section-badge-primary' : 'igny8-section-badge-secondary'; ?>">
|
||||
<?php echo esc_html($badge['text']); ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
<span class="igny8-section-badge igny8-section-badge-primary">
|
||||
<?php echo esc_html($badges[0]['text']); ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h2 class="igny8-section-heading"><?php echo esc_html($section['heading']); ?></h2>
|
||||
@@ -128,15 +152,14 @@ $reuse_pattern = [1, 0, 3, 2]; // Featured, Square1, Landscape2, Square2
|
||||
}
|
||||
?>
|
||||
<div class="igny8-section-content">
|
||||
<figure class="igny8-image-figure">
|
||||
<figure class="igny8-image-figure igny8-image-card">
|
||||
<img src="<?php echo esc_url($img_url); ?>"
|
||||
alt="<?php echo esc_attr($section['heading']); ?>"
|
||||
class="<?php echo esc_attr($img_class); ?>"
|
||||
loading="lazy">
|
||||
<?php if ($show_description && $img_prompt): ?>
|
||||
<figcaption class="igny8-image-caption">
|
||||
<p class="igny8-caption-label">Visual Direction</p>
|
||||
<p class="igny8-caption-text"><?php echo esc_html($img_prompt); ?></p>
|
||||
<?php echo esc_html($img_prompt); ?>
|
||||
</figcaption>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
@@ -161,11 +184,16 @@ $reuse_pattern = [1, 0, 3, 2]; // Featured, Square1, Landscape2, Square2
|
||||
loading="lazy">
|
||||
<?php if ($show_description && $img_prompt): ?>
|
||||
<figcaption class="igny8-image-caption">
|
||||
<p class="igny8-caption-label">Visual Direction</p>
|
||||
<p class="igny8-caption-text"><?php echo esc_html($img_prompt); ?></p>
|
||||
<?php echo esc_html($img_prompt); ?>
|
||||
</figcaption>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
<?php
|
||||
// Render TOC in section 1 after image
|
||||
if ($index === 0) {
|
||||
include plugin_dir_path(dirname(__FILE__)) . 'igny8-table-of-contents.php';
|
||||
}
|
||||
?>
|
||||
<div class="igny8-prose">
|
||||
<?php echo $section['content']; ?>
|
||||
</div>
|
||||
@@ -184,15 +212,14 @@ $reuse_pattern = [1, 0, 3, 2]; // Featured, Square1, Landscape2, Square2
|
||||
}
|
||||
?>
|
||||
<div class="igny8-section-content">
|
||||
<figure class="igny8-image-figure">
|
||||
<figure class="igny8-image-figure igny8-image-card">
|
||||
<img src="<?php echo esc_url($img_url); ?>"
|
||||
alt="<?php echo esc_attr($section['heading']); ?>"
|
||||
class="<?php echo esc_attr($img_class); ?>"
|
||||
loading="lazy">
|
||||
<?php if ($show_description && $img_prompt): ?>
|
||||
<figcaption class="igny8-image-caption">
|
||||
<p class="igny8-caption-label">Visual Direction</p>
|
||||
<p class="igny8-caption-text"><?php echo esc_html($img_prompt); ?></p>
|
||||
<?php echo esc_html($img_prompt); ?>
|
||||
</figcaption>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
|
||||
@@ -20,22 +20,10 @@ if (!$image_url) {
|
||||
?>
|
||||
|
||||
<div class="igny8-featured-image-block">
|
||||
<div class="igny8-featured-header">
|
||||
<span class="igny8-featured-label">Featured Visual</span>
|
||||
</div>
|
||||
|
||||
<div class="igny8-featured-image-wrapper">
|
||||
<figure class="igny8-image-figure igny8-image-card">
|
||||
<img src="<?php echo esc_url($image_url); ?>"
|
||||
alt="<?php echo esc_attr($image_alt ?: get_the_title()); ?>"
|
||||
class="igny8-featured-image igny8-image-landscape"
|
||||
style="max-width: 1024px;"
|
||||
loading="lazy">
|
||||
</div>
|
||||
|
||||
<?php if ($featured_image_prompt): ?>
|
||||
<div class="igny8-image-prompt">
|
||||
<p class="igny8-prompt-label">AI Image Prompt</p>
|
||||
<p class="igny8-prompt-text"><?php echo esc_html($featured_image_prompt); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
@@ -16,20 +16,9 @@ $status_class = igny8_get_status_class($status);
|
||||
?>
|
||||
|
||||
<div class="igny8-header">
|
||||
<!-- Back Button -->
|
||||
<div class="igny8-header-back">
|
||||
<a href="<?php echo esc_url(get_post_type_archive_link('post')); ?>" class="igny8-back-button">
|
||||
<span class="igny8-back-icon">←</span>
|
||||
<span>Back to Posts</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Title & Status -->
|
||||
<!-- Title -->
|
||||
<div class="igny8-header-title-row">
|
||||
<h1 class="igny8-title"><?php the_title(); ?></h1>
|
||||
<span class="igny8-status-badge <?php echo esc_attr($status_class); ?>">
|
||||
<?php echo esc_html($status_label); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Metadata Row -->
|
||||
@@ -64,13 +53,21 @@ $status_class = igny8_get_status_class($status);
|
||||
</div>
|
||||
|
||||
<!-- Topic (Cluster Name) -->
|
||||
<?php if ($cluster_name): ?>
|
||||
<?php if ($cluster_name):
|
||||
// Get cluster term for link
|
||||
$cluster_terms = get_the_terms(get_the_ID(), 'igny8_clusters');
|
||||
$cluster_link = (!empty($cluster_terms) && !is_wp_error($cluster_terms)) ? get_term_link($cluster_terms[0]) : '';
|
||||
?>
|
||||
<div class="igny8-meta-item">
|
||||
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z"/>
|
||||
</svg>
|
||||
<span class="igny8-meta-label">Topic:</span>
|
||||
<span class="igny8-meta-value"><?php echo esc_html($cluster_name); ?></span>
|
||||
<?php if ($cluster_link): ?>
|
||||
<a href="<?php echo esc_url($cluster_link); ?>" class="igny8-meta-link"><?php echo esc_html($cluster_name); ?></a>
|
||||
<?php else: ?>
|
||||
<span class="igny8-meta-value"><?php echo esc_html($cluster_name); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -82,8 +79,18 @@ $status_class = igny8_get_status_class($status);
|
||||
</svg>
|
||||
<span class="igny8-meta-label">Categories:</span>
|
||||
<div class="igny8-meta-badges">
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<span class="igny8-category-badge"><?php echo esc_html($cat->name); ?></span>
|
||||
<?php
|
||||
foreach ($categories as $cat):
|
||||
// Build hierarchy path (Parent > Child)
|
||||
$cat_hierarchy = [];
|
||||
$current_cat = $cat;
|
||||
while ($current_cat) {
|
||||
array_unshift($cat_hierarchy, $current_cat);
|
||||
$current_cat = ($current_cat->parent > 0) ? get_category($current_cat->parent) : null;
|
||||
}
|
||||
$hierarchy_text = implode(' > ', array_map(function($c) { return $c->name; }, $cat_hierarchy));
|
||||
?>
|
||||
<a href="<?php echo esc_url(get_category_link($cat->term_id)); ?>" class="igny8-category-badge"><?php echo esc_html($hierarchy_text); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -97,8 +104,12 @@ $status_class = igny8_get_status_class($status);
|
||||
</svg>
|
||||
<span class="igny8-meta-label">Tags:</span>
|
||||
<div class="igny8-meta-badges">
|
||||
<?php foreach ($tags as $tag): ?>
|
||||
<span class="igny8-tag-badge"><?php echo esc_html($tag->name); ?></span>
|
||||
<?php
|
||||
// Get only tags assigned to the post (not keywords)
|
||||
$post_tags = wp_get_post_tags(get_the_ID());
|
||||
foreach ($post_tags as $tag):
|
||||
?>
|
||||
<a href="<?php echo esc_url(get_tag_link($tag->term_id)); ?>" class="igny8-tag-badge"><?php echo esc_html($tag->name); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,8 +80,7 @@ if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
include plugin_dir_path(__FILE__) . 'parts/igny8-featured-image.php';
|
||||
}
|
||||
|
||||
// Table of Contents
|
||||
include plugin_dir_path(__FILE__) . 'parts/igny8-table-of-contents.php';
|
||||
// NOTE: Table of Contents is now rendered inside section 1 (see igny8-content-sections.php)
|
||||
|
||||
// Content sections
|
||||
include plugin_dir_path(__FILE__) . 'parts/igny8-content-sections.php';
|
||||
|
||||
Reference in New Issue
Block a user