✏️ 正在编辑: single.php
路径:
/home/h359620/public_html/wp-content/themes/datis/template-parts/project/single/single.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php if (!defined('ABSPATH')) { exit(); } $theme_options = get_option('datis_theme_options'); $project_single_top_template_id = !empty($theme_options['project_single_elementor_template']) ? absint($theme_options['project_single_elementor_template']) : 0; $has_project_single_top_section = $project_single_top_template_id && class_exists('\Elementor\Plugin'); $demo = get_option('datis_active_demo'); $heading_icon = ''; if ($demo === 'business') : $heading_icon = '<svg width="18" height="69" viewBox="0 0 18 69" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 19.8558L10.8558 18L9 16.1442L7.14423 18L9 19.8558ZM9 18L9.32143 18L9.32143 -1.40501e-08L9 0L8.67857 1.40501e-08L8.67857 18L9 18Z" fill="#0A2647" fill-opacity="0.2"/> <path d="M0.322266 39.2267C0.322266 40.7192 1.53224 41.9292 3.02481 41.9292H14.1728C15.6654 41.9292 16.8753 40.7192 16.8753 39.2267V35.7801C16.8753 34.0703 15.3076 32.7902 13.6324 33.1321L2.48441 35.4072C1.22608 35.664 0.322266 36.7709 0.322266 38.0552V39.2267Z" fill="#0A2647"/> <path d="M16.875 28.4159C16.875 26.9233 15.665 25.7134 14.1725 25.7134H3.02447C1.53189 25.7134 0.321926 26.9233 0.321926 28.4159V31.8625C0.321926 33.5722 1.88964 34.8523 3.56487 34.5105L14.7129 32.2354C15.9712 31.9786 16.875 30.8717 16.875 29.5874V28.4159Z" fill="var(--datis-primary-color)"/> <path d="M9 48.2868L10.8558 50.1426L9 51.9983L7.14423 50.1426L9 48.2868ZM9 50.1426L9.32143 50.1426L9.32143 68.1426L9 68.1426L8.67857 68.1426L8.67857 50.1426L9 50.1426Z" fill="#0A2647" fill-opacity="0.2"/> </svg>'; elseif ($demo === 'industry') : $heading_icon = '<svg width="5" height="62" viewBox="0 0 5 62" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M0 0C2.76142 0 5 2.23858 5 5V57C5 59.7614 2.76142 62 0 62V0Z" fill="var(--datis-secondary-color)"/> </svg>'; else : $heading_icon = '<svg width="84" height="15" viewBox="0 0 84 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_633_2489)"> <rect width="84" height="15" rx="7.5" fill="var(--datis-primary-color)"/> <rect x="-10" width="75" height="15" rx="7.5" fill="var(--datis-secondary-color)"/> </g> <defs> <clipPath id="clip0_633_2489"> <rect width="84" height="15" rx="7.5" fill="white"/> </clipPath> </defs> </svg>'; endif; $approved_count = get_comments_number(get_the_ID()); $style_map = [ 'architecture' => '1', 'business' => '2', 'industry' => '2', ]; $style = $style_map[$demo] ?? 'style-1'; $q = new WP_Query([ 'post_type' => 'project', 'posts_per_page' => 6, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, 'post__not_in' => [get_the_ID()], ]); function datis_inline_project_cat_svg(int $term_id, int $size = 18): string { $url = ''; if (class_exists('\Datis_Page_Options')) { $url = \Datis_Page_Options::get_project_category_svg_url($term_id); } if (!$url) { $raw = get_term_meta($term_id, '_datis_project_cat_svg', true); $url = $raw ? esc_url($raw) : ''; } if (!$url) return ''; $svg = ''; // 1) HTTP $resp = wp_remote_get($url, ['timeout' => 5, 'redirection' => 3]); if (!is_wp_error($resp)) { $code = (int) wp_remote_retrieve_response_code($resp); if ($code >= 200 && $code < 300) { $body = wp_remote_retrieve_body($resp); if (is_string($body) && stripos($body, '<svg') !== false) { $svg = $body; } } } // 2) Attachment file fallback if ($svg === '') { $att_id = attachment_url_to_postid($url); if ($att_id) { $file = get_attached_file($att_id); if (is_string($file) && file_exists($file)) { $body = @file_get_contents($file); if (is_string($body) && stripos($body, '<svg') !== false) { $svg = $body; } } } } // 3) Map local url -> filesystem fallback if ($svg === '') { $home = rtrim(home_url('/'), '/'); $siteurl = rtrim(site_url('/'), '/'); $u = $url; if (strpos($u, $home) === 0) $u = substr($u, strlen($home)); if (strpos($u, $siteurl) === 0) $u = substr($u, strlen($siteurl)); $candidate = ABSPATH . ltrim($u, '/'); if (is_string($candidate) && file_exists($candidate)) { $body = @file_get_contents($candidate); if (is_string($body) && stripos($body, '<svg') !== false) { $svg = $body; } } } if ($svg === '') return ''; // Minimal sanitize $svg = preg_replace('~<\?xml.*?\?>~i', '', $svg); $svg = preg_replace('~<!DOCTYPE.*?>~is', '', $svg); $svg = preg_replace('~<script[^>]*>.*?</script>~is', '', $svg); $svg = preg_replace('~<foreignObject[^>]*>.*?</foreignObject>~is', '', $svg); $svg = preg_replace('/\son\w+\s*=\s*(?:"[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $svg); $svg = preg_replace('/\s(xlink:)?href\s*=\s*"javascript:[^"]*"/i', '', $svg); // Inject size + class into first <svg> $size = max(1, (int) $size); $svg = preg_replace_callback('/<svg\b([^>]*)>/i', function ($m) use ($size) { $attrs = $m[1]; // اگر width/height ست شده بود حذفش کن تا کنترل دست ما باشه $attrs = preg_replace('/\s(width|height)\s*=\s*(?:"[^"]*"|\'[^\']*\')/i', '', $attrs); // class merge if (preg_match('/\sclass\s*=\s*"([^"]*)"/i', $attrs, $cm)) { $old = trim($cm[1]); $new = trim($old . ' projects-filter-icon'); $attrs = preg_replace('/\sclass\s*=\s*"([^"]*)"/i', ' class="' . esc_attr($new) . '"', $attrs, 1); } else { $attrs .= ' class="projects-filter-icon"'; } // aria if (stripos($attrs, 'aria-hidden=') === false) $attrs .= ' aria-hidden="true"'; if (stripos($attrs, 'focusable=') === false) $attrs .= ' focusable="false"'; return '<svg' . $attrs . ' width="' . $size . '" height="' . $size . '">'; }, $svg, 1); return trim($svg); } ?> <div class="container project-single <?php echo esc_attr($demo); ?>-demo p-0 pt-3"> <?php if ($has_project_single_top_section) : ?> <div class="project-single-top-section mt-3 mt-lg-4"> <?php echo \Elementor\Plugin::$instance->frontend->get_builder_content_for_display( $project_single_top_template_id ); ?> </div> <?php endif; ?> <div class="project-media-gallery mt-lg-3"> <?php echo Datis_Project_Media_Swiper::get_instance()->render(get_the_ID()); ?> </div> <?php $post_id = get_the_ID(); $features = get_post_meta($post_id, '_datis_project_features', true); if (is_array($features) && !empty($features)) : ?> <div class="project-meta mt-lg-4"> <?php foreach ($features as $feature) : if (!is_array($feature)) continue; $icon_type = $feature['icon_type'] ?? 'icon'; // icon | image $icon_class = $feature['icon_class'] ?? ''; $icon_image = $feature['icon_image'] ?? ''; $title = $feature['title'] ?? ''; $desc = $feature['desc'] ?? ''; $icon_image_url = ''; if (!empty($icon_image)) { if (is_numeric($icon_image)) { $icon_image_url = wp_get_attachment_url((int) $icon_image); } elseif (is_array($icon_image) && !empty($icon_image['url'])) { $icon_image_url = $icon_image['url']; } elseif (is_string($icon_image)) { $icon_image_url = $icon_image; } } if ($title === '' && $desc === '' && $icon_class === '' && $icon_image_url === '') continue; ?> <div class="meta-item"> <?php if ($icon_type === 'icon' && $icon_class !== '') : ?> <i class="<?php echo esc_attr($icon_class); ?>" aria-hidden="true"></i> <?php elseif ($icon_type === 'image' && $icon_image_url !== '') : ?> <img src="<?php echo esc_url($icon_image_url); ?>" alt="" loading="lazy"> <?php endif; ?> <div class="d-flex flex-column"> <?php if ($title !== '') : ?> <div class="meta-title"><?php echo esc_html($title); ?></div> <?php endif; ?> <?php if ($desc !== '') : ?> <div class="meta-desc"><?php echo wp_kses($desc, []); ?></div> <?php endif; ?> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> <div class="project-content"> <?php the_content(); ?> </div> <?php if ($approved_count > 0) : ?> <div class="project-comments mt-5 pt-5"> <div class="heading d-flex flex-row justify-content-between align-items-center gap-3 mb-4"> <?php if ($demo === 'business' || $demo === 'industry') : ?> <div class="d-flex flex-row align-items-center gap-3"> <?php else : ?> <div class="d-flex flex-column align-items-start gap-3"> <?php endif; ?> <?php echo $heading_icon; ?> <div class="d-flex flex-column"> <?php if ($demo === 'industry') : ?> <p> <?php printf( wp_kses_post(__("%s Reviews", 'datis')), '<span class="accent-text">' . esc_html__("User'", 'datis') . '</span>' ); ?> </p> <span><?php esc_html_e('Real Feedback from Our Loyal Partners', 'datis'); ?></span> <?php elseif ($demo === 'architecture') : ?> <span>REVIEWS</span> <p><?php esc_html_e("User Reviews", 'datis'); ?></p> <?php else : ?> <p><?php esc_html_e("User Reviews", 'datis'); ?></p> <span><?php esc_html_e('REVIEWS', 'datis'); ?></span> <?php endif; ?> </div> </div><!-- /layout div --> <?php if ($demo === 'business' || $demo === 'industry') : ?> <svg class="d-none d-lg-flex" width="850" height="6" viewBox="0 0 950 6" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M-3.26633e-05 2.88672L2.88672 5.77347L5.77347 2.88672L2.88672 -3.26633e-05L-3.26633e-05 2.88672ZM2.88672 2.88672V3.38672H949.887V2.88672V2.38672H2.88672V2.88672Z" fill="#0A2647" fill-opacity="0.1" /> </svg> <?php endif; ?> </div><!-- /.heading --> <?php datis_comments_list(); ?> </div><!-- /.project-comments --> <?php endif; ?> <div class="project-comment-form mt-5 pt-5"> <div class="heading d-flex flex-row justify-content-between align-items-center gap-3 mb-4"> <?php if ($demo === 'business' || $demo === 'industry') : ?> <div class="d-flex flex-row align-items-center gap-3"> <?php else : ?> <div class="d-flex flex-column align-items-start gap-3"> <?php endif; ?> <?php echo $heading_icon; ?> <div class="d-flex flex-column"> <?php if ($demo === 'industry') : ?> <p> <?php printf( wp_kses_post(__("%s Reviews", 'datis')), '<span class="accent-text">' . esc_html__("User'", 'datis') . '</span>' ); ?> </p> <span><?php esc_html_e('Real Feedback from Our Loyal Partners', 'datis'); ?></span> <?php elseif ($demo === 'architecture') : ?> <span>REVIEWS</span> <p><?php esc_html_e("User Reviews", 'datis'); ?></p> <?php else : ?> <p><?php esc_html_e("User Reviews", 'datis'); ?></p> <span><?php esc_html_e('REVIEWS', 'datis'); ?></span> <?php endif; ?> </div> </div><!-- /layout div --> <?php if ($demo === 'business' || $demo === 'industry') : ?> <svg class="d-none d-lg-flex" width="850" height="6" viewBox="0 0 950 6" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M-3.26633e-05 2.88672L2.88672 5.77347L5.77347 2.88672L2.88672 -3.26633e-05L-3.26633e-05 2.88672ZM2.88672 2.88672V3.38672H949.887V2.88672V2.38672H2.88672V2.88672Z" fill="#0A2647" fill-opacity="0.1" /> </svg> <?php endif; ?> </div><!-- /.heading --> <div class="col-12 col-lg-9" id="respond"> <?php datis_comments_form(); ?> </div> </div><!-- /.project-comment-form --> <div class="recent-projects mt-5 pt-5"> <div class="heading d-flex flex-row justify-content-start align-items-center gap-3 mb-4"> <?php if ($demo === 'business' || $demo === 'industry') : ?> <div class="d-flex flex-row align-items-center gap-3"> <?php else : ?> <div class="d-flex flex-column align-items-center w-100 gap-3"> <?php endif; ?> <?php echo $heading_icon; ?> <div class="d-flex flex-column"> <?php if ($demo === 'industry') : ?> <p> <?php printf( wp_kses_post(__("%s Our Recent ", 'datis')), '<span class="accent-text">' . esc_html__("Projects", 'datis') . '</span>' ); ?> </p> <span><?php esc_html_e('Projects with inspiring results', 'datis'); ?></span> <?php elseif ($demo === 'architecture') : ?> <span><?php esc_html_e('Our Recent Projects', 'datis'); ?></span> <p><?php esc_html_e("Projects with inspiring results", 'datis'); ?></p> <?php else : ?> <p><?php esc_html_e("Our Recent Projects", 'datis'); ?></p> <span><?php esc_html_e('Projects with inspiring results', 'datis'); ?></span> <?php endif; ?> </div> </div><!-- /layout div --> <?php if ($demo === 'business' || $demo === 'industry') : ?> <svg class="d-none d-lg-flex" width="850" height="6" viewBox="0 0 950 6" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M-3.26633e-05 2.88672L2.88672 5.77347L5.77347 2.88672L2.88672 -3.26633e-05L-3.26633e-05 2.88672ZM2.88672 2.88672V3.38672H949.887V2.88672V2.38672H2.88672V2.88672Z" fill="#0A2647" fill-opacity="0.1" /> </svg> <?php endif; ?> </div><!-- /.heading --> <?php /** * ✅ Filters only in architecture demo * taxonomy: project-categories */ if ($demo === 'architecture') : $filter_terms = get_terms([ 'taxonomy' => 'project-categories', 'hide_empty' => true, ]); if (!is_wp_error($filter_terms) && !empty($filter_terms)) : ?> <div class="projects-filters datis-recent-projects-filters" data-swiper=".datis-latest-projects-swiper"> <button type="button" class="projects-filter is-active" data-term="all"> <span class="projects-filter-label"><?php echo esc_html__('All', 'datis'); ?></span> </button> <?php foreach ($filter_terms as $t) : ?> <button type="button" class="projects-filter" data-term="<?php echo (int) $t->term_id; ?>"> <?php // ✅ SVG icon (inline) مثل ویجت echo datis_inline_project_cat_svg((int) $t->term_id, 18); ?> <span class="projects-filter-label"><?php echo esc_html($t->name); ?></span> </button> <?php endforeach; ?> </div> <?php endif; endif; ?> <?php if ($q->have_posts()) : ?> <div class="swiper datis-latest-projects-swiper" data-demo="<?php echo esc_attr($demo); ?>"> <div class="swiper-wrapper"> <?php while ($q->have_posts()) : $q->the_post(); ?> <?php // ✅ term ids for filtering $term_ids = wp_get_post_terms(get_the_ID(), 'project-categories', ['fields' => 'ids']); $data_terms = !empty($term_ids) ? implode(',', array_map('intval', $term_ids)) : ''; ?> <?php if ($demo === 'architecture') : ?> <div class="swiper-slide" data-terms="<?php echo esc_attr($data_terms); ?>"> <div class="datis-projects projects-style-2"> <?php get_template_part('template-parts/project/content/content-card', $style); ?> </div> </div> <?php else : ?> <div class="swiper-slide"> <?php get_template_part('template-parts/project/content/content-card', $style); ?> </div> <?php endif; ?> <?php endwhile; wp_reset_postdata(); ?> </div><!-- /.swiper-wrapper --> <?php if ($demo === 'architecture') : ?> <!-- ✅ Navigation دقیقا مثل ویجت style-2 (اما با کلاسهای اختصاصی) --> <div class="projects-nav latest-projects-nav"> <button type="button" class="latest-projects-prev" aria-label="<?php echo esc_attr__('Previous', 'datis'); ?>"> <svg width="42" height="14" viewBox="0 0 42 14" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M0.75 6.75L6.75 0.75M0.75 6.75L6.75 12.75M0.75 6.75H11.25M40.75 6.75H14.25" stroke="#090625" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> <button type="button" class="latest-projects-next" aria-label="<?php echo esc_attr__('Next', 'datis'); ?>"> <svg width="42" height="14" viewBox="0 0 42 14" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M40.75 6.75L34.75 0.75M40.75 6.75L34.75 12.75M40.75 6.75H30.25M0.75 6.75H27.25" stroke="#090625" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> <span class="projects-nav-line"></span> </div> <?php else : ?> <!-- ناوبری قبلی برای سایر دموها --> <div class="latest-projects-nav"> <div class="swiper-button-prev"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10.3717 10.371H18.1498M10.3717 10.371V18.1492M10.3717 10.371L17.1776 17.1769M20.7426 20.7419L19.1221 19.1215" stroke="#0A2647" stroke-width="1.23483" stroke-linecap="round" stroke-linejoin="round" /> </svg> </div> <div class="swiper-button-next"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.7416 10.371H12.9635M20.7416 10.371V18.1492M20.7416 10.371L13.9357 17.1769M10.3707 20.7419L11.9912 19.1215" stroke="#0A2647" stroke-width="1.23483" stroke-opacity="0.64" stroke-linecap="round" stroke-linejoin="round" /> </svg> </div> </div><!-- /.latest-projects-nav --> <?php endif; ?> </div><!-- /.swiper --> <?php endif; ?> </div><!-- /.recent-projects -->
💾 保存文件
← 返回文件管理器