@ftchinese/ftc-header
v2.1.2
Published
FTC Header
Downloads
58
Readme
ftc-header
The responsive header component for FTChinese. There are three kinds of headers to choose.
This package provides both js and sass APIs for building these headers.
Install
cd yourProject
npm install "@ftchinese/ftc-header"
NOTE: Please ensure there is a package.json and a bower.json in the root of your project, which can be generated by npm init and bower init
Prepare the html
Before using our APIs, you may first prepare the html code.
Learn about the structure and the components of our header
At this part, I will introduce the root element and the html code fragments of the components of our header. They are just help you to understand the structure and configuration of ftc-header.If you do are not interested in them, you can skip this part and go direct to the next part:The 3 kinds of headers we provide.
The Root
The root element of ftc-header is a header, which should have the attribute data-ftc-component="ftc-header" and the class class="ftc-header":
<header class="ftc-header" data-ftc-component="ftc-header" data-ftc-header--no-js>
</header>
This is the base structure of all kinds of our headers. All the other data are in this header element.
The Lang:
This is a little component for choosing the language of our website, which is at the left of the top line of our header when home page is showed.
The pure html:
<div class="ftc-header__lang" data-ftc-component="ftc-header-lang">
<ul class="ftc-header__lang-list ftc-header__lang-listdefault">
<li class="ftc-header__lang-item">
<a href=#>
简体中文
</a>
</li>
<li class="ftc-header__lang-item">
<a href=http://big5.ftchinese.com/>
繁体中文
</a>
</li>
<li class="ftc-header__lang-item">
<a href=https://www.ft.com/>
英文
</a>
</li>
</ul>
</div>
Or, if you use template, here is the nunjucks template:
<div class="ftc-header__lang" data-ftc-component="ftc-header-lang">
<ul class="ftc-header__lang-list ftc-header__lang-listdefault">
{% for onelang in header.lang.list %}
<li class="ftc-header__lang-item">
<a href={{onelang.url}}>
{{onelang.name}}
</a>
</li>
{% endfor%}
</ul>
</div>
The Sign
The menu about sign in ,sign up or sign out.And if the user has signed in, showing the menu for registered user.
Pure html:
<div data-ftc-component="ftc-header-sign">
<div class="ftc-header__sign-readermenu ftc-header__sign-visitormenu">
<a class="ftc-header__sign-signin" href=http://user.ftchinese.com/login>
登录
</a>
<a href=http://user.ftchinese.com/register>
免费注册
</a>
</div>
<div class="ftc-header__sign-readermenu ftc-header__sign-memebermenu ftc-header__sign--hide">
<a href=/users/mystories>
我的FT
</a>
<a href=/users/cp>
设置
</a>
<a href=http://user.ftchinese.com/logout>
登出
</a>
</div>
</div>
The Nunjucks version is easy, so is omitted here.
And there is another component related to the Sign menu: the loginOverlay. And click the "登录" in Sign will show the loginOverlay instead of navigation to the href if there is loginOVerlay code segment.
The LoginOverlay
Pure html:
<!-- The loginOverlay -->
<div class="ftc-header__loginoverlay" data-ftc-component="ftc-header-loginoverlay">
<div class="ftc-header__loginoverlay-window">
<div class="ftc-header__loginoverlay-title">
登录
<span class="ftc-header__loginoverlay-close">×</span>
</div>
<form method="post" class="ftc-header__loginoverlay-form" action="/users/login"><!-- Add your php file to handle the login or find the password, the "/users/login" is my case -->
<div class="ftc-header__loginoverlay-item ftc-header__loginoverlay-username">
<label for="ftcLoginUsername">
电子邮件/用户名
</label>
<input type="text" name="username" id="ftcLoginUsername">
</div>
<div class="ftc-header__loginoverlay-item">
<label for="ftcLoginPassword">
密码
</label>
<input type="password" class="ftc-header__loginoverlay-oneline" name="password" id="ftcLoginPassword">
</div>
<div class="ftc-header__loginoverlay-saveandsub">
<input class="ftc-header__loginoverlay-saveme" type="checkbox" class="checkbox" value="1" checked="checked" name="saveme" id="ftcLoginSaveme" >
<label for="ftcLoginSaveme">记住我</label>
<input class="ftc-header__loginoverlay-submit" type="submit" value="提交">
</div>
</form>
<div class="ftc-header__loginoverlay-bottom">
<div class="ftc-header__loginoverlay-bottomline">
<a href="/users/findpassword">
找回密码
</a>
</div>
<div class="ftc-header__loginoverlay-bottomline">
<a href="http://user.ftchinese.com/register">
免费注册
</a>
</div>
</div>
</div>
</div>
The Search
It is for searching articles in our web.
<div class="ftc-header__search ftc-header__search-default ftc-header__row" data-ftc-component="ftc-header-search" data-ftc--sticky >
<div class="ftc-header__container">
<form class="ftc-header__search-formregion" action=/search/ role="search"><!-- Add your php file to handle the search, in my case it is "/search/"-->
<button class="ftc-header__search-searchbtn"></button>
<div class="ftc-header__search-inputarea">
<input class="ftc-header__search-input" type="search" placeholder=输入年月日‘xxxx-xx-xx’可搜索该日存档 >
</div>
</form>
</form>
<div class="ftc-header__search-switch">
</div>
</div>
</div>
The Nav
This is the most complicated part. And There are dynamic and static two modes you can choose.
1. dynamic version
The dynamic version is that the data about nav and the actions of nav are both written by js. So after you adding the js, you can change the channel and see the changing effect on a single page. The related js will be discussed later, and the html are very simple:
<nav class="ftc-header__nav" data-ftc-component="ftc-channelnav" role="navigation" aria-label="Main navigation">
<ul class="ftc-header__nav-list ftc-header__nav-toplist" data-ftc--sticky>
</ul>
<ul class="ftc-header__nav-list ftc-header__nav-sublist">
</ul>
</nav>
2. static version
The static version is that the data about nav are computed directly in html template. So I can only provide the templete and the data.
The Nunjucks template:
<nav class="ftc-header__nav" data-ftc-component="ftc-channelnav" role="navigation" aria-label="Main navigation">
<ul class="ftc-header__nav-list ftc-header__nav-toplist" data-ftc--sticky>
{% set subChannels = {} %}
{% for topChannel in header.nav.topChannels %}
<li class={{'"ftc-header__nav-item ftc-header__nav-topitem ftc-header__nav-topitem-selected"' if header.nav.indexForSelectedTopChannel==topChannel.index else '"ftc-header__nav-item ftc-header__nav-topitem"'}} data-index={{topChannel.index}}>
<a data-ftc--target-top href={{topChannel.url}} >{{topChannel.name}}</a>
<ul class="ftc-header__nav-pushdownlist">
{% for pushdownChannel in topChannel.subChannels %}
<li class="ftc-header__nav-pushdownitem" data-index={{pushdownChannel.index}}><a data-ftc--target-pushdown href={{pushdownChannel.url}}>{{pushdownChannel.name}}</a></li>
{% endfor %}
</ul>
</li>
{% if header.nav.indexForSelectedTopChannel==topChannel.index %}
{% set subChannels = topChannel.subChannels %}
{% endif %}
{% endfor %}
</ul>
<ul class="ftc-header__nav-list ftc-header__nav-sublist">
{% for subChannel in subChannels %}
<li class={{ '"ftc-header__nav-item ftc-header__nav-subitem ftc-header__nav-subitem-selected"' if header.nav.indexForSelectedSubChannel==subChannel.index else '"ftc-header__nav-item ftc-header__nav-subitem"' }} data-index={{subChannel.index}}>
<a href={{subChannel.url}}>{{subChannel.name}}</a>
</li>
{% endfor %}
</ul>
</nav>
And the data:
"nav": {
"indexForSelectedTopChannel": 0, //The index of top channel which is default selected.This "0" means the top channel "首页" is default selected.
"indexForSelectedSubChannel": 8, //The index of sub channel which is default selected.This "8" means the sub channel "数据新闻" of the top channel "首页" is default selected.And if there are no subchannel selected ,it should be -1
"topChannels": [
{
"name": "首页",
"url": "#",
"index":0,
"subChannels":[
{
"name":"特别报道",
"url":"http://www.ftchinese.com/channel/special.html",
"index":0
},
{
"name":"热门文章",
"url":"http://www.ftchinese.com/channel/special.html",
"index":1
},
...
{
"name":"数据新闻",
"url":"http://www.ftchinese.com/channel/datanews.html",
"index":8
},
{
"name":"FT研究院",
"url":"http://www.ftchinese.com/m/marketing/intelligence.html",
"index":9
},
{
"name":"FT商城",
"url":"https://shop193762308.taobao.com/",
"index":10
}
]
},
{
"name": "中国",
"url": "http://www.ftchinese.com/channel/china.html",
"index":1,
"subChannels":[
{
"name":"政经",
"url":"http://www.ftchinese.com/channel/chinareport.html",
"index":0
},
...
]
},
{
"name": "全球",
"url": "http://www.ftchinese.com/channel/world.html",
"index":2
},
...
]
}
Go here to see the nav prop to get the completed json data about ftc nav.
The 3 kinds of headers we provide
Full Header:
This is a kind of header which contains the full components of ftc header. And its nav is static, which is the same as our true header in our website.
This is the template (using nunjucks) for full header :
<header class="ftc-header" data-ftc-component="ftc-header" data-ftc-header--no-js>
<!-- The top -->
<div class="ftc-header__top ">
<div class="ftc-header__container">
{% if header.nav.indexForSelectedTopChannel == 0 and header.nav.indexForSelectedSubChannel < 0 %}
{% set isHome = "yes" %}
{% else %}
{% set isHome = "no" %}
{% endif %}
<div class={{'"ftc-header__top-column ftc-header__top-center ftc-header-hometitle"' if isHome == "yes" else '"ftc-header__top-column ftc-header__top-center ftc-header-tagtitle"'}} data-ftc-component="ftc-header-title">
{{header.myTitle if isHome == "no" else " "}}
</div>
<div class="ftc-header__top-column ftc-header__top-left">
{% if isHome == "yes" %}
{% include "partials/lang.html" %}
{% else %}
<div class="ftc-header__brand">
</div>
{% endif %}
<div class="ftc-header__hamburg" data-ftc-component="ftc-header-hamburg">
</div>
</div>
<div class="ftc-header__top-column ftc-header__top-right">
{% include "partials/sign.html" %}
</div>
</div>
</div>
{% if header.nav %}
{% include "partials/navStatic.html" %}
{% endif %}
{% if header.search %}
{% include "partials/search.html" %}
{% endif %}
{% include "partials/loginOverlay.html" %}
</header>
Using above template, you can write both home header and tag header.
If you use the home data, you may build a header which is just like the real header of the home page of our website. The data are like:
{
"lang" :{
"default":"简体中文",
"list": [
{
"name":"简体中文",
"url":"#"
},
{
"name":"繁体中文",
"url":"http://big5.ftchinese.com/"
},
{
"name":"英文",
"url":"https://www.ft.com/"
}
]
},
"signIn":{
"url":"http://user.ftchinese.com/login",
"word":"登录"
},
...
"nav": {
"indexForSelectedTopChannel": 0,
"indexForSelectedSubChannel": -1,
"topChannels": [
{
"name": "首页",
"url": "http://www.ftchinese.com",
"index":0,
"subChannels":[
{
"name":"特别报道",
"url":"http://www.ftchinese.com/channel/special.html",
"index":0
},
{
"name":"热门文章",
"url":"http://www.ftchinese.com/channel/special.html",
"index":1
},
...
]
},
...
]
}
...
But in most cases, you may use the tag data as you are more likely to write another page with a special title which may belong to a top channel and a sub channel. The data are like this:
{
"myTitle":"我的页面",
"signIn":{
"url":"http://user.ftchinese.com/login",
"word":"登录"
},
...
"nav": {
"indexForSelectedTopChannel": 0,
"indexForSelectedSubChannel": 8,
"topChannels": [
{
"name": "首页",
"url": "http://www.ftchinese.com",
"index":0,
"subChannels":[
...
]
},
...
]
}
...
The difference between the home and the tag data is the "indexForSelectedTopChannel" and the "indexForSelectedSubChannel"—— you can to go the part The nave > 2. static version to see more details, and you should provide the field **"myTitle" if you write the tag data.
Go to To home data and tag data to get the full json data of this two cases.
And if you do not want to use the template, go to html results to see the final html.
Simple Header
The Simple Header only contains the core part of FTC's header.
The template:
<header class="ftc-header" data-ftc-component="ftc-header" data-ftc-header--no-js>
<!-- The top -->
<div class="ftc-header__top ">
<div class="ftc-header__container">
<div class={{ '"ftc-header__top-column ftc-header__top-center ftc-header-tagtitle"'if header.myTitle else '"ftc-header__top-column ftc-header__top-center ftc-header-hometitle"' }} data-ftc-component="ftc-header-title">
{{header.myTitle if header.myTitle }}
</div>
<div class="ftc-header__top-column ftc-header__top-right">
{% include "partials/sign.html" %}
</div>
</div>
</div>
{% include "partials/loginOverlay.html" %}
</header>
The data:
{
"signIn":{
"url":"http://user.ftchinese.com/login",
"word":"登录"
},
"signUp":{
"url":"http://user.ftchinese.com/register",
"word":"免费注册"
},
"myFT":{
"url":"/users/mystories",
"word":"我的FT"
},
"mySet":{
"url":"/users/cp",
"word":"设置"
},
"signOut":{
"url":"http://user.ftchinese.com/logout",
"word":"登出"
}
}
And if you want a Simple Header for tag data, you should only add the "myTitle" field.
Dynamic Header
The dynamic header is with the dynamic nav, which is not the real case with our website. But if you what to make a custom single page, the nav of which doesn't need to do some interactive with our website, you may choose this header.
The tempate:
<header class="ftc-header" data-ftc-component="ftc-header" data-ftc-header--no-js>
<!-- The top -->
<div class="ftc-header__top ">
<div class="ftc-header__container">
<div class="ftc-header__top-column ftc-header__top-center ftc-header-hometitle" data-ftc-component="ftc-header-title">
</div>
<div class="ftc-header__top-column ftc-header__top-left">
{% include "partials/lang.html" %}
<div class="ftc-header__brand ftc-header--hide">
</div>
<div class="ftc-header__hamburg" data-ftc-component="ftc-header-hamburg">
</div>
</div>
<div class="ftc-header__top-column ftc-header__top-right">
{% include "partials/sign.html" %}
</div>
</div>
</div>
{% if header.nav %}
{% include "partials/navDynamic.html" %}
{% endif %}
{% if header.search %}
{% include "partials/search.html" %}
{% endif %}
</header>
{% include "partials/loginOverlay.html" %}
The data:
{
"lang" :{
"default":"简体中文",
"list": [
{
"name":"简体中文",
"url":"#"
},
{
"name":"繁体中文",
"url":"http://big5.ftchinese.com/"
},
{
"name":"英文",
"url":"https://www.ft.com/"
}
]
},
"signIn":{
"url":"http://user.ftchinese.com/login",
"word":"登录"
},
"signUp":{
"url":"http://user.ftchinese.com/register",
"word":"免费注册"
},
"myFT":{
"url":"/users/mystories",
"word":"我的FT"
},
"mySet":{
"url":"/users/cp",
"word":"设置"
},
"signOut":{
"url":"http://user.ftchinese.com/logout",
"word":"登出"
},
"nav": true,
"search": {
"actionUrl":"/search/",
"placeholderText":"输入年月日‘xxxx-xx-xx’可搜索该日存档"
}
}
And go here to see the final html.
API for JS
For Full Header
import {FullHeader} from '@ftchinese/ftc-header';
FullHeader.init();
For Simple Header
import {SimpleHeader} from '@ftchinese/ftc-header';
SimpleHeader.init();
For Dynamic Header
import {DynamicHeader} from '@ftchinese/ftc-header';
DynamicHeader.init();
The above method will use the default provided nav data.
If you want to define the nav data by your self, please set the navData to cover the default data before calling DynamicHeader.init() :
import {DynamicHeader} from '@ftchinese/ftc-header';
//Set the navData constant for the nav's js dynamic generation. The navData should be set by this pattern:
var navData = {
"indexForSelectedTopChannel": 0, // The default selected top channel index.
"topChannels": [
{
"name": "首页",
"url": "#",
"index":0,
"subChannels":[
{
"name":"特别报道",
"url":"#",
"index":0
},
{
"name":"热门文章",
"url":"#",
"index":1
},
...
]
},
{
"name": "中国",
"url": "#",
"index":1,
"subChannels":[
{
"name":"政经",
"url":"#",
"index":0
},
...
]
},
{
"name": "全球",
"url": "#",
"index":2
},
{
"name": "经济",
"url": "#",
"index":3
},
...
]
}
DynamicHeader.init();
API for SCSS
The simplest way is to set the $ftc-header-is-silent to be false, and what you need to do is just import the main.scss
$ftc-header-is-silent: false;
@import '@ftchinese/ftc-header/main.scss';
These is propably suitbale for the Full Header and the Dynamic Header.
As for Simple Header, you may choose to include the mixin as you need:
$ftc-header-is-silent: true;
@import '@ftchinese/ftc-header/main.scss';
@include ftcHeaderBase;
@include ftcHeaderTop;
@include ftcHeaderLoginOverlay;