diff --git a/src/coffee/constants.coffee b/src/coffee/constants.coffee index 5ee7fa62b..4824efb3b 100644 --- a/src/coffee/constants.coffee +++ b/src/coffee/constants.coffee @@ -68,6 +68,9 @@ Url.mod = _.template "/browse/<%= modSlug %>/" Url.modData = _.template "/data/<%= modSlug %>/mod.cg" Url.modIcon = _.template "/browse/<%= modSlug %>/icon.png" Url.modVersionData = _.template "/data/<%= modSlug %>/<%= modVersion %>/mod-version.cg" +Url.tutorial = _.template "/browse/<%= modSlug %>/tutorials/<%= tutorialSlug %>/" +Url.tutorialData = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>.cg" +Url.tutorialIcon = _.template "/browse/<%= modSlug %>/tutorials/<%= tutorialSlug %>/icon.png" exports.UrlParam = UrlParam = {} UrlParam.quantity = 'count' diff --git a/src/coffee/controllers/markdown_section_controller.coffee b/src/coffee/controllers/markdown_section_controller.coffee new file mode 100644 index 000000000..52c3139d6 --- /dev/null +++ b/src/coffee/controllers/markdown_section_controller.coffee @@ -0,0 +1,40 @@ +### +Crafting Guide - markdown_section_controller.coffee + +Copyright (c) 2015 by Redwood Labs +All rights reserved. +### + +BaseController = require './base_controller' + +######################################################################################################################## + +module.exports = class MarkdownSectionController extends BaseController + + constructor: (options={})-> + options.model ?= '' + options.title ?= 'Description' + options.templateName = 'markdown_section' + super options + + @title = options.title + + # BaseController Overrides ##################################################################### + + onDidRender: -> + @$title = @$('h2') + @$markdownPanel = @$('.markdown') + super + + refresh: -> + @$title.html @title + + @$markdownPanel.empty() + @$markdownPanel.html _.parseMarkdown @model + super + + # Backbone.View Overrides ###################################################################### + + events: -> + return _.extend super, + 'click .markdown': 'routeLinkClick' diff --git a/src/coffee/controllers/mod_page_controller.coffee b/src/coffee/controllers/mod_page_controller.coffee index 634723043..600ca93fc 100644 --- a/src/coffee/controllers/mod_page_controller.coffee +++ b/src/coffee/controllers/mod_page_controller.coffee @@ -11,6 +11,7 @@ ItemGroupController = require './item_group_controller' Mod = require '../models/mod' ModPack = require '../models/mod_pack' PageController = require './page_controller' +TutorialController = require './tutorial_controller' {Duration} = require '../constants' {Text} = require '../constants' {Url} = require '../constants' @@ -55,15 +56,17 @@ module.exports = class ModPageController extends PageController onDidRender: -> @adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper' - @$name = @$('.name') - @$byline = @$('.byline p') - @$description = @$('.description p') - @$documentationLink = @$('.documentation') - @$downloadLink = @$('.download') - @$homePageLink = @$('.homePage') - @$groupContainer = @$('.itemGroups') - @$titleImage = @$('.titleImage img') - @$versionSelector = @$('select.version') + @$name = @$('.name') + @$byline = @$('.byline p') + @$description = @$('.description p') + @$documentationLink = @$('.documentation') + @$downloadLink = @$('.download') + @$homePageLink = @$('.homePage') + @$groupContainer = @$('.itemGroups') + @$titleImage = @$('.titleImage img') + @$tutorialsSection = @$('.tutorials') + @$tutorialsContainer = @$('.tutorials .panel') + @$versionSelector = @$('select.version') super @@ -83,6 +86,7 @@ module.exports = class ModPageController extends PageController @_refreshLink @$downloadLink, @model.downloadUrl @_refreshItemGroups() + @_refreshTutorials() @_refreshVersions() super @@ -128,7 +132,7 @@ module.exports = class ModPageController extends PageController while @_groupControllers.length > groupIndex + 1 controller = @_groupControllers.pop() - controller.$el.slideUp duration:Duration.normal, -> @remove() + controller.$el.slideUp duration:Duration.normal, complete:-> @remove() _refreshLink: ($link, url)-> if url? @@ -137,6 +141,32 @@ module.exports = class ModPageController extends PageController else $link.slideUp duration:Duration.normal + _refreshTutorials: -> + @_tutorialControllers ?= [] + tutorials = @model.tutorials + + if tutorials.length is 0 + @$tutorialsSection.addClass 'hidden' + else + @$tutorialsSection.removeClass 'hidden' + + index = 0 + for tutorial in tutorials + controller = @_tutorialControllers[index] + if not controller? + controller = new TutorialController model:tutorial + controller.render() + @$tutorialsContainer.append controller.$el + @_tutorialControllers.push controller + else + controller.model = model + + index += 1 + + while @_tutorialControllers.length > index + controller = @_tutorialControllers.pop() + controller.$el.slideUp duration:Duration.normal, complete:-> @remove() + _refreshVersions: -> @$versionSelector.empty() return unless @model? diff --git a/src/coffee/controllers/tutorial_controller.coffee b/src/coffee/controllers/tutorial_controller.coffee new file mode 100644 index 000000000..8c590d582 --- /dev/null +++ b/src/coffee/controllers/tutorial_controller.coffee @@ -0,0 +1,39 @@ +### +Crafting Guide - tutorial_controller.coffee + +Copyright (c) 2015 by Redwood Labs +All rights reserved. +### + +BaseController = require './base_controller' +{Url} = require '../constants' + +######################################################################################################################## + +module.exports = class TutorialController extends BaseController + + constructor: (options={})-> + if not options.model? then throw new Error 'options.model is required' + options.templateName = 'tutorial' + super options + + # BaseController Overrides ##################################################################### + + onDidRender: -> + @$icon = @$('img') + @$link = @$('a') + @$title = @$('p') + super + + refresh: -> + templateData = modSlug:@model.modSlug, tutorialSlug:@model.slug + @$icon.attr 'src', Url.tutorialIcon templateData + @$link.attr 'href', Url.tutorial templateData + @$title.html @model.name + super + + # Backbone.View Overrides ###################################################################### + + events: -> + return _.extend super, + 'click a': 'routeLinkClick' diff --git a/src/coffee/controllers/tutorial_page_controller.coffee b/src/coffee/controllers/tutorial_page_controller.coffee new file mode 100644 index 000000000..45a9f03ff --- /dev/null +++ b/src/coffee/controllers/tutorial_page_controller.coffee @@ -0,0 +1,127 @@ +### +Crafting Guide - tutorial_page_controller.coffee + +Copyright (c) 2015 by Redwood Labs +All rights reserved. +### + +AdsenseController = require './adsense_controller' +BaseController = require './base_controller' +MarkdownSectionController = require './markdown_section_controller' +{Event} = require '../constants' +{Url} = require '../constants' + +######################################################################################################################## + +module.exports = class TutorialPageController extends BaseController + + constructor: (options={})-> + if not options.modSlug? then throw new Error 'options.modSlug is required' + if not options.tutorialSlug? then throw new Error 'options.tutorialSlug is required' + if not options.modPack? then throw new Error 'options.modPack is required' + + options.model ?= null + options.templateName = 'tutorial_page' + super options + + @modPack = options.modPack + @imageLoader = options.imageLoader + @modSlug = options.modSlug + @tutorialSlug = options.tutorialSlug + + @modPack.on Event.change, => @_resolveTutorial() + @_resolveTutorial() + + # BaseController Overrides ##################################################################### + + onDidRender: -> + @adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper' + + @$byline = @$('.byline') + @$bylineLink = @$('.byline a') + @$name = @$('.name') + @$officialLink = @$('a.officialPage') + @$sectionsContainer = @$('.sections') + @$title = @$('h1.name') + @$titleImage = @$('.titleImage img') + super + + refresh: -> + if @model? and @model.isLoaded + @$el.removeClass 'hidden' + else + @$el.addClass 'hidden' + + @_refreshByline() + @_refreshOfficialUrl() + @_refreshSections() + @_refreshTitle() + super + + # Private Methods ############################################################################## + + _refreshByline: -> + if @model? + @$byline.removeClass 'hidden' + @$bylineLink.html @modPack.getMod(@modSlug).name + @$bylineLink.attr 'href', Url.mod modSlug:@modSlug + else + @$byline.addClass 'hidden' + + _refreshOfficialUrl: -> + if @model?.officialUrl? + @$officialLink.attr 'href', @model.officialUrl + @$officialLink.removeClass 'hidden' + else + @$officialLink.addClass 'hidden' + + _refreshTitle: -> + if @model? + @$title.html @model.name + @$titleImage.attr 'src', Url.tutorialIcon modSlug:@modSlug, tutorialSlug:@tutorialSlug + else + @$title.empty() + @$titleImage.removeAttr 'src' + + _refreshSections: -> + @_sectionControllers ?= [] + index = 0 + + if @model? + for section in @model.sections + controller = @_sectionControllers[index] + if not controller? + controller = new MarkdownSectionController title:section.title, model:section.content + controller.render() + @$sectionsContainer.append controller.$el + @_sectionControllers.push controller + else + controller.title = section.title + controller.model = section.model + controller.refresh() + + index += 1 + + while @_sectionControllers.length > index + controller = @_sectionController.pop() + controller.$el.fadeOut duration:Duration.normal, complete:-> @remove() + + _resolveTutorial: -> + return if @model? + + mod = @modPack.getMod @modSlug + if not mod? + logger.error => "cannot find the mod for: #{@modSlug}" + router.navigate '/', trigger:true + return + + if not mod.isLoaded + mod.fetch() + return + + @model = mod.getTutorial @tutorialSlug + if not @model? + logger.error => "mod #{@modSlug} doesn't have a tutorial for: #{@tutorialSlug}" + return + + @model.fetch() diff --git a/src/coffee/crafting_guide_router.coffee b/src/coffee/crafting_guide_router.coffee index ec32b5044..6a5f3e06d 100644 --- a/src/coffee/crafting_guide_router.coffee +++ b/src/coffee/crafting_guide_router.coffee @@ -16,6 +16,7 @@ ItemSlug = require './models/item_slug' Mod = require './models/mod' ModPack = require './models/mod_pack' ModPageController = require './controllers/mod_page_controller' +TutorialPageController = require './controllers/tutorial_page_controller' Storage = require './models/storage' UrlParams = require './url_params' {ProductionEnvs} = require './constants' @@ -64,13 +65,14 @@ module.exports = class CraftingGuideRouter extends Backbone.Router @_recordPageView() routes: - '(/)': 'route__home' - 'browse(/)': 'route__browse' - 'browse/:modSlug(/)': 'route__browseMod' - 'browse/:modSlug/:itemSlug(/)': 'route__browseModItem' - 'configure(/)': 'route__configure' - 'craft(/)': 'route__craft' - 'craft/:text': 'route__craft' + '(/)': 'route__home' + 'browse(/)': 'route__browse' + 'browse/:modSlug(/)': 'route__browseMod' + 'browse/:modSlug/:itemSlug(/)': 'route__browseModItem' + 'browse/:modSlug/tutorials/:tutorialSlug(/)': 'route__browseTutorial' + 'configure(/)': 'route__configure' + 'craft(/)': 'route__craft' + 'craft/:text': 'route__craft' 'item/:itemSlug': 'deprecated__item' 'crafting/(:text)': 'deprecated__crafting' @@ -100,6 +102,10 @@ module.exports = class CraftingGuideRouter extends Backbone.Router controller = new ItemPageController _.extend {itemSlug:slug}, @_defaultOptions @_setPage 'browseModItem', controller + route__browseTutorial: (modSlug, tutorialSlug)-> + controller = new TutorialPageController _.extend {modSlug:modSlug, tutorialSlug:tutorialSlug}, @_defaultOptions + @_setPage 'browseTutorial', controller + route__configure: -> @_setPage 'configure', new ConfigurePageController _.extend {}, @_defaultOptions diff --git a/src/coffee/models/item_page.coffee b/src/coffee/models/item_page.coffee index 4500a01b7..2638475a6 100644 --- a/src/coffee/models/item_page.coffee +++ b/src/coffee/models/item_page.coffee @@ -22,7 +22,7 @@ module.exports = class ItemPage extends BaseModel compileDescription: -> return null unless @item?.description? - description = markdown.parse @item.description, 'Maruku' + description = _.parseMarkdown @item.description return description findComponentInItems: -> diff --git a/src/coffee/models/mod.coffee b/src/coffee/models/mod.coffee index fa0edea5b..7c7715c9a 100644 --- a/src/coffee/models/mod.coffee +++ b/src/coffee/models/mod.coffee @@ -16,6 +16,7 @@ module.exports = class Mod extends BaseModel constructor: (attributes={}, options={})-> if not attributes.slug? then throw new Error 'attributes.slug is required' + attributes.author ?= '' attributes.description ?= '' attributes.documentationUrl ?= null @@ -23,11 +24,13 @@ module.exports = class Mod extends BaseModel attributes.homePageUrl ?= null attributes.modPack ?= null attributes.name ?= '' + super attributes, options @_activeModVersion = null @_activeVersion = null @_modVersions = [] + @_tutorials = [] Object.defineProperties this, 'activeModVersion': { get:-> @_activeModVersion } @@ -107,6 +110,31 @@ module.exports = class Mod extends BaseModel # Property Methods ############################################################################# + getActiveVersion: -> + return @_activeVersion + + setActiveVersion: (version)-> + return if version is @_activeVersion + + version ?= Mod.Version.None + if version is Mod.Version.Latest then version = _.last(@_modVersions).version + + if version is Mod.Version.None + @_activeVersion = version + @_activateModVersion null + + @trigger Event.change + ':activeVersion', this, @_activeVersion + @trigger Event.change, this + else + for modVersion in @_modVersions + if version is modVersion.version + @_activateModVersion modVersion + break + + @_activeVersion = version + @trigger Event.change + ':activeVersion', this, @_activeVersion + @trigger Event.change, this + addModVersion: (modVersion)-> return unless modVersion? return if @_modVersions.indexOf(modVersion) isnt -1 @@ -136,30 +164,22 @@ module.exports = class Mod extends BaseModel return null - getActiveVersion: -> - return @_activeVersion + addTutorial: (tutorial)-> + return unless tutorial? + if @getTutorial(tutorial.slug)? then throw new Error "duplicate tutorial: #{tutorial.name}" + @_tutorials.push tutorial + tutorial.modSlug = @slug - setActiveVersion: (version)-> - return if version is @_activeVersion + getAllTutorials: -> + return @_tutorials[..] - version ?= Mod.Version.None - if version is Mod.Version.Latest then version = _.last(@_modVersions).version + getTutorial: (tutorialSlug)-> + for tutorial in @_tutorials + return tutorial if tutorial.slug is tutorialSlug + return null - if version is Mod.Version.None - @_activeVersion = version - @_activateModVersion null - - @trigger Event.change + ':activeVersion', this, @_activeVersion - @trigger Event.change, this - else - for modVersion in @_modVersions - if version is modVersion.version - @_activateModVersion modVersion - break - - @_activeVersion = version - @trigger Event.change + ':activeVersion', this, @_activeVersion - @trigger Event.change, this + Object.defineProperties @prototype, + tutorials: { get:@prototype.getAllTutorials } # Backbone.View Overrides ###################################################################### diff --git a/src/coffee/models/parser_versions/mod_parser_v1.coffee b/src/coffee/models/parser_versions/mod_parser_v1.coffee index 3c2c25f50..f244fb301 100644 --- a/src/coffee/models/parser_versions/mod_parser_v1.coffee +++ b/src/coffee/models/parser_versions/mod_parser_v1.coffee @@ -8,6 +8,7 @@ All rights reserved. CommandParserVersionBase = require './command_parser_version_base' Mod = require '../mod' ModVersion = require '../mod_version' +Tutorial = require '../tutorial' ######################################################################################################################## @@ -47,17 +48,23 @@ module.exports = class ModParserV1 extends CommandParserVersionBase if downloadUrl.length is 0 then throw new Error 'downloadUrl cannot be empty (omit it instead)' @_rawData.downloadUrl = downloadUrl - _command_name: (name)-> - if @_rawData.name? then throw new Error 'duplicate declaration of "name"' - if name.length is 0 then throw new Error '"name" cannot be empty' - @_rawData.name = name - _command_homePageUrl: (homePageUrl='')-> if @_rawData.homePageUrl? then throw new Error 'duplicate declaration of "homePageUrl"' if homePageUrl.length is 0 then throw new Error 'homePageUrl cannot be empty' @_rawData.homePageUrl = homePageUrl + _command_name: (name)-> + if @_rawData.name? then throw new Error 'duplicate declaration of "name"' + if name.length is 0 then throw new Error '"name" cannot be empty' + @_rawData.name = name + + _command_tutorial: (nameParts...)-> + name = nameParts.join(', ').trim() + if name.length is 0 then throw new Error '"name" cannot be empty' + @_rawData.tutorialNames ?= [] + @_rawData.tutorialNames.push name + _command_version: (version='')-> if version.length is 0 then throw new Error 'version cannot be empty' @@ -78,5 +85,9 @@ module.exports = class ModParserV1 extends CommandParserVersionBase model.name = rawData.name model.homePageUrl = rawData.homePageUrl + if rawData.tutorialNames? + for tutorialName in rawData.tutorialNames + model.addTutorial new Tutorial name:tutorialName + for version in rawData.versions model.addModVersion new ModVersion modSlug:model.slug, version:version diff --git a/src/coffee/models/parser_versions/tutorial_parser_v1.coffee b/src/coffee/models/parser_versions/tutorial_parser_v1.coffee new file mode 100644 index 000000000..c5bf37df3 --- /dev/null +++ b/src/coffee/models/parser_versions/tutorial_parser_v1.coffee @@ -0,0 +1,65 @@ +### +Crafting Guide - tutorial_parser_v1.coffee + +Copyright (c) 2014-2015 by Redwood Labs +All rights reserved. +### + +CommandParserVersionBase = require './command_parser_version_base' +Tutorial = require '../tutorial' + +######################################################################################################################## + +module.exports = class TutorialParserV1 extends CommandParserVersionBase + + # CommandParserVersionBase Overrides ########################################################### + + _buildModel: (rawData, model)-> + @_buildTutorial rawData, model + + _unparseModel: (builder, model)-> + @_unparseTutorial builder, model + + # Command Methods ############################################################################## + + _command_content: (contentParts...)-> + if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"' + if @_rawData.currentSection.content? then throw new Error 'duplicate declaration of content' + content = contentParts.join(', ').trim() + if not content.length > 0 then throw new Error 'content cannot be empty' + + @_rawData.currentSection.content = content + + _command_officialUrl: (officialUrl)-> + if @_rawData.officialUrl? then throw new Error 'duplicate declaration of "officialUrl"' + if officialUrl.length is 0 then throw new Error 'officialUrl cannot be empty' + @_rawData.officialUrl = officialUrl + + _command_section: (textParts...)-> + @_rawData.sections ?= [] + @_rawData.sections.push @_rawData.currentSection = {} + + _command_title: (titleParts...)-> + if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"' + if @_rawData.currentSection.title? then throw new Error 'duplicate declaration of title' + title = titleParts.join(', ').trim() + if not title.length > 0 then throw new Error 'title cannot be empty' + + @_rawData.currentSection.title = title + + _command_video: (youTubeId, nameParts...)-> + if not youTubeId?.length then throw new Error 'video declaration requires a YouTubeID' + name = nameParts.join ', ' + if not name?.length then throw new Error 'video declaration requires a name' + + @_rawData.videos ?= [] + @_rawData.videos.push youTubeId:youTubeId, name:name + + # Object Building Methods ###################################################################### + + _buildTutorial: (rawData, model)-> + if not rawData.sections? then throw new Error 'the "section" declaration is required' + + model.officialUrl = rawData.officialUrl + model.videos = rawData.videos + model.sections = rawData.sections diff --git a/src/coffee/models/tutorial.coffee b/src/coffee/models/tutorial.coffee new file mode 100644 index 000000000..1ca03a6d5 --- /dev/null +++ b/src/coffee/models/tutorial.coffee @@ -0,0 +1,35 @@ +### +Crafting Guide - tutorial.coffee + +Copyright (c) 2015 by Redwood Labs +All rights reserved. +### + +BaseModel = require './base_model' +TutorialParser = require './tutorial_parser' +{Url} = require '../constants' + +######################################################################################################################## + +module.exports = class Tutorial extends BaseModel + + constructor: (attributes={}, options={})-> + if not attributes.name?.length > 0 then throw new Error "attributes.name cannot be empty" + attributes.modSlug ?= null + attributes.officialUrl ?= null + attributes.sections ?= [] + attributes.slug ?= _.slugify attributes.name + attributes.videos ?= [] + super attributes, options + + # Backbone.Model Overrides ##################################################################### + + parse: (text)-> + TutorialParser = require './tutorial_parser' # to avoid require cycles + @_parser ?= new TutorialParser model:this + @_parser.parse text + + return null # prevent calling `set` + + url: -> + return Url.tutorialData modSlug:@modSlug, tutorialSlug:@slug diff --git a/src/coffee/models/tutorial_parser.coffee b/src/coffee/models/tutorial_parser.coffee new file mode 100644 index 000000000..21d83127b --- /dev/null +++ b/src/coffee/models/tutorial_parser.coffee @@ -0,0 +1,19 @@ +### +Crafting Guide - tutorial_parser.coffee + +Copyright (c) 2014-2015 by Redwood Labs +All rights reserved. +### + +VersionedParserBase = require './versioned_parser_base' +TutorialParserV1 = require './parser_versions/tutorial_parser_v1' + +######################################################################################################################## + +module.exports = class TutorialParser extends VersionedParserBase + + # VersionedParserBase Overrides ################################################################ + + _createParsers: (options)-> + return result = + '1': new TutorialParserV1 options diff --git a/src/coffee/underscore_mixins.coffee b/src/coffee/underscore_mixins.coffee index 707227cca..a4d9e0c9b 100644 --- a/src/coffee/underscore_mixins.coffee +++ b/src/coffee/underscore_mixins.coffee @@ -1,5 +1,5 @@ ### -Crafting Guide - underscore.coffee +Crafting Guide - underscore_mixins.coffee Copyright (c) 2014-2015 by Redwood Labs All rights reserved. @@ -7,6 +7,9 @@ All rights reserved. _.mixin + parseMarkdown: (text)-> + return markdown.parse text, 'Maruku' + slugify: (text)-> return null unless text? diff --git a/src/jade/templates/markdown_section.jade b/src/jade/templates/markdown_section.jade new file mode 100644 index 000000000..1e77bb761 --- /dev/null +++ b/src/jade/templates/markdown_section.jade @@ -0,0 +1,10 @@ +//- +//- Crafting Guide - markdown_section.jade +//- +//- Copyright (c) 2015 by Redwood Labs +//- All rights reserved. +//- + +.view__markdown_section.section + h2 + .panel.markdown diff --git a/src/jade/templates/mod_page.jade b/src/jade/templates/mod_page.jade index 3b950dce0..f0145fdc3 100644 --- a/src/jade/templates/mod_page.jade +++ b/src/jade/templates/mod_page.jade @@ -20,4 +20,8 @@ .byline: p .description: p + .tutorials.section + h2 Tutorials + .panel + .itemGroups diff --git a/src/jade/templates/tutorial.jade b/src/jade/templates/tutorial.jade new file mode 100644 index 000000000..2ab96ca96 --- /dev/null +++ b/src/jade/templates/tutorial.jade @@ -0,0 +1,11 @@ +//- +//- Crafting Guide - tutorial.jade +//- +//- Copyright (c) 2015 by Redwood Labs +//- All rights reserved. +//- + +.view__tutorial + a + img + .caption: p \ No newline at end of file diff --git a/src/jade/templates/tutorial_page.jade b/src/jade/templates/tutorial_page.jade new file mode 100644 index 000000000..4029c040d --- /dev/null +++ b/src/jade/templates/tutorial_page.jade @@ -0,0 +1,19 @@ +//- +//- Crafting Guide - tutorial_page.jade +//- +//- Copyright (c) 2015 by Redwood Labs +//- All rights reserved. +//- + +.view__tutorial_page + .sidebar + .titleImage: a: img + a.officialPage.externalLink(target="new"): p Offical Documentation + + .view__adsense + + .mainBody + h1.name + .byline: p from + + .sections diff --git a/src/scss/classes.scss b/src/scss/classes.scss index 4ad3695ce..7879fb392 100644 --- a/src/scss/classes.scss +++ b/src/scss/classes.scss @@ -5,6 +5,16 @@ Copyright (C) 2015 by Redwood Labs All rights reserved. */ +.byline { + margin: 0.25em 0 2em 0; + + p { + font-family: $font-family-normal; + font-size: $font-size-normal; + font-style: italic; + } +} + .centered { text-align: center; } @@ -22,6 +32,20 @@ All rights reserved. .error-new { background: $color-error-new !important; } +.hidden { + max-height: 0; + opacity: 0; +} + +.mainBody { + position: relative; width: 81.25%; + + display: inline-block; + padding: 1em; + padding-top: 2em; + vertical-align: top; +} + .sidebar { position: relative; width: 18.75%; @@ -53,15 +77,6 @@ All rights reserved. } } -.mainBody { - position: relative; width: 81.25%; - - display: inline-block; - padding: 1em; - padding-top: 2em; - vertical-align: top; -} - .section { margin-top: 3em; @@ -86,4 +101,4 @@ All rights reserved. background: white; padding: 1em; } -} \ No newline at end of file +} diff --git a/src/scss/tags.scss b/src/scss/tags.scss index 3d1665d0e..93fbc2efe 100644 --- a/src/scss/tags.scss +++ b/src/scss/tags.scss @@ -48,6 +48,12 @@ h1 { font-family: $font-family-header; font-size: $font-size-xx-large; } + + &.name { + font-family: $font-family-header; + font-size: $font-size-x-large; + margin: 0; + } } h2 { diff --git a/src/scss/templates/index.scss b/src/scss/templates/index.scss index b72f3f7c7..19bc6da1e 100644 --- a/src/scss/templates/index.scss +++ b/src/scss/templates/index.scss @@ -23,4 +23,5 @@ All rights reserved. @import 'mod_page'; @import 'mod_selector'; @import 'stack'; +@import 'tutorial'; @import 'video'; diff --git a/src/scss/templates/item_page.scss b/src/scss/templates/item_page.scss index 3358a9d92..137385cf1 100644 --- a/src/scss/templates/item_page.scss +++ b/src/scss/templates/item_page.scss @@ -24,22 +24,6 @@ All rights reserved. } .mainBody { - h1.name { - font-family: $font-family-header; - font-size: $font-size-x-large; - margin: 0; - } - - .byline { - display: none; - margin: 0.25em 0 2em 0; - - p { - font-family: $font-family-normal; - font-size: $font-size-normal; - font-style: italic; - } - } .recipes { display: none; diff --git a/src/scss/templates/mod_page.scss b/src/scss/templates/mod_page.scss index b29173afb..5d2670b72 100644 --- a/src/scss/templates/mod_page.scss +++ b/src/scss/templates/mod_page.scss @@ -23,22 +23,6 @@ All rights reserved. .mainBody { - .name { - font-family: $font-family-header; - font-size: $font-size-x-large; - margin: 0; - } - - .byline { - margin: 0.25em 0 2em 0; - - p { - font-family: $font-family-normal; - font-size: $font-size-normal; - font-style: italic; - } - } - .description { margin-bottom: 4em; diff --git a/src/scss/templates/tutorial.scss b/src/scss/templates/tutorial.scss new file mode 100644 index 000000000..2d4065e69 --- /dev/null +++ b/src/scss/templates/tutorial.scss @@ -0,0 +1,28 @@ +/* +Crafting Guide - tutorial.scss + +Copyright (C) 2015 by Redwood Labs +All rights reserved. +*/ + +.view__tutorial { + position: relative; + display: inline-block; + margin-left: 1em; + vertical-align: top; + + &:first-child { + margin-left: 0; + } + + .caption { + position: relative; width: 100%; + display: block; + + p { + margin-top: 0.5em; + font-weight: bold; + text-align: center; + } + } +} \ No newline at end of file diff --git a/static/browse/buildcraft/tutorials/gates/icon.png b/static/browse/buildcraft/tutorials/gates/icon.png new file mode 100644 index 000000000..4ee0debda Binary files /dev/null and b/static/browse/buildcraft/tutorials/gates/icon.png differ diff --git a/static/data/buildcraft/mod.cg b/static/data/buildcraft/mod.cg index 078e9ef32..503e00854 100644 --- a/static/data/buildcraft/mod.cg +++ b/static/data/buildcraft/mod.cg @@ -8,3 +8,5 @@ documentationUrl: http://www.mod-buildcraft.com/wiki/doku.php downloadUrl: http://www.mod-buildcraft.com/download/ version: 6.2.6 + +tutorial: Gates diff --git a/static/data/buildcraft/tutorials/gates.cg b/static/data/buildcraft/tutorials/gates.cg new file mode 100644 index 000000000..8892d22e0 --- /dev/null +++ b/static/data/buildcraft/tutorials/gates.cg @@ -0,0 +1,7 @@ +schema: 1 + +section: + title: Gates + content: <<-END + This is the gate tutorial. It's short. + END \ No newline at end of file