Problem Summary
From Redmine:
Root Cause Analysis
ต้องการทำให้ระบบสามารถรองรับการปรับแต่งได้ทุกอย่างสำหรับลูกค้าทุกราย
โดยจะต้องมีโค้ดชุดเดียว แต่สามารถรองรับการปรับแต่งได้ทุกอย่างสำหรับลูกค้าทุกราย
Monorepo, Less Customization
From Redmine:
ต้องการทำให้ระบบสามารถรองรับการปรับแต่งได้ทุกอย่างสำหรับลูกค้าทุกราย
โดยจะต้องมีโค้ดชุดเดียว แต่สามารถรองรับการปรับแต่งได้ทุกอย่างสำหรับลูกค้าทุกราย
Monorepo, Less Customization
Version: 2.0 (Final)
Style: Plugin-First Monorepo (Intranet & OPAC)
สถาปัตยกรรมนี้รวบรวมไฟล์ Customization ทั้งหมด (Logic, CGI, Templates, Assets) ไว้ใน Koha Plugin เพียงแห่งเดียว เพื่อให้ง่ายต่อการ Deploy, Version Control และรองรับ Multi-tenant ผ่าน Feature Flags โดยใช้เทคนิค Symlink และ Apache Rewrite ในการเชื่อมต่อเข้ากับ Core System ของ Koha อย่างปลอดภัย
ตำแหน่งไฟล์จริงจะอยู่ภายในโฟลเดอร์ของ Plugin ทั้งหมด
Base Path: /var/lib/koha/{instance}/plugins/Koha/Plugin/Punsarn/Core/
Koha/Plugin/Punsarn/Core/
├── lib/
│ └── C4/
│ └── Templates.pm # Modified Core with "Fallback" logic
├── cgi-bin/
│ ├── intranet/ # Custom .pl for Staff Client
│ └── opac/ # Custom .pl for OPAC
├── templates/
│ ├── intranet/ # Custom .tt/.inc for Staff Client
│ └── opac/ # Custom .tt/.inc for OPAC
├── assets/ # Frontend Assets
│ ├── css/
│ └── js/
├── config/
│ └── features.yaml # Feature Flags Configuration
└── PunsarnCore.pm # Main Plugin File (Asset Injection Logic)
สร้าง Symlink เพื่อ Map ไฟล์จาก Plugin เข้าสู่โครงสร้างของ Koha (รันด้วย user root หรือ koha):
PLUGIN_PATH="/var/lib/koha/{instance}/plugins/Koha/Plugin/Punsarn/Core"
Intranet CGI
ln -s "$PLUGIN_PATH/cgi-bin/intranet" /usr/share/koha/intranet/cgi-bin/punsarn
OPAC CGI
ln -s "$PLUGIN_PATH/cgi-bin/opac" /usr/share/koha/opac/cgi-bin/punsarn
Intranet Templates
บังคับให้ Perl โหลด Module จาก Plugin ก่อน (เพื่อใช้ C4::Templates ที่แก้ Logic แล้ว)
/etc/default/koha-commonPERL5LIB="/var/lib/koha/{instance}/plugins/Koha/Plugin/Punsarn/Core/lib:/usr/share/koha/lib"
แก้ไข /etc/apache2/sites-available/koha-common.conf เพื่อทำ Shadowing ไฟล์ CGI Scripts
<VirtualHost *:8080>
# ... existing config ...
RewriteEngine On
# [Logic] Intranet CGI Override
# เช็คว่ามีไฟล์ชื่อเดียวกันใน folder 'punsarn' (Symlink) หรือไม่?
RewriteCond %{REQUEST_URI} ^/cgi-bin/koha/(.*)\.pl$
RewriteCond /usr/share/koha/intranet/cgi-bin/punsarn/%1.pl -f
# ถ้ามี ให้ Rewrite ไปใช้ไฟล์นั้น (Pass-Through to Plack)
RewriteRule ^/cgi-bin/koha/(.*)\.pl$ /cgi-bin/koha/punsarn/$1.pl [PT,L]
# ... existing config ...
</VirtualHost>
<VirtualHost *:80>
# ... existing config ...
RewriteEngine On
# [Logic] OPAC CGI Override
RewriteCond %{REQUEST_URI} ^/cgi-bin/koha/opac-(.*)\.pl$
RewriteCond /usr/share/koha/opac/cgi-bin/punsarn/opac-%1.pl -f
RewriteRule ^/cgi-bin/koha/opac-(.*)\.pl$ /cgi-bin/koha/opac/punsarn/opac-$1.pl [PT,L]
# ... existing config ...
</VirtualHost>
config/features.yamlfeatures:
new_header_design:
enabled: true
css: ["assets/css/header_v2.css"]
js: ["assets/js/mega_menu.js"]
custom_circulation_rules:
enabled: false
PunsarnCore.pm)ใช้ Hooks ในการ Inject JS/CSS ตาม Config
sub intranet_js {
my ($self) = @_;
return $self->_inject_assets('intranet', 'js');
}
sub opac_css {
my ($self) = @_;
return $self->_inject_assets('opac', 'css');
}
sub _inject_assets {
my ($self, $interface, $type) = @_;
# 1. Load YAML Config
# 2. Iterate enabled features
# 3. Return HTML string (<script src="..."> or <link href="...">)
}
Deployment:
.kp)./etc/default/koha-common.Code Updates:
.pm หรือ .pl ต้อง systemctl restart koha-common (เพื่อ clear Plack cache).Koha Upgrades (Critical):
CI/CD:
How can someone verify that the fix is working correctly? Include steps, commands, or queries.