JVCMS is built with PHP + MySQL. Please confirm your server meets the following requirements before deployment:
| Item | Requirement |
|---|---|
| PHP Version | PHP 8.0 ~ 8.5 (PHP 8.5 recommended) |
| Database | MySQL 5.7 |
| Web Server | Nginx / Apache / IIS (URL rewrite required) |
| PHP Extensions | PDO, pdo_mysql, mbstring, openssl, fileinfo |
Configure URL rewriting for your server type after deployment; see the "URL Rewrite" section for the rules.
├── index.php # 前台入口
├── admin.php # 后台入口
├── api.php # 应用市场接口
├── config.php # 数据库配置
├── Application/
│ ├── Controllers/ # 控制器(Web/Admin/Api)
│ ├── Core/ # 内核:Lang、Hook、Setting 等
│ ├── Kernel/Kernel.php # 全局常量与契约定义
│ ├── Models/Repository.php # 数据仓库层
│ ├── Plugin/ # 插件目录
│ └── Template/Engine/ # 模板引擎
├── Template/
│ └── default/ # 默认模板
│ ├── pc/ # PC端模板
│ └── mobile/ # 移动端模板(存在则自动启用)
├── languages/ # 17语言包
└── uploads/ # 上传文件
JVCMS frontend uses pretty URLs with optional language prefixes (e.g. /en/list/4.html):
| URL Pattern | Description |
|---|---|
| /list/{id}.html | Category list page (first page) |
| /list/{id}/{page}.html | Category list page (page N) |
| /article/{id}.html | Article detail page |
| /download/{id}.html | Download detail page |
| /search.html?keyword=xx | Search page |
| /tags/{tag}.html | Tag archive page |
Use the {jv:url} prefix tag in templates to generate language-aware links:
<a href="{jv:url}list/4.html">列表页</a>
<a href="{jv:url}article/123.html">详情页</a>
Choose the rule set matching your web server, save it to the corresponding config file, then reload the service. IIS / Windows requires the URL Rewrite module.
Nginx: add to the site server block or a separate rewrite config file.
# Nginx 伪静态
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
}
}
rewrite ^/[a-z][a-z]/index\.php$ /index.php last;
rewrite ^/[a-z][a-z]-[A-Z][A-Z]/index\.php$ /index.php last;
Apache: save as .htaccess in the site root.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^[a-z][a-z]/index\.php$ index.php [QSA,L]
RewriteRule ^[a-z][a-z]-[A-Z][A-Z]/index\.php$ index.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
IIS / Windows: save as web.config in the site root.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="JVCMS Lang Index" stopProcessing="true">
<match url="^[a-z][a-z]/index\.php$" />
<action type="Rewrite" url="index.php" />
</rule>
<rule name="JVCMS Lang Index Region" stopProcessing="true">
<match url="^[a-z][a-z]-[A-Z][A-Z]/index\.php$" />
<action type="Rewrite" url="index.php" />
</rule>
<rule name="JVCMS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Each template lives in /Template/[code]/ with independent pc/ and mobile/ subdirectories. Switch templates in the admin panel; if mobile/ exists it is used for phone visits, otherwise pc/ is used as fallback.
/Template/blog/
├── pc/
│ ├── header.html # 公共头部
│ ├── footer.html # 公共底部
│ ├── index.html # 首页
│ ├── lists_article.html # 文章列表页
│ ├── article.html # 文章详情页
│ └── skin/ # css/js/images 资源
└── mobile/ # 移动端(可选)
Template files are pure HTML — no PHP code allowed; all data is output via {jv:...} tags. Shared parts are included via the include tag:
{jv:include file='header.html' /}
<div class="main">
{jv:artlist typeid="4" loop="10"}
<a href="{jv:arcurl}">{jv:title}</a>
{/jv:artlist}
</div>
{jv:include file='footer.html' /}
JVCMS ships with 17 languages: zh, zh-HK, hi, en, id, pt, ru, ur, es, ja, bn, vi, de, tr, th, fr, ko. Language packs live in languages/{locale}/web.php (frontend) and admin.php (backend).
Use the lang tag in templates to output multilingual strings:
{jv:lang name='view_more' /}
<!-- languages/en/web.php -->
<?php return ['view_more' => 'View More'];
Build a language switcher with the language loop tag:
{jv:language}
<a href="{jv:language_url}">{jv:name}</a>
{/jv:language}
Detail pages can use these field aliases directly:
| Tag | Description |
|---|---|
| {jv:field.title /} | Title |
| {jv:field.keywords /} | SEO keywords |
| {jv:field.description /} | SEO description |
| {jv:field.content /} | Content body |
| {jv:field.click /} | Clicks |
| {jv:field.pubdate /} | Publish time |
| {jv:field.typename /} | Category name |
| {jv:field.typeurl /} | Category URL |
| {jv:field.arcurl /} | Article URL |
Plugins live in Application/Plugin/[code]/ with plugin.php as the entry. Plugins attach to template hook points or admin menus via the Hook system.
Application/Plugin/myplugin/
├── plugin.php # 插件入口(注册钩子/菜单)
├── config.php # 插件信息
└── ... # 业务文件
Reserve hook points in templates:
{jv:hook name='footer_ad' /}
# 插件内监听
Hook::add('template_footer_ad', function($html, $data){
return $html . '<div>插件输出</div>';
});
Admin integration: a plugin can register its own admin pages and sidebar menus, with GET/POST requests handled through the AdminController plugin routes.
{jv:pagelist /}