first commit 2
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* rb.custom :: general_ad_section/config.php
|
||||
* 일반 광고 모듈 설정 파일
|
||||
*/
|
||||
|
||||
$general_ad_config = array(
|
||||
// 이 모듈이 가져올 배너의 위치(bn_position) 코드
|
||||
'position' => 'general_main',
|
||||
|
||||
// --- 💡 [최종 수정] 레이아웃 및 출력 모드 설정 ---
|
||||
|
||||
// 1. 출력 모드 설정 ('fixed', 'slide', 'both')
|
||||
'display_mode' => 'fixed', // 기본값으로 슬라이드형만 출력
|
||||
|
||||
// 2. 고정형 그리드 설정
|
||||
'fixed_grid_columns' => 2, // 한 줄에 표시할 배너 개수
|
||||
|
||||
// 3. 배너 유닛 크기 및 간격 설정
|
||||
'banner_width' => 180, // 슬라이드 배너 한 개의 가로 크기 (px)
|
||||
'banner_height' => 80, // 배너 한 개의 세로 크기 (px)
|
||||
'banner_gap' => 10, // 배너 사이의 간격 (px)
|
||||
|
||||
// 4. 슬라이드 옵션
|
||||
'slide_options' => array(
|
||||
'fx' => 'carousel', // 캐러셀 효과
|
||||
'timeout' => 4000, // 각 슬라이드 표시 시간 (0이면 자동롤링 안함)
|
||||
'slides' => '> .banner-unit-wrapper', // 슬라이드 될 자식 요소
|
||||
'log' => false,
|
||||
'allow-wrap' => true, // 무한 반복
|
||||
),
|
||||
);
|
||||
?>
|
||||
@@ -0,0 +1,92 @@
|
||||
/* General Ad Section Style - Final Layout Fix */
|
||||
|
||||
.general-ad-section {
|
||||
padding: 20px;
|
||||
background: #f1f3f5;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* 1. 고정형 그리드 */
|
||||
.general-ad-fixed-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--banner-gap, 10px);
|
||||
margin-bottom: var(--banner-gap, 10px);
|
||||
}
|
||||
|
||||
.general-ad-fixed-grid .banner-unit-wrapper {
|
||||
flex: 1 0 calc((100% - (var(--banner-gap, 10px) * (var(--fixed-columns) - 1))) / var(--fixed-columns));
|
||||
height: var(--banner-height, 80px);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
/* 2. 슬라이드형 래퍼 */
|
||||
.general-ad-row {
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 50px;
|
||||
}
|
||||
|
||||
.general-ad-slider {
|
||||
width: 100%;
|
||||
height: var(--banner-height, 80px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.general-ad-slider .banner-unit-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.banner-unit-wrapper img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.slider-controls .swiper-button-prev,
|
||||
.slider-controls .swiper-button-next {
|
||||
color: #555 !important;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
margin-top: 0;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.slider-controls .swiper-button-prev:after,
|
||||
.slider-controls .swiper-button-next:after {
|
||||
font-size: 14px !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.slider-controls .swiper-button-prev { left: 0; }
|
||||
.slider-controls .swiper-button-next { right: 0; }
|
||||
|
||||
.empty-banner {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.general-ad-fixed-grid .banner-unit-wrapper {
|
||||
flex-basis: calc((100% - var(--banner-gap, 10px)) / 2);
|
||||
}
|
||||
.general-ad-row {
|
||||
padding: 0 30px;
|
||||
}
|
||||
.general-ad-slider {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
if (typeof window.initGeneralAdSection === 'function') {
|
||||
// return;
|
||||
}
|
||||
|
||||
window.initGeneralAdSection = function(moduleId) {
|
||||
const $module = $('#' + moduleId);
|
||||
if (!$module.length) return;
|
||||
|
||||
$module.find('.general-ad-row').each(function() {
|
||||
const $row = $(this);
|
||||
const $swiperContainer = $row.find('.swiper-container');
|
||||
|
||||
const slidesPerView = parseInt($swiperContainer.data('slides-per-view'), 10) || 6;
|
||||
const spaceBetween = parseInt($swiperContainer.data('space-between'), 10) || 10;
|
||||
const totalSlides = $swiperContainer.find('.swiper-slide').length;
|
||||
|
||||
const loop = totalSlides > 1;
|
||||
|
||||
new Swiper($swiperContainer[0], {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: spaceBetween,
|
||||
loop: loop,
|
||||
autoplay: {
|
||||
delay: 3000,
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
navigation: {
|
||||
nextEl: $row.find('.swiper-button-next')[0],
|
||||
prevEl: $row.find('.swiper-button-prev')[0],
|
||||
},
|
||||
breakpoints: {
|
||||
640: { slidesPerView: 3 },
|
||||
768: { slidesPerView: 4 },
|
||||
1024: {
|
||||
slidesPerView: (totalSlides < slidesPerView) ? totalSlides : slidesPerView
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$(function() {
|
||||
$('.general-ad-section').each(function() {
|
||||
window.initGeneralAdSection($(this).attr('id'));
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* rb.custom :: general_ad_section/module.php
|
||||
* 일반 광고 모듈 (설정에 따라 고정형/슬라이드형 선택)
|
||||
*/
|
||||
|
||||
if (!isset($md_id) || !$md_id) return;
|
||||
|
||||
$md_id_safe = sql_real_escape_string($md_id);
|
||||
$module_config = sql_fetch(" SELECT * FROM `rb_module` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) $module_config = sql_fetch(" SELECT * FROM `rb_module_shop` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) return;
|
||||
|
||||
$config_path = __DIR__ . '/config.php';
|
||||
if (file_exists($config_path)) include_once($config_path);
|
||||
else return;
|
||||
|
||||
// 데이터 가져오기
|
||||
$position = $general_ad_config['position'];
|
||||
$sql = " SELECT * FROM `rb_banner` WHERE bn_position = '{$position}' AND bn_begin_time <= NOW() AND bn_end_time >= NOW() ORDER BY bn_order ASC, bn_id DESC ";
|
||||
$result = sql_query($sql);
|
||||
|
||||
$all_banners = [];
|
||||
while ($row = sql_fetch_array($result)) {
|
||||
$row['bn_img'] = '<img src="' . G5_DATA_URL . '/banners/' . $row['bn_id'] . '" alt="' . get_text($row['bn_alt']) . '">';
|
||||
$all_banners[] = $row;
|
||||
}
|
||||
|
||||
// 💡 [핵심 수정] 설정값(display_mode)에 따라 배너 분류
|
||||
$display_mode = $general_ad_config['display_mode']; // 'fixed' or 'slide'
|
||||
$fixed_banners = [];
|
||||
$slide_groups = [];
|
||||
|
||||
if ($display_mode === 'fixed') {
|
||||
// 고정형: 모든 배너를 고정 영역으로
|
||||
$fixed_banners = $all_banners;
|
||||
} else {
|
||||
// 슬라이드형: 모든 배너를 하나의 슬라이드 그룹으로 (다중 행 처리는 아래에서 함)
|
||||
// 키는 임의로 'default'로 지정
|
||||
if (!empty($all_banners)) {
|
||||
$slide_groups['default'] = $all_banners;
|
||||
}
|
||||
}
|
||||
|
||||
$md_banner_skin = isset($module_config['md_banner_skin']) && $module_config['md_banner_skin'] !=''? $module_config['md_banner_skin'] : 'rb.mod/banner/skin/split_layout';
|
||||
$item_skin_file = G5_PATH . '/rb/' . $md_banner_skin . '/skin.php';
|
||||
|
||||
$css_vars = [
|
||||
'--fixed-columns: ' . (int)$general_ad_config['fixed_grid_columns'],
|
||||
'--banner-width: ' . (int)$general_ad_config['banner_width'] . 'px',
|
||||
'--banner-height: ' . (int)$general_ad_config['banner_height'] . 'px',
|
||||
'--banner-gap: ' . (int)$general_ad_config['banner_gap'] . 'px',
|
||||
];
|
||||
|
||||
$visual_id = 'gas_' . uniqid();
|
||||
?>
|
||||
|
||||
<div class="general-ad-section" id="<?php echo $visual_id; ?>" style="<?php echo implode('; ', $css_vars); ?>;">
|
||||
|
||||
<!-- 1. 고정형 배너 영역 -->
|
||||
<?php if (!empty($fixed_banners)): ?>
|
||||
|
||||
<div class="general-ad-fixed-grid">
|
||||
<?php
|
||||
foreach ($fixed_banners as $banner) {
|
||||
if (file_exists($item_skin_file)) {
|
||||
echo '<div class="banner-unit-wrapper">';
|
||||
include($item_skin_file);
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 2. 슬라이드형 배너 영역 (다중 행 지원) -->
|
||||
<?php if (!empty($slide_groups)): ?>
|
||||
<?php foreach ($slide_groups as $group_name => $banners):
|
||||
$columns = (int)$general_ad_config['fixed_grid_columns'];
|
||||
$chunk_size = $columns * 2;
|
||||
$banner_rows = array_chunk($banners, $chunk_size);
|
||||
?>
|
||||
<?php foreach ($banner_rows as $row_index => $banners_in_row):
|
||||
$current_count = count($banners_in_row);
|
||||
$slides_per_view = ($current_count < $columns) ? $current_count : $columns;
|
||||
?>
|
||||
<div class="general-ad-row">
|
||||
<div class="swiper-container general-ad-slider"
|
||||
data-slides-per-view="<?php echo $slides_per_view; ?>"
|
||||
data-space-between="<?php echo (int)$general_ad_config['banner_gap']; ?>">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($banners_in_row as $banner): ?>
|
||||
<div class="swiper-slide banner-unit-wrapper">
|
||||
<?php
|
||||
if (file_exists($item_skin_file)) {
|
||||
include($item_skin_file);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="slider-controls">
|
||||
<div class="swiper-button-prev btn-prev"><i class="fa fa-chevron-left"></i></div>
|
||||
<div class="swiper-button-next btn-next"><i class="fa fa-chevron-right"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($fixed_banners) && empty($slide_groups)): ?>
|
||||
<div class="empty-banner">등록된 배너가 없습니다.</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="<?php echo G5_THEME_URL; ?>/rb.custom/general_ad_section/module.css?ver=<?php echo G5_CSS_VER; ?>">
|
||||
|
||||
<!-- 통합 동적 로더 (Swiper) -->
|
||||
<script>
|
||||
(function() {
|
||||
var currentModuleId = '<?php echo $visual_id; ?>';
|
||||
var initFunctionName = 'initGeneralAdSection';
|
||||
var themeUrl = '<?php echo G5_THEME_URL; ?>';
|
||||
var jsVer = '<?php echo G5_JS_VER; ?>';
|
||||
|
||||
function loadScript(src, id, callback) {
|
||||
if (document.getElementById(id)) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
var script = document.createElement('script');
|
||||
script.id = id;
|
||||
script.src = src;
|
||||
script.async = false;
|
||||
if (callback) {
|
||||
script.onload = callback;
|
||||
}
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
function finalAction() {
|
||||
if (typeof window[initFunctionName] === 'function') {
|
||||
window[initFunctionName](currentModuleId);
|
||||
}
|
||||
}
|
||||
|
||||
function loadModuleScript() {
|
||||
loadScript(themeUrl + '/rb.custom/general_ad_section/module.js?ver=' + jsVer, 'general-ad-section-js', finalAction);
|
||||
}
|
||||
|
||||
if (typeof Swiper === 'undefined') {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://unpkg.com/swiper/swiper-bundle.min.css';
|
||||
document.head.appendChild(link);
|
||||
|
||||
loadScript('https://unpkg.com/swiper/swiper-bundle.min.js', 'swiper-bundle-js', loadModuleScript);
|
||||
} else {
|
||||
loadModuleScript();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user