github.com/gohugoio/hugo@v0.88.1/commands/new_theme.go (about)

     1  // Copyright 2018 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package commands
    15  
    16  import (
    17  	"bytes"
    18  	"errors"
    19  	"path/filepath"
    20  	"strings"
    21  	"time"
    22  
    23  	"github.com/gohugoio/hugo/helpers"
    24  	"github.com/gohugoio/hugo/hugofs"
    25  	"github.com/spf13/cobra"
    26  	jww "github.com/spf13/jwalterweatherman"
    27  )
    28  
    29  var _ cmder = (*newThemeCmd)(nil)
    30  
    31  type newThemeCmd struct {
    32  	*baseBuilderCmd
    33  }
    34  
    35  func (b *commandsBuilder) newNewThemeCmd() *newThemeCmd {
    36  	cc := &newThemeCmd{}
    37  
    38  	cmd := &cobra.Command{
    39  		Use:   "theme [name]",
    40  		Short: "Create a new theme",
    41  		Long: `Create a new theme (skeleton) called [name] in ./themes.
    42  New theme is a skeleton. Please add content to the touched files. Add your
    43  name to the copyright line in the license and adjust the theme.toml file
    44  as you see fit.`,
    45  		RunE: cc.newTheme,
    46  	}
    47  
    48  	cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
    49  
    50  	return cc
    51  }
    52  
    53  // newTheme creates a new Hugo theme template
    54  func (n *newThemeCmd) newTheme(cmd *cobra.Command, args []string) error {
    55  	c, err := initializeConfig(false, false, false, &n.hugoBuilderCommon, n, nil)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	if len(args) < 1 {
    61  		return newUserError("theme name needs to be provided")
    62  	}
    63  
    64  	createpath := c.hugo().PathSpec.AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
    65  	jww.FEEDBACK.Println("Creating theme at", createpath)
    66  
    67  	cfg := c.DepsCfg
    68  
    69  	if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
    70  		return errors.New(createpath + " already exists")
    71  	}
    72  
    73  	mkdir(createpath, "layouts", "_default")
    74  	mkdir(createpath, "layouts", "partials")
    75  
    76  	touchFile(cfg.Fs.Source, createpath, "layouts", "index.html")
    77  	touchFile(cfg.Fs.Source, createpath, "layouts", "404.html")
    78  	touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "list.html")
    79  	touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "single.html")
    80  
    81  	baseofDefault := []byte(`<!DOCTYPE html>
    82  <html>
    83      {{- partial "head.html" . -}}
    84      <body>
    85          {{- partial "header.html" . -}}
    86          <div id="content">
    87          {{- block "main" . }}{{- end }}
    88          </div>
    89          {{- partial "footer.html" . -}}
    90      </body>
    91  </html>
    92  `)
    93  	err = helpers.WriteToDisk(filepath.Join(createpath, "layouts", "_default", "baseof.html"), bytes.NewReader(baseofDefault), cfg.Fs.Source)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "head.html")
    99  	touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "header.html")
   100  	touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "footer.html")
   101  
   102  	mkdir(createpath, "archetypes")
   103  
   104  	archDefault := []byte("+++\n+++\n")
   105  
   106  	err = helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), bytes.NewReader(archDefault), cfg.Fs.Source)
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	mkdir(createpath, "static", "js")
   112  	mkdir(createpath, "static", "css")
   113  
   114  	by := []byte(`The MIT License (MIT)
   115  
   116  Copyright (c) ` + time.Now().Format("2006") + ` YOUR_NAME_HERE
   117  
   118  Permission is hereby granted, free of charge, to any person obtaining a copy of
   119  this software and associated documentation files (the "Software"), to deal in
   120  the Software without restriction, including without limitation the rights to
   121  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
   122  the Software, and to permit persons to whom the Software is furnished to do so,
   123  subject to the following conditions:
   124  
   125  The above copyright notice and this permission notice shall be included in all
   126  copies or substantial portions of the Software.
   127  
   128  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   129  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
   130  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
   131  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   132  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   133  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   134  `)
   135  
   136  	err = helpers.WriteToDisk(filepath.Join(createpath, "LICENSE"), bytes.NewReader(by), cfg.Fs.Source)
   137  	if err != nil {
   138  		return err
   139  	}
   140  
   141  	n.createThemeMD(cfg.Fs, createpath)
   142  
   143  	return nil
   144  }
   145  
   146  func (n *newThemeCmd) createThemeMD(fs *hugofs.Fs, inpath string) (err error) {
   147  	by := []byte(`# theme.toml template for a Hugo theme
   148  # See https://github.com/gohugoio/hugoThemes#themetoml for an example
   149  
   150  name = "` + strings.Title(helpers.MakeTitle(filepath.Base(inpath))) + `"
   151  license = "MIT"
   152  licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE"
   153  description = ""
   154  homepage = "http://example.com/"
   155  tags = []
   156  features = []
   157  min_version = "0.41.0"
   158  
   159  [author]
   160    name = ""
   161    homepage = ""
   162  
   163  # If porting an existing theme
   164  [original]
   165    name = ""
   166    homepage = ""
   167    repo = ""
   168  `)
   169  
   170  	err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), fs.Source)
   171  	if err != nil {
   172  		return
   173  	}
   174  
   175  	return nil
   176  }