…`map[string]string` to `map[string]interface{}`.
This allows values other than `string` values to be saved to Author,
such as:
```toml
# config.toml
…
[Author]
name = "Austin Ziegler"
social-site = [ "Facebook", "Twitter", "GitHub" ]
```
My specific use-case is that I’m trying to make something work similar
whether it’s specified in `.Params.Author` or in `.Site.Author` without
introducing `.Site.Params.Author`.
`GroupBy` is modified to allow it to receive a method name argument for
example `Type` as its first argument. It is only allowed to call with
a method which takes no arguments and returns a result or a pair of
a result and an error.
The functions discussed at #443 are also added
- `ByPublishDate`: Order contents by `PublishDate` front matter variable
- `GroupByPublishDate(format, order)`: Group contents by `PublishDate`
front matter variable formatted in string like `GroupByDate`
- `GroupByParam(key, order)`: Group contents by `Param` front matter
variable specified by `key` argument
- `GroupByParamDate(key, format, order)`: Group contents by `Param`
front matter variable specified by `key` argument and formatted in
string like `GroupByDate`. It's effective against `time.Time` type
front matter variable
Prior to this commit, `HasMenuCurrent` and `IsMenuCurrent` on `Node` always returned false.
This made it hard (if possible at all) to mark the currently selected menu item/group for non-Page content (home page, category pages etc.), i.e. for menus defined in the site configuration.
This commit provides an implementation of these two methods.
Notable design choices:
* These menu items have a loose coupling to the the resources they navigate to; the `Url` is the best common identificator. To facilitate a consistent matching, and to get it in line with the menu items connected to `Page`, relative Urls (Urls starting with '/') for menu items in the site configuration are converted to permaLinks using the same rules used for others’.
* `IsMenuCurrent` only looks at the children of the current node; this is in line with the implementation on `Page`.
* Due to this loose coupling, `IsMenuCurrent` have to search downards in the tree to make sure that the node is inside the current menu. This could have been made simpler if it could answer `yes` to any match of any menu item matching the current resource.
This commit also adds a set of unit tests for the menu system.
Fixes#367
TOML and YAML handles integers differently, creating issues when using integer values from configuration or front matter in the First template function.
This currently works in YAML (parses into int), but not in TOML (parses into int64).
This commit modifies First so it accepts any int.
Fixes#551
The Intersect template-method would fail if one or both of the lists were nil (post vs page; post has tags, page has not).
This commit adds a nil-check and returns an empty result if any of the inputs are nil.
See #537
If content pages are fully rendered in a list page, footnotes that use
the same reference (`[^fn]`) will have duplicated anchors. This change
builds on #526 to put the page filename (`Page.File.Name`) as part of
the anchor for a footnote.
This would fix discussion [116](http://discuss.gohugo.io/t/footnote-references-are-duplicated-on-list-pages/116).
- The config file can provide FootnoteAnchorPrefix, which will be used
by blackfriday when rendering to HTML. A value of `q:` has the effect
of making the anchor for a footnote `[^footie]` be `fn:q:footie`. The
default is `""`.
- The config file can provide FootnoteReturnLinkContents, which will be
used by blackfriday when rendering to HTML. A value of `^` has the
effect of making the return link be `^` instead of `[return]`.
Node.Site.Recent is not really just recent pages, but all pages, so I figured it was better to add a new parameter with a more informative name.
I also changed the code slightly so that all pages are added to the list of pages before we start rendering shortcodes... this way you can use a shortcode to refer to another page. Previosuly, this had been broken, because the list ofg pages would not be fully populated while the shortcodes were being processed. The code that does this is not reading from disk or doing any rendering, so it shouldn't take any more time to do.
This fixes#450. There are two problems:
1.) We're creating a new goroutine for every page.
2.) We're calling s.Pages = append(s.Pages, page) inside each goroutine.
1 is a problem if in that if you have a ton of pages, that's a ton of goroutines. It's not really useful to have more than a few goroutines at a time, and lots can actually make your code much slower, and, evidently, crash.
2 is a problem in that append is not thread safe. Sometimes it returns a new slice with a larger capacity, when the original slice isn't large enough. This can cause problems if two goroutines do this at the same time.
The solution for 1 is to use a limited number of workers (I chose 2*GOMAXPROCS as a nice guess).
The solution for 2 is to serialize access to s.Pages, which I did by doing it in a single goroutine.
Mainly this was a change to helpers.MakePermalink, but to get the local server to run correctly,
we needed to redirect the path of the request from /foo to /. In addition, I added tests for the
server's code for fixing up the base url with different config file & CLI options.
git bisect identified 62dd1d4 as the breaking commit; when
github.com/spf13/viper was introduced, the Params field was always
empty.
Given a map in YAML in Viper, the return type is
`map[interface{}]interface{}`, _not_ `map[string]interface{}`, even if
`.SetDefault()` has been called with an item of
`map[string]interface{}{}` so the cast assertion on the `.Get("Params")`
always failed.
Viper stores Permalinks as a map[string]interface{}, so the type assertion
to PermalinkOverrides (map[string]PathPattern) will always fail.
We can, however, get Permalinks as a map[string]string, and convert each
value to a PathPattern.
If you don't have access to the root domain of your site (eg a GitHub project
page) and you try to generate custom permalinks, they must begin with a slash.
Go's URL resolution library sees the leading slash and thinks "this URL starts
at the root", just like a filesystem - so it discards your subdomain and maps
all custom permalinks from the root of your site. Fine if you control the root
domain, not so useful if you don't.
Removing the check for a leading slash fixes this problem. You can now specify
custom permalinks that do not start with a slash, and they will map safely
regardless of what subdomain you upload the generated site under.
Tests have been updated for this commit so that they continue to function.
Modified markdownRender and markdownRenderWithTOC in hugolib/page.go to
use the same flags and extensions as were previously used when we simply
called blackfriday.MarkdownCommon to convert Markdown to HTML. These
flags/extensions were dropped during the refactor that added the
`.TableOfContents` page variable, and caused features like Markdown
tables to no longer work.
Modified the expected output for TestTableOfContents in page_test.go,
apparently changing the flags/extensions caused an `—` to become
`–`.
Added TableOfContents field to hugolib.Page struct. New function
getTableOfContents is used in convertMarkdown to set the TableOfContents
field.
Added new test file hugolib/page_toc_test.go with a simple test of the
new functionality.
Conflicts:
hugolib/page.go
Be able to inhibit AbsURL canonicalization of content, on a site
configuration basis. Advantages of being able to inhibit this include
making it easier to rendering on other hostnames, and being able to
include resources on http or https depending on how this page was
retrieved, avoiding mixed-mode client complaints without adding latency
for plain http.
Fixed windows uses different filepath separator. The filepath.ToSlash
shouldn't be used, because it can cause errors in filepath suffix and prefix
testing since "c:\a" isn't a prefix of "c:/a/b/c".
A sample config.yaml for a site might contain:
```yaml
permalinks:
post: /:year/:month/:title/
```
Then, any article in the `post` section, will have the canonical URL
formed via the permalink specification given.
Signed-off-by: Noah Campbell <noahcampbell@gmail.com>
* Add `.Truncated` bool to each page; will be set true if the
`.Summary` is truncated and it's worth showing a "more" link of some
kind.
* Add `Params` to the site config, defining `.Site.Params` accessible
to each page; this lets the site maintainer associate arbitrary data
with names, on a site-wide basis.
* Provide a `First` function to templates:
* Use-case: `{{range First 5 .Site.Recent}}` or anything else which
is a simple iterable provided by hugolib
* Tests by me for `.Truncated` and `First`
Also @noahcampbell contributed towards this:
* Add UnitTest for `.Site.Params`:
> Digging into this test case a bit more, I'm realizing that we need
> to create a param test case to ensure that for each type we render
> (page, index, homepage, rss, etc.) that the proper fields are
> represented. This will help us refactor without fear in the
> future.
Sample config.yaml:
```yaml
title: "Test site"
params:
Subtitle: "More tests always good"
AuthorName: "John Doe"
SidebarRecentLimit: 5
```
Signed-off-by: Noah Campbell <noahcampbell@gmail.com>
Remove the hugo-nav since it relied on a slow library. The current
build reimplements the absurl functionality based on string replace.
Discovered that my prior implementation missed the requirement for
making absolute paths (/path) absolute with the host, whereas a relative
path is left untouched. Updated the test cases to support this if this
is reimplemented.
Checks to make sure the xml document starts with <?xml. Previously, the
html translate package would write additional details into the document
that caused it to fail.
50% speedup. Fix#91
to run the benchmark:
go test -test.run=NONE -bench=".*" -test.benchmem=true ./transform/ > new.txt
to compare the results:
/usr/local/go/misc/benchcmp baseline.txt new.txt
Speedup and memory improvements
benchmark old ns/op new ns/op delta
BenchmarkChain 101219 50453 -50.15%
BenchmarkTransform 51625 45531 -11.80%
benchmark old allocs new allocs delta
BenchmarkChain 222 103 -53.60%
BenchmarkTransform 135 106 -21.48%
benchmark old bytes new bytes delta
BenchmarkChain 23919 10998 -54.02%
BenchmarkTransform 11858 10665 -10.06%
Removed these checks so a single file in content can generate a site.
For example, given a site with a content directory and an index.html,
running hugo -s dir will generate a project without any more input.
The render code path would use a fallback if there was an exception.
This change instead relies on explicit declaration of the layout to use
and includes a check to see if the layout indeed exists before
attempting to render it.
If a file named index.html exists in a directory, or root, it will be
rendered as if ugly urls are turned on. This allows for top level
content to not need a supporting layout file and content in content.
This change should not affect anyone who is using the perscribed way.
I also cleaned up a bunch of one off functions in site.go.
Allow content that is not markdown and does not need to be rendered to
exists in the content directory. Currently any valid html or xml
document can exist. Templates are applied to these documents as well.
If you need to have content that doesn't have templates or AbsUrlify
like operations, then continue to put this content in static and it will
be copied over.
As pages are read from the target, they will be assessed if they should
be rendered or not. The logic for IsRenderable is in the parser/page.go
and looks for anything exception '<'.
I want to move all logic to writing aliases to target so I can pave the
way for writing aliases specific to other runtimes (like .htaccess for
apache or a script for updating AWS or symlinking on a filesystem).
filepath was used inconsistently throughout the hugolib. With the
introduction of source and target modules, all path are normalized to
"/". This simplifies the processing of paths. It does mean that
contributors need to be aware of using path/filepath in any module other
than source or target is not recommended. The current exception is
hugolib/config.go
It started with wanting to move templates in template bundles and the
rest followed. I did my best to start grouping related functions
together, but there are some that I missed. There is also the method
Urlize that seems to be a special function used in both worlds. I'll
need to revisit this method.
Tests to ensure rendering dates in templates is working correctly.
Actually, I was running into invalid templates not giving warnings when
I was trying to render a date.
Introducing the target module in hugo. This provides the simple
interface for writing content given a label (filename) and a io.Reader
containing the content to be written.
If site.Target is not set, it defaults back to the original behavior of
writing to file system.
In hugolib/site_url_test.go I have an InMemoryTarget for testing
purposes and use it to see if the final output of a render matches.
Allow full control of summaries which can be rendered as html rather
than text. Using a `<!--more-->` html comment in your markdown / rst
you can indiciate where the summary should end and have the summary
converted to html.
Signed-off-by: Noah Campbell <noahcampbell@gmail.com>
Conflicts:
hugolib/page_test.go