平台概述
开发者指引
开发文档
平台政策
联系我们
主题开发快速入门
前言
主题是EduSoho的插件之一,是通过HTML及JavaScript开发的可插拔的应用;主要是展现给用户良好的交互界面;此文档即对如何开发主题进行了详细的说明,供开发者参考使用。EduSoho的主题样式是基于bootstrap定义的,所以要制作主题样式之前需要一定的bootstrap基础。 在bootstrap的基础上您可以制做任意风格、任意布局的主题,只要你能发挥出想像。
主题的目录结构说明
| 目录地址 | 说明 |
| web/themes | 主题的根目录 |
| web/themes/autumn | autumn为主题名称 |
| web/themes/autumn/TopxiaWebBundle/views | 主页面目录 |
| web/themes/autumn/css | css样式目录 |
| web/themes/autumn/js | javascript目录 |
| web/themes/autumn/img | 图片资源目录 |
创建主题
1.创建主题的目录
此文档以建一个名为“天之蓝”的主题作为例子,创建一个名为blue的主题标准目录结构.在blue目录下创建文件theme.json文件,内容如下:
{
"name": "天之蓝 [主题名称]",
"author": "drools [作者]",
"version": "1.0 [版本号]",
"supprot_version": "1.0+ [兼容EduSoho版本号]",
"date": "2013-11-09 [发布日期]",
"thumb": "img/theme.jpg [主题图标]"
}
EduSoho会自动扫描web/themes/XXX/theme.json文件,并将theme.json里面的数据显示到"管理后台"->"系统"->"全局设置"->"主题设置"
在“主题设置”中已经显示了刚刚定义的主题,点击“使用”后使用该主题。
2.创建布局
文件地址:web/themes/blue/TopxiaWebBundle/views/layout.html.twig
{% import "TopxiaWebBundle::macro.html.twig" as web_macro %}
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class=""> <!--<![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %} {{ setting('site.name', 'EDUSOHO') }} - {% if setting('site.slogan') %}{{ setting('site.slogan') }} -{% endif %} Powered by EDUSOHO{% endblock %}</title>
<meta name="keywords" content="{% block keywords %}{% endblock %}" />
<meta name="description" content="{% block description %}{% endblock %}" />
<meta content="{{ csrf_token('site') }}" name="csrf-token" />
{{ setting('login_bind.verify_code', '')|raw }}
{% if setting('site.favicon') %}
<link href="{{ asset(setting('site.favicon')) }}" rel="shortcut icon" />
{% endif %}
{% block stylesheets %}
<link href="{{ asset('assets/libs/gallery2/bootstrap/3.1.1/css/bootstrap.css') }}" rel="stylesheet" />
<link rel="stylesheet" media="screen" href="{{ asset('assets/css/common.css') }}" />
<link rel="stylesheet" media="screen" href="{{ asset('assets/css/bootstrap-extends.css') }}" />
<!-- 在这加入自定义的CSS样式表 -->
<!--[if lt IE 8]>
<link href="{{ asset('assets/css/oldie.css') }}" rel="stylesheet">
<![endif]-->
{% endblock %}
<!--[if lt IE 9]>
<script src="{{ asset('assets/libs/html5shiv.js') }}"></script>
<![endif]-->
<!--[if IE 8]>
<script src="{{ asset('assets/libs/respond.min.js') }}"></script>
<![endif]-->
{% block head_scripts %}{% endblock %}
</head>
<body {% if bodyClass|default('') %}class="{{ bodyClass }}"{% endif %}>
{% block body %}
<!-- 头部页面布局代码 -->
{% block topbanner %}{% endblock %}
{% block content %}{% endblock %}
{% block bottom %}{% endblock %}
<div id="login-modal" class="modal" data-url="{{ path('login_ajax') }}"></div>
<div id="modal" class="modal"></div>
{% endblock %}
{% include 'TopxiaWebBundle::script_boot.html.twig' with {script_main: asset('bundles/topxiaweb/js/app.js')} %}
</body>
</html>
在这个布局文件<body>里面是空的,只有给模板是继承预留了block
定义头部布局
3.创建首页
文件地址:web/themes/blue/TopxiaWebBundle/views/Default/index.html.twig
{% extends 'TopxiaWebBundle:Default:layout.html.twig' %}
{% block topbanner %}{% endblock %}
{% block content %}{% endblock %}
{% block bottom %}{% endblock %}
一个空白的主题框架已经搭好了,现在访问首页会是一个空白界面。
制作主题
此文档将分头部、内容模板、底部来分别阐述如何制作一个完整的主题。1.制作头部
头部界面布局的代码可以放在web/themes/blue/TopxiaWebBundle/views/layout.html.twig的{% block body %}标签里面。头部界面示意:
这个头部界面可分为几块:网站Logo栏、搜索栏、登录栏、菜单栏,整个头部界面的布部如下:
<div class="head">
<div class="container">
<div class="row">
<div id="head-top">
<!-- 网站Logo栏 -->
<div id="header_logo" class="col-sm-3">
{% if setting('site.logo') %}
<a class="navbar-brand-logo" href="{{ path('homepage') }}"><img src="{{ asset(setting('site.logo')) }}"></a>
{% else %}
<a class="navbar-brand" href="{{ path('homepage') }}">{{ setting('site.name', 'EDUSOHO') }}</a>
{% endif %}
</div>
<!-- 搜索栏 -->
<div id="search_block_top" class="col-sm-5 clearfix">
<form id="searchbox" class="navbar-form navbar-left clearfix" role="search" action="/search">
<div class="form-group">
<input type="search" id="search_query_top" placeholder="" name="q" maxLength="40">
<button type="submit" class="btn button-search iconfont icon-sousuo1"></button>
</div>
</form>
</div>
<!-- 登录栏 -->
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
{% if app.user %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img class="img-circle" src="{{ file_path(app.user.smallAvatar, 'avatar.png') }}">
<p>我</p></a>
<ul class="dropdown-menu">
<li><a href="{{ path('user_show', {id:app.user.id}) }}"><i class="glyphicon glyphicon-home"></i> 我的主页</a></li>
<li><a href="{{ path('settings') }}"><i class="glyphicon glyphicon-cog"></i> 帐号设置</a></li>
{% if is_granted('ROLE_ADMIN') %}
<li><a href="{{ path('admin') }}"><i class="glyphicon glyphicon-lock"></i> 管理后台</a></li>
{% endif %}
<li><a href="{{ path('logout') }}"><i class="glyphicon glyphicon-off"></i> 退出</a></li>
</ul>
</li>
<li><a href="{{ path('my') }}"> <span class="iconfont icon-iconbook"></span><p>课程</p></a></li>
<li>
<a href="{{ path('message') }}" class="badge-container message-badge-container">
<span class="iconfont icon-email"></span>
<p>消息</p>
{% if app.user.newMessageNum > 0 %}<i class="badge">{{ app.user.newMessageNum }}</i>{% endif %}
</a>
</li>
<li>
<a href="{{ path('notification') }}" class="badge-container notification-badge-container">
<span class="iconfont icon-wushenglaba"></span>
<p>通知</p>
{% if app.user.newNotificationNum > 0 %}<i class="badge">{{ app.user.newNotificationNum }}</i>{% endif %}</a>
</li>
{% else %}
<li><a href="{{ path('login') }}"> <span class="iconfont icon-login"></span><p>登录</p></a></li>
<li><a href="{{ path('register') }}"> <span class="iconfont icon-zhuce"></span><p>注册</p></a></li>
{% endif %}
</ul>
</div>
</div>
</div>
<!-- 菜单栏 -->
<div id="block_top_menu" class="row">
<div class="stickUpTop" style="position: relative; top: 0px;">
<div>
<ul class="sf-menu clearfix menu-content">
<li><a href="/" title="首页">首页</a></li>
<li><a href="/course/explore" title="课程">课程</a></li>
<li><a href="/" title="直播">直播</a></li>
<li><a href="/teacher" title="教题团队">教题团队</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
代码详解:
- 1.网站Logo栏:分析网站Logo栏的代码会发现,当管理员没有设置网站的Logo 时,会显示网站默认的Logo
- 2.搜索栏:在搜索栏里面是一个form表单,表单中包含一个文件框和一个按钮
- 3.登录栏:在登录栏里面有两种状态,在登录状态下{% if app.user %}显示我的个人中心、课程、消息、通知;在没有登录的情况下只显示“登录”,“注册”两个按钮。
- 4.菜单栏:在菜单栏中放置几个连接作为菜单。
2.制作内容模板
在内容区域可以填充多个内容模板,每个内容模板尽量遵循简单、独立、易用的原则,以方便后续的升级维护等工作。在开发内容模板之前,您得先了解API文档,只有了解了每块数据如何获取和使用之后,才能开发出更好的应用。此文档列举了一些常用内容模板的开发作为例子。2.1最新课程列表模板
创建web/themes/blue/TopxiaWebBundle/Default/category-course.html.twig文件作为模板文件。
{% import "TopxiaWebBundle::macro.html.twig" as web_macro %}
<!-- course 为模板定义一个样式es-box,主要申明布局的大小、边距等样式 -->
<div class="es-box es-course">
<h2>最新课程</h2>
<!-- 获取最新课程列表 LatestCourses -->
{% set count = 3 %}
{% set categoryId = null %}
{% set courses = data('LatestCourses',{'count':count, 'categoryId':categoryId}) %}
<!-- 当有课程数据时,显示课程 -->
{% if courses %}
{% set mode = mode|default('default') %}
<ul class="row">
<!-- 遍历Course -->
{% for course in courses %}
<!-- 单个课程的布局 -->
<li class="col-sm-6 col-md-4 es-course-list">
<div>
<div class="course-top">
<img src="{{ file_path(course.largePicture, 'course-large.png') }}" class="img-responsive thumb">
</div>
<div class="course-bottom">
<h4>{{ course.title }}</h4>
<p class="metas clearfix">
{% if course.price > 0 %}
<span class="price-num">¥{{ course.price }}</span>
{% else %}
<span class="price-num">免费</span>
{% endif %}
{% if course.showStudentNumType == 'opened' %}
<span class="student-num">{{ course.studentNum }}人报名</span>
{% endif %}
</p>
<span class="nickname">
{% for teacher in course.teachers %}
{{ web_macro.user_link(teacher, 'text-muted') }}
{% endfor %}
</span>
</div>
<!-- 当鼠标hover时显示mask里的信息,hover显示控制要在js中进行处理 -->
<div class="mask">
<a href="{{ path('course_show', {id:course.id}) }}">
{% set teacher = course.teachers|first %}
<div class="teacher-info clearfix">
<img class="img-circle pull-left" src="{{ file_path(teacher.smallAvatar, 'avatar.png') }}">
<span>{{ teacher.nickname }}</span>
<span>{{ teacher.title|plain_text(10) }}</span>
</div>
<p>{{ teacher.profile.about|plain_text(50) }}</p>
<span class="iconfont icon-jiantou"></span>
<h4 class="title">{{ course.title|plain_text(8) }}</h4>
</a>
</div>
</div>
</li>
{% endfor %}
</ul>
<!-- 当没有课程数据时,显示“还没有发布的课程” -->
{% else %}
<div class="empty">还没有发布的课程</div>
{% endif %}
<a class="more" href="{{ path('course_explore',{category:config.categoryId|default(null)}) }}">更多></a>
</div>
2.2推荐教师模板
创建web/themes/blue/TopxiaWebBundle/Default/recommend-teacher.html.twig文件作为模板文件。
{% import "TopxiaWebBundle::macro.html.twig" as web_macro %}
<!-- teacher -->
<div class="es-box teachers">
<h2>{{ 教师风采 }}</h2>
<!-- 获取推荐教师数据 LatestCourses -->
{% set teachers = data('RecommendTeachers',{'count':10}) %}
{% if teachers %}
<ul class="row">
<!-- 遍历teachers -->
{% for teacher in teachers %}
{% if teacher %}
<li class="col-sm-6 col-md-4">
<div class="teachers-item">
<a href="{{ path('user_show', {id:teacher.id}) }}">
<img class="img-circle" src="{{ file_path(teacher.mediumAvatar, 'avatar.png') }}">
</a>
<span>{{ web_macro.user_link(teacher) }}</span>
<i> {{ teacher.title }}</i>
<p> {{ teacher.about|plain_text(30) }}</p>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
<!-- 当没有课程数据时,显示"尚未设置推荐老师,请在管理后台设置" -->
{% else %}
<div class="empty">尚未设置推荐老师,请在管理后台设置。</div>
{% endif %}
<a class="more" href="{{ path('teacher') }}">更多></a>
</div>
3.制作底部
底部页面一般有如下几块内容组成:网站Logo、版权信息、底部导航、课程存档和备案信息。 创建web/themes/blue/TopxiaWebBundle/Default/complex-bottom.html.twig文件作为模板文件。
<div id="footer-sec" class="hidden-xs ">
<div class="container clearfix htmlcontenttop">
<div class="copyright">
<!-- 网站Logo -->
{% if setting('site.logo') %}
<a class="site-footer-logo" href="{{ path('homepage') }}"><img src="{{ asset(setting('site.logo')) }}"></a>
{% else %}
<a class="site-footer-logo" href="{{ path('homepage') }}">{{ setting('site.name', 'EDUSOHO') }}</a>
{% endif %}
<!-- 版权信息 -->
<p>{% include "TopxiaWebBundle::powered-by.html.twig" %} </p>
</div>
<div class="footer-container">
<!-- 底部导航 -->
{{ render(controller('TopxiaWebBundle:Default:footNavigation')) }}
<!-- 课程存档 -->
<a href="{{ path('course_archive') }}">课程存档</a>
{% if setting('site.copyright') %}
课程内容版权均归<a href="/">{{ setting('site.copyright') }}</a>所有
{% endif %}
<!-- 备案信息 -->
{% if setting('site.icp') %}
<a href="http://www.miibeian.gov.cn/" target="_blank">{{ setting('site.icp') }}</a>
{% endif %}</p>
{{ setting('site.analytics')|raw }}
</div>
</div>
</div>
这个底部使用到的参数说明:
4.使用模板
模板的使用方式采用twig标记语法如下
{% include 'TopxiaWebBundle:Default:category-course.html.twig' %}
在主页面引用模板示例:
{% extends 'TopxiaWebBundle:Default:layout.html.twig' %}
{% block topbanner %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-9">
{% include 'TopxiaWebBundle:Default:category-course.html.twig'%}
{% include 'TopxiaWebBundle:Default:recommend-teacher.html.twig'%}
</div>
</div>
{% endblock %}
{% block bottom %}{% include 'TopxiaWebBundle:Default:complex-bottom.html.twig' %}{% endblock %}