Requirements

JVCMS is built with PHP + MySQL. Please confirm your server meets the following requirements before deployment:

ItemRequirement
PHP VersionPHP 8.0 ~ 8.5 (PHP 8.5 recommended)
DatabaseMySQL 5.7
Web ServerNginx / Apache / IIS (URL rewrite required)
PHP ExtensionsPDO, pdo_mysql, mbstring, openssl, fileinfo

Installation

  • Upload the JVCMS release to your web root and extract it
  • Create a MySQL database (utf8 charset)
  • Visit your domain to open the install wizard and fill in database info
  • After installation, remove/protect install.php and log in to the admin panel

Configure URL rewriting for your server type after deployment; see the "URL Rewrite" section for the rules.

Directory Structure

├── 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/               # 上传文件

URL Routing

JVCMS frontend uses pretty URLs with optional language prefixes (e.g. /en/list/4.html):

URL PatternDescription
/list/{id}.htmlCategory list page (first page)
/list/{id}/{page}.htmlCategory list page (page N)
/article/{id}.htmlArticle detail page
/download/{id}.htmlDownload detail page
/search.html?keyword=xxSearch page
/tags/{tag}.htmlTag 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>

URL Rewrite

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>

Template Development

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' /}

Multilingual

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 Fields

Detail pages can use these field aliases directly:

TagDescription
{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

Plugin Development

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.

Pagination

  • Each category can define its own page size in admin (1-200, default 10)
  • Pagination appears automatically when total articles exceed the page size
  • Pagination URL: /list/4.html (page 1), /list/4/2.html (page 2)
  • Pagination includes first / prev / page numbers / next / last with the current page highlighted
{jv:pagelist /}