mirror of
https://github.com/flarum/core.git
synced 2025-08-07 17:07:19 +02:00
Add dedicated tags page
This commit is contained in:
4
extensions/tags/js/bootstrap.js
vendored
4
extensions/tags/js/bootstrap.js
vendored
@@ -17,6 +17,10 @@ app.initializers.add('flarum-tags', function() {
|
|||||||
app.routes['tags'] = ['/tags', TagsPage.component()];
|
app.routes['tags'] = ['/tags', TagsPage.component()];
|
||||||
app.routes['tag'] = ['/t/:tags', IndexPage.component()];
|
app.routes['tag'] = ['/t/:tags', IndexPage.component()];
|
||||||
|
|
||||||
|
app.route.tag = function(tag) {
|
||||||
|
return app.route('tag', { tags: tag.slug() });
|
||||||
|
};
|
||||||
|
|
||||||
// Register models.
|
// Register models.
|
||||||
app.store.models['tags'] = Tag;
|
app.store.models['tags'] = Tag;
|
||||||
Discussion.prototype.tags = Model.many('tags');
|
Discussion.prototype.tags = Model.many('tags');
|
||||||
|
@@ -4,25 +4,26 @@ import NavItem from 'flarum/components/nav-item';
|
|||||||
import Separator from 'flarum/components/separator';
|
import Separator from 'flarum/components/separator';
|
||||||
|
|
||||||
import TagNavItem from 'flarum-tags/components/tag-nav-item';
|
import TagNavItem from 'flarum-tags/components/tag-nav-item';
|
||||||
|
import TagsPage from 'flarum-tags/components/tags-page';
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
// Add a link to the tags page, as well as a list of all the tags,
|
// Add a link to the tags page, as well as a list of all the tags,
|
||||||
// to the index page's sidebar.
|
// to the index page's sidebar.
|
||||||
extend(IndexPage.prototype, 'navItems', function(items) {
|
extend(IndexPage.prototype, 'navItems', function(items) {
|
||||||
items.add('tags', NavItem.component({
|
items.add('tags', NavItem.component({
|
||||||
icon: 'reorder',
|
icon: 'th-large',
|
||||||
label: 'Tags',
|
label: 'Tags',
|
||||||
href: app.route('tags'),
|
href: app.route('tags'),
|
||||||
config: m.route
|
config: m.route
|
||||||
}), {last: true});
|
}), {last: true});
|
||||||
|
|
||||||
|
if (app.current instanceof TagsPage) return;
|
||||||
|
|
||||||
items.add('separator', Separator.component(), {last: true});
|
items.add('separator', Separator.component(), {last: true});
|
||||||
|
|
||||||
var params = this.stickyParams();
|
var params = this.stickyParams();
|
||||||
var tags = app.store.all('tags');
|
var tags = app.store.all('tags');
|
||||||
|
|
||||||
items.add('untagged', TagNavItem.component({params}), {last: true});
|
|
||||||
|
|
||||||
var addTag = tag => {
|
var addTag = tag => {
|
||||||
var currentTag = this.currentTag();
|
var currentTag = this.currentTag();
|
||||||
var active = currentTag === tag;
|
var active = currentTag === tag;
|
||||||
|
@@ -1,38 +1,75 @@
|
|||||||
import Component from 'flarum/component';
|
import Component from 'flarum/component';
|
||||||
import WelcomeHero from 'flarum/components/welcome-hero';
|
import WelcomeHero from 'flarum/components/welcome-hero';
|
||||||
|
import IndexPage from 'flarum/components/index-page';
|
||||||
import icon from 'flarum/helpers/icon';
|
import icon from 'flarum/helpers/icon';
|
||||||
|
import listItems from 'flarum/helpers/list-items';
|
||||||
|
import abbreviateNumber from 'flarum/utils/abbreviate-number';
|
||||||
|
import humanTime from 'flarum/helpers/human-time';
|
||||||
|
|
||||||
|
import sortTags from 'flarum-tags/utils/sort-tags';
|
||||||
|
|
||||||
export default class TagsPage extends Component {
|
export default class TagsPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.categories = m.prop(app.store.all('categories'));
|
this.tags = sortTags(app.store.all('tags').filter(tag => !tag.parent()));
|
||||||
|
|
||||||
|
app.current = this;
|
||||||
|
app.history.push('tags');
|
||||||
}
|
}
|
||||||
|
|
||||||
view() {
|
view() {
|
||||||
return m('div.categories-area', [
|
var pinned = this.tags.filter(tag => tag.position() !== null);
|
||||||
m('div.title-control.categories-forum-title', app.config.forum_title),
|
var cloud = this.tags.filter(tag => tag.position() === null);
|
||||||
WelcomeHero.component(),
|
|
||||||
|
return m('div.tags-area', {config: this.onload.bind(this)}, [
|
||||||
|
IndexPage.prototype.hero(),
|
||||||
m('div.container', [
|
m('div.container', [
|
||||||
m('ul.category-list.category-list-tiles', [
|
m('nav.side-nav.index-nav', [
|
||||||
m('li.filter-tile', [
|
m('ul', listItems(IndexPage.prototype.sidebarItems().toArray()))
|
||||||
m('a', {href: app.route('index'), config: m.route}, 'All Discussions'),
|
]),
|
||||||
// m('ul.filter-list', [
|
m('div.offset-content.tags-content', [
|
||||||
// m('li', m('a', {href: app.route('index'), config: m.route}, m('span', [icon('star'), ' Following']))),
|
m('ul.tag-tiles', [
|
||||||
// m('li', m('a', {href: app.route('index'), config: m.route}, m('span', [icon('envelope-o'), ' Inbox'])))
|
pinned.map(tag => {
|
||||||
// ])
|
var lastDiscussion = tag.lastDiscussion();
|
||||||
|
var children = app.store.all('tags').filter(child => {
|
||||||
|
var parent = child.parent();
|
||||||
|
return parent && parent.id() == tag.id();
|
||||||
|
});
|
||||||
|
|
||||||
|
return m('li.tag-tile', {style: 'background-color: '+tag.color()}, [
|
||||||
|
m('a.tag-info', {href: app.route.tag(tag), config: m.route}, [
|
||||||
|
m('h3.name', tag.name()),
|
||||||
|
m('p.description', tag.description()),
|
||||||
|
children ? m('div.children', children.map(tag =>
|
||||||
|
m('a', {href: app.route.tag(tag), config: m.route, onclick: (e) => e.stopPropagation()}, tag.name())
|
||||||
|
)) : ''
|
||||||
|
]),
|
||||||
|
lastDiscussion
|
||||||
|
? m('a.last-discussion', {
|
||||||
|
href: app.route.discussion(lastDiscussion, lastDiscussion.lastPostNumber()),
|
||||||
|
config: m.route
|
||||||
|
}, [m('span.title', lastDiscussion.title()), humanTime(lastDiscussion.lastTime())])
|
||||||
|
: m('span.last-discussion')
|
||||||
|
]);
|
||||||
|
})
|
||||||
]),
|
]),
|
||||||
this.categories().map(category =>
|
m('div.tag-cloud', [
|
||||||
m('li.category-tile', {style: 'background-color: '+category.color()}, [
|
m('h4', 'Tags'),
|
||||||
m('a', {href: app.route('category', {categories: category.slug()}), config: m.route}, [
|
m('div.tag-cloud-content', cloud.map(tag =>
|
||||||
m('h3.title', category.title()),
|
m('a', {href: app.route.tag(tag), config: m.route, style: tag.color() ? 'color: '+tag.color() : ''}, tag.name())
|
||||||
m('p.description', category.description()),
|
))
|
||||||
m('span.count', category.discussionsCount()+' discussions'),
|
])
|
||||||
])
|
|
||||||
])
|
|
||||||
)
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onload(element, isInitialized, context) {
|
||||||
|
IndexPage.prototype.onload.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
onunload() {
|
||||||
|
IndexPage.prototype.onunload.apply(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -212,3 +212,123 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.tag-tiles {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
& > li {
|
||||||
|
float: left;
|
||||||
|
width: ~"calc(50% - 1px)";
|
||||||
|
height: 200px;
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-radius: @border-radius-base 0 0 0;
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
border-radius: 0 @border-radius-base 0 0;
|
||||||
|
}
|
||||||
|
&:nth-last-child(2):nth-child(even), &:last-child {
|
||||||
|
border-radius: 0 0 @border-radius-base 0;
|
||||||
|
}
|
||||||
|
&:nth-last-child(2):nth-child(odd), &:last-child:nth-child(odd) {
|
||||||
|
border-radius: 0 0 0 @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tag-tile {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&, & a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
& .tag-info, & .last-discussion {
|
||||||
|
padding: 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
& > a {
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: fade(#000, 10%);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background: fade(#000, 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& .tag-info {
|
||||||
|
top: 0;
|
||||||
|
bottom: 55px;
|
||||||
|
padding-right: 20px;
|
||||||
|
|
||||||
|
& .name {
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
& .description {
|
||||||
|
color: fade(#fff, 50%);
|
||||||
|
margin: 0 0 15px;
|
||||||
|
}
|
||||||
|
& .children {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& .last-discussion {
|
||||||
|
bottom: 0;
|
||||||
|
height: 55px;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
padding-top: 17px;
|
||||||
|
padding-bottom: 17px;
|
||||||
|
color: fade(#fff, 50%);
|
||||||
|
|
||||||
|
& .title {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tag-cloud {
|
||||||
|
margin-top: 30px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
& h4 {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: @fl-body-muted-color;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
.fa();
|
||||||
|
content: @fa-var-tags;
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tag-cloud-content {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&, & a {
|
||||||
|
color: @fl-body-muted-color;
|
||||||
|
}
|
||||||
|
& a {
|
||||||
|
margin: 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user