Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b3fb5fa87 | |||
| 5f7c17b900 | |||
| 9ade6d983e | |||
| f464b6dc11 | |||
| 8c811d5638 | |||
| 4229164197 | |||
| b6a063152f | |||
| 46c22a8b87 | |||
| 7e379cfab1 | |||
| 93d3d10453 | |||
| 98a0006c86 | |||
| d97721f38b | |||
| 8d3ec8605e | |||
| 7517389072 | |||
| b7011139cf | |||
| 6e8a68dd0d | |||
| 4e8309d3e4 | |||
| 371ab21d16 | |||
| cbcbc4bc3f | |||
| dc9b2e1766 | |||
| 334df62651 | |||
| 046353cf7e | |||
| 51f2f032d7 | |||
| 70360edb96 | |||
| 2b12ab9206 | |||
| 87a01e04ce | |||
| 5f04200bd0 | |||
| aa823b5a2d | |||
| 9012dee888 | |||
| 81d5f1a8bb | |||
| d2b0a22a8f | |||
| 355e6b1f18 | |||
| 7a2c9107c3 | |||
| 127473fff8 | |||
| 9a79b0a800 | |||
| ca13298d00 | |||
| eaf82e6367 | |||
| cae290ded7 | |||
| a22208a0be | |||
| bc877dc9dc | |||
| 40b1775d42 | |||
| c2dc605adb | |||
| a1e1af07a4 | |||
| 76948130f6 | |||
| f71ba31bfe | |||
| b7caa228e6 | |||
| 0101dd2f65 | |||
| c8baa61fe3 | |||
| 104335706a |
@@ -0,0 +1,39 @@
|
|||||||
|
name: Deploy docker
|
||||||
|
on: [push]
|
||||||
|
env:
|
||||||
|
DEPLOY_NAME: gollumwiki/gollum:latest
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
steps:
|
||||||
|
- name: Check Out Repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Login
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
- name: Cache docker layers
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
- name: Build and push
|
||||||
|
id: docker_build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile
|
||||||
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.DEPLOY_NAME }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||||
|
- name: Image digest
|
||||||
|
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
name: Build and Test Docker
|
||||||
|
on: [push, pull_request]
|
||||||
|
env:
|
||||||
|
CI_IMAGE: gollum-ci-img
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check Out Repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
- name: Cache docker layers
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
- name: Build
|
||||||
|
id: docker_build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile
|
||||||
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
push: false
|
||||||
|
tags: ${{ env.CI_IMAGE }}
|
||||||
|
outputs: type=docker
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||||
|
- name: Image digest
|
||||||
|
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||||
|
- name: docker state
|
||||||
|
run: docker image ls
|
||||||
|
- name: Run gollum as test
|
||||||
|
run: docker run -e CI=true ${{ env.CI_IMAGE }} --irb
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
on:
|
||||||
|
push:
|
||||||
|
# Sequence of patterns matched against refs/tags
|
||||||
|
tags:
|
||||||
|
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||||
|
|
||||||
|
name: Create Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Create Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
|
||||||
|
with:
|
||||||
|
tag_name: ${{ github.ref }}
|
||||||
|
release_name: Release ${{ github.ref }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
name: Ruby Build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
jruby_build:
|
||||||
|
name: JRuby (${{ matrix.ruby }})
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
ruby: [jruby-9.2.18]
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ github.workspace }}
|
||||||
|
- name: Set up Java
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: '11'
|
||||||
|
- name: Set up Ruby
|
||||||
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: ${{ matrix.ruby }}
|
||||||
|
bundler-cache: true
|
||||||
|
- name: Run tests
|
||||||
|
run: bundle exec rake
|
||||||
|
mri_build:
|
||||||
|
name: Ruby (${{ matrix.ruby }})
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
ruby: [2.6, 2.7, 3.0]
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ github.workspace }}
|
||||||
|
- name: Set up Ruby
|
||||||
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: ${{ matrix.ruby }}
|
||||||
|
bundler-cache: true
|
||||||
|
- name: Run tests
|
||||||
|
run: bundle exec rake
|
||||||
@@ -8,3 +8,4 @@ Gemfile.lock
|
|||||||
.*
|
.*
|
||||||
!.sprockets*
|
!.sprockets*
|
||||||
!lib/gollum/public/gollum/stylesheets/_styles.css
|
!lib/gollum/public/gollum/stylesheets/_styles.css
|
||||||
|
!.github*
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
rvm:
|
|
||||||
- 2.4.0
|
|
||||||
- 2.6.0
|
|
||||||
- jruby-9.2.9.0
|
|
||||||
jdk:
|
|
||||||
- oraclejdk9
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get update
|
|
||||||
- sudo apt-get install libicu-dev
|
|
||||||
@@ -63,6 +63,8 @@ Pull Requests fixing bugs, implementing new features, or updating documentation
|
|||||||
bundle exec rake test
|
bundle exec rake test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To profile slow tests, you can use `bundle exec rake test TESTOPTS="--verbose"`.
|
||||||
|
|
||||||
### Working with test repositories
|
### Working with test repositories
|
||||||
|
|
||||||
An example of how to add a test file to the bare repository lotr.git.
|
An example of how to add a test file to the bare repository lotr.git.
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
FROM ruby:2.7-alpine AS builder
|
||||||
|
|
||||||
|
RUN apk add \
|
||||||
|
build-base \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
icu-dev \
|
||||||
|
openssl-dev
|
||||||
|
|
||||||
|
COPY Gemfile* /tmp/
|
||||||
|
COPY gollum.gemspec* /tmp/
|
||||||
|
WORKDIR /tmp
|
||||||
|
RUN bundle install
|
||||||
|
|
||||||
|
RUN gem install \
|
||||||
|
asciidoctor \
|
||||||
|
creole \
|
||||||
|
wikicloth \
|
||||||
|
org-ruby \
|
||||||
|
RedCloth \
|
||||||
|
bibtex-ruby \
|
||||||
|
&& echo "gem-extra complete"
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . /app
|
||||||
|
RUN bundle exec rake install
|
||||||
|
|
||||||
|
|
||||||
|
FROM ruby:2.7-alpine
|
||||||
|
|
||||||
|
COPY --from=builder /usr/local/bundle/ /usr/local/bundle/
|
||||||
|
|
||||||
|
RUN apk add \
|
||||||
|
bash \
|
||||||
|
git
|
||||||
|
|
||||||
|
VOLUME /wiki
|
||||||
|
WORKDIR /wiki
|
||||||
|
COPY docker-run.sh /docker-run.sh
|
||||||
|
ENTRYPOINT ["/docker-run.sh"]
|
||||||
@@ -1,10 +1,26 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
if RUBY_PLATFORM == 'java'
|
gem 'warbler', platforms: :jruby
|
||||||
gem 'warbler'
|
|
||||||
end
|
# FIXME:
|
||||||
|
#
|
||||||
|
# There's an issue in 1.12.5 that causes XHTML elements to be generated badly,
|
||||||
|
# causing Gollum's test suite to fail.[1] The issue has been fixed upstream,
|
||||||
|
# but we're still waiting for a new Nokogiri point release.
|
||||||
|
#
|
||||||
|
# However, 1.12.5 is a security patch, so we don't want end users to use an
|
||||||
|
# older version of Nokogiri. But this is safe to do in our CI environment.
|
||||||
|
#
|
||||||
|
# Once there's a new Nokogiri release, we can remove this dependency and JRuby
|
||||||
|
# CI should pass normally again.
|
||||||
|
#
|
||||||
|
# Note that Nokogiri 1.11+ does not support Ruby v2.4.x anymore. So to make our
|
||||||
|
# current CI workflows pass, we should only try to install this version of
|
||||||
|
# Nokogiri for newer Ruby versions.
|
||||||
|
#
|
||||||
|
# [1]: https://github.com/gollum/gollum/issues/1779
|
||||||
|
gem 'nokogiri', '1.12.4' unless RUBY_VERSION.include? '2.4'
|
||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
gem "rake", '~> 13.0'
|
gem 'rake', '~> 13.0'
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
# 5.2.3 2021-04-18
|
||||||
|
|
||||||
|
* Fix bug preventing page titles from being displayed
|
||||||
|
|
||||||
# 5.2.1 2021-02-25
|
# 5.2.1 2021-02-25
|
||||||
|
|
||||||
* Fix include call to a missing asset (@benjaminwil). This caused slow first page loads on JRuby.
|
* Fix include call to a missing asset (@benjaminwil). This caused slow first page loads on JRuby.
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ gollum -- A git-based Wiki
|
|||||||
====================================
|
====================================
|
||||||
|
|
||||||
[](http://badge.fury.io/rb/gollum)
|
[](http://badge.fury.io/rb/gollum)
|
||||||
[](https://travis-ci.org/gollum/gollum)
|

|
||||||
[](https://www.codetriage.com/gollum/gollum)
|
[](https://www.codetriage.com/gollum/gollum)
|
||||||
[](https://dometto-cuttingedge.herokuapp.com/github/gollum/gollum/info)
|
[](https://dometto-cuttingedge.herokuapp.com/github/gollum/gollum/info)
|
||||||
|
|
||||||
|
|
||||||
**Gollum version 5.0 is out!** See [here](https://github.com/gollum/gollum/wiki/5.0-release-notes) for a list of changes and new features compared to Gollum version 4.x, and see some [Screenshots](https://github.com/gollum/gollum/wiki/Screenshots) of Gollum's features.
|
**Gollum version 5.0 is out!** See [here](https://github.com/gollum/gollum/wiki/5.0-release-notes) for a list of changes and new features compared to Gollum version 4.x, and see some [Screenshots](https://github.com/gollum/gollum/wiki/Screenshots) of Gollum's features.
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -45,7 +46,7 @@ Installation examples for individual systems can be seen [here](https://github.c
|
|||||||
|
|
||||||
To run, simply:
|
To run, simply:
|
||||||
|
|
||||||
1. Run: `gollum /path/to/wiki`.
|
1. Run: `gollum /path/to/wiki` where `/path/to/wiki` is an initialized Git repository.
|
||||||
2. Open `http://localhost:4567` in your browser.
|
2. Open `http://localhost:4567` in your browser.
|
||||||
|
|
||||||
See [below](#running-from-source) for information on running Gollum from source, as a Rack app, and more.
|
See [below](#running-from-source) for information on running Gollum from source, as a Rack app, and more.
|
||||||
@@ -83,19 +84,19 @@ See [here](https://github.com/gollum/gollum/wiki/Custom-rendering-gems) for inst
|
|||||||
|
|
||||||
### Rack
|
### Rack
|
||||||
|
|
||||||
Gollum can also be ran with any [rack-compatible web server](https://github.com/rack/rack#supported-web-servers). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack).
|
Gollum can also be run with any [rack-compatible web server](https://github.com/rack/rack#supported-web-servers). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack).
|
||||||
|
|
||||||
### Rack, with an authentication server
|
### Rack, with an authentication server
|
||||||
|
|
||||||
Gollum can also be ran alongside a CAS (Central Authentication Service) SSO (single sign-on) server. With a bit of tweaking, this adds basic user-support to Gollum. To see an example and an explanation, navigate [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack-and-CAS-SSO).
|
Gollum can also be run alongside a CAS (Central Authentication Service) SSO (single sign-on) server. With a bit of tweaking, this adds basic user-support to Gollum. To see an example and an explanation, navigate [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack-and-CAS-SSO).
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
Gollum can also be ran via [Docker](https://www.docker.com/). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Docker).
|
Gollum can also be run via [Docker](https://www.docker.com/). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Docker).
|
||||||
|
|
||||||
### Service
|
### Service
|
||||||
|
|
||||||
Gollum can also be ran as a service. More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-as-a-service).
|
Gollum can also be run as a service. More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-as-a-service).
|
||||||
|
|
||||||
## CONFIGURATION
|
## CONFIGURATION
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ Gollum comes with the following command line options:
|
|||||||
| --no-display-metadata | none | Do not render metadata tables in pages. |
|
| --no-display-metadata | none | Do not render metadata tables in pages. |
|
||||||
| --user-icons | [MODE] | Tell Gollum to use specific user icons for history view. Can be set to `gravatar`, `identicon` or `none`. Default: `none`. |
|
| --user-icons | [MODE] | Tell Gollum to use specific user icons for history view. Can be set to `gravatar`, `identicon` or `none`. Default: `none`. |
|
||||||
| --mathjax-config | [FILE] | Specify path to a custom MathJax configuration. If not specified, uses the `mathjax.config.js` file from repository root. |
|
| --mathjax-config | [FILE] | Specify path to a custom MathJax configuration. If not specified, uses the `mathjax.config.js` file from repository root. |
|
||||||
| --template-dir | [PATH] | Specify custom mustache template directory. |
|
| --template-dir | [PATH] | Specify custom mustache template directory. Only overrides templates that exist in this directory. |
|
||||||
| --template-page | none | Use _Template in root as a template for new pages. Must be committed. |
|
| --template-page | none | Use _Template in root as a template for new pages. Must be committed. |
|
||||||
| --emoji | none | Parse and interpret emoji tags (e.g. `:heart:`) except when the leading colon is backslashed (e.g. `\:heart:`). |
|
| --emoji | none | Parse and interpret emoji tags (e.g. `:heart:`) except when the leading colon is backslashed (e.g. `\:heart:`). |
|
||||||
| --lenient-tag-lookup | none | Internal links resolve case-insensitively, will treat spaces as hyphens, and will match the first page found with a certain filename, anywhere in the repository. Provides compatibility with Gollum 4.x. |
|
| --lenient-tag-lookup | none | Internal links resolve case-insensitively, will treat spaces as hyphens, and will match the first page found with a certain filename, anywhere in the repository. Provides compatibility with Gollum 4.x. |
|
||||||
@@ -149,3 +150,7 @@ When `--config` option is used, certain inner parts of Gollum can be customized.
|
|||||||
## CONTRIBUTING
|
## CONTRIBUTING
|
||||||
|
|
||||||
Please consider helping out! See [CONTRIBUTING](CONTRIBUTING.md) for information on how to submit issues, and how to start hacking on gollum.
|
Please consider helping out! See [CONTRIBUTING](CONTRIBUTING.md) for information on how to submit issues, and how to start hacking on gollum.
|
||||||
|
|
||||||
|
## THANKS TO
|
||||||
|
|
||||||
|
[](https://saucelabs.com)
|
||||||
|
|||||||
+2
-3
@@ -149,7 +149,7 @@ MSG
|
|||||||
'Can be set to \'gravatar\' or \'identicon\'. Default: standard avatar.') do |mode|
|
'Can be set to \'gravatar\' or \'identicon\'. Default: standard avatar.') do |mode|
|
||||||
wiki_options[:user_icons] = mode.to_s
|
wiki_options[:user_icons] = mode.to_s
|
||||||
end
|
end
|
||||||
opts.on('--template-dir [PATH]', 'Specify custom mustache template directory.') do |path|
|
opts.on('--template-dir [PATH]', 'Specify custom mustache template directory. Only overrides templates that exist in this directory.') do |path|
|
||||||
wiki_options[:template_dir] = path
|
wiki_options[:template_dir] = path
|
||||||
end
|
end
|
||||||
opts.on('--template-page', 'Use _Template.{ext} as a template for new pages.') do
|
opts.on('--template-page', 'Use _Template.{ext} as a template for new pages.') do
|
||||||
@@ -206,7 +206,7 @@ begin
|
|||||||
rescue OptionParser::InvalidOption => e
|
rescue OptionParser::InvalidOption => e
|
||||||
puts "gollum: #{e.message}"
|
puts "gollum: #{e.message}"
|
||||||
puts 'gollum: try \'gollum --help\' for more information'
|
puts 'gollum: try \'gollum --help\' for more information'
|
||||||
exit
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# --gollum-path wins over ARGV[0]
|
# --gollum-path wins over ARGV[0]
|
||||||
@@ -271,7 +271,6 @@ else
|
|||||||
Precious::App.set(:environment, ENV.fetch('RACK_ENV', :production).to_sym)
|
Precious::App.set(:environment, ENV.fetch('RACK_ENV', :production).to_sym)
|
||||||
Precious::App.set(:gollum_path, gollum_path)
|
Precious::App.set(:gollum_path, gollum_path)
|
||||||
Precious::App.set(:wiki_options, wiki_options)
|
Precious::App.set(:wiki_options, wiki_options)
|
||||||
Precious::App.settings.mustache[:templates] = wiki_options[:template_dir] if wiki_options[:template_dir]
|
|
||||||
|
|
||||||
if cfg = options[:config]
|
if cfg = options[:config]
|
||||||
# If the path begins with a '/' it will be considered an absolute path,
|
# If the path begins with a '/' it will be considered an absolute path,
|
||||||
|
|||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Initialize the wiki
|
||||||
|
if [ ! -d .git ]; then
|
||||||
|
git init
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start gollum service
|
||||||
|
[[ "$@" != *--mathjax* ]] && echo "WARNING: Mathjax will soon be disabled by default. To explicitly enable it, use --mathjax" >&2
|
||||||
|
exec gollum $@ --mathjax
|
||||||
+10
-10
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
|
|||||||
s.required_ruby_version = '>= 1.9'
|
s.required_ruby_version = '>= 1.9'
|
||||||
|
|
||||||
s.name = 'gollum'
|
s.name = 'gollum'
|
||||||
s.version = '5.2.1'
|
s.version = '5.2.3'
|
||||||
s.date = '2021-02-25'
|
s.date = '2021-04-18'
|
||||||
s.license = 'MIT'
|
s.license = 'MIT'
|
||||||
|
|
||||||
s.summary = 'A simple, Git-powered wiki.'
|
s.summary = 'A simple, Git-powered wiki.'
|
||||||
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'kramdown-parser-gfm', '~> 1.1.0'
|
s.add_dependency 'kramdown-parser-gfm', '~> 1.1.0'
|
||||||
s.add_dependency 'sinatra', '~> 2.0'
|
s.add_dependency 'sinatra', '~> 2.0'
|
||||||
s.add_dependency 'sinatra-contrib', '~> 2.0'
|
s.add_dependency 'sinatra-contrib', '~> 2.0'
|
||||||
s.add_dependency 'mustache-sinatra', '~> 1.0'
|
s.add_dependency 'mustache-sinatra', '>= 1.0.1', '< 2'
|
||||||
s.add_dependency 'useragent', '~> 0.16.2'
|
s.add_dependency 'useragent', '~> 0.16.2'
|
||||||
s.add_dependency 'gemojione', '~> 4.1'
|
s.add_dependency 'gemojione', '~> 4.1'
|
||||||
s.add_dependency 'octicons', '~> 12.0'
|
s.add_dependency 'octicons', '~> 12.0'
|
||||||
@@ -38,14 +38,14 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'sprockets-helpers', '~> 1.2'
|
s.add_dependency 'sprockets-helpers', '~> 1.2'
|
||||||
s.add_dependency 'rss', '~> 0.2.9'
|
s.add_dependency 'rss', '~> 0.2.9'
|
||||||
s.add_dependency 'therubyrhino', '~> 2.1.0'
|
s.add_dependency 'therubyrhino', '~> 2.1.0'
|
||||||
|
s.add_dependency 'webrick', '~> 1.7'
|
||||||
|
s.add_dependency 'i18n', '~> 1.8'
|
||||||
|
|
||||||
s.add_development_dependency 'rack-test', '~> 0.6.3'
|
s.add_development_dependency 'rack-test', '~> 0.6.3'
|
||||||
s.add_development_dependency 'shoulda', '~> 3.6.0'
|
s.add_development_dependency 'shoulda', '~> 3.6.0'
|
||||||
s.add_development_dependency 'minitest-reporters', '~> 1.3.6'
|
s.add_development_dependency 'minitest-reporters', '~> 1.3.6'
|
||||||
s.add_development_dependency 'twitter_cldr', '~> 3.2.0'
|
|
||||||
s.add_development_dependency 'mocha', '~> 1.8.0'
|
s.add_development_dependency 'mocha', '~> 1.8.0'
|
||||||
s.add_development_dependency 'test-unit', '~> 3.3.0'
|
s.add_development_dependency 'test-unit', '~> 3.3.0'
|
||||||
s.add_development_dependency 'webrick', '~> 1.4.2'
|
|
||||||
|
|
||||||
# = MANIFEST =
|
# = MANIFEST =
|
||||||
s.files = %w[
|
s.files = %w[
|
||||||
@@ -69,11 +69,11 @@ Gem::Specification.new do |s|
|
|||||||
lib/gollum/app.rb
|
lib/gollum/app.rb
|
||||||
lib/gollum/assets.rb
|
lib/gollum/assets.rb
|
||||||
lib/gollum/helpers.rb
|
lib/gollum/helpers.rb
|
||||||
lib/gollum/public/assets/.sprockets-manifest-15b663a27211dc9de9a452b4b74462d7.json
|
lib/gollum/public/assets/.sprockets-manifest-de7bb79aec424e55af1acdcc4237b301.json
|
||||||
lib/gollum/public/assets/app-7a0bbff2e8bad3033e7c17e0e0f886f336a9d23d3b912dcd2ae389c48b4b63e6.css
|
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js
|
||||||
lib/gollum/public/assets/app-7a0bbff2e8bad3033e7c17e0e0f886f336a9d23d3b912dcd2ae389c48b4b63e6.css.gz
|
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js.gz
|
||||||
lib/gollum/public/assets/app-7a4bd115f4bc7ece39bc8073ca0ffad7c5e55cc5837b1464a12dead4905cefb2.js
|
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css
|
||||||
lib/gollum/public/assets/app-7a4bd115f4bc7ece39bc8073ca0ffad7c5e55cc5837b1464a12dead4905cefb2.js.gz
|
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css.gz
|
||||||
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css
|
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css
|
||||||
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css.gz
|
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css.gz
|
||||||
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js
|
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js
|
||||||
|
|||||||
+6
-19
@@ -5,35 +5,23 @@ require 'digest/sha1'
|
|||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
|
||||||
# external
|
# external
|
||||||
|
require 'i18n'
|
||||||
require 'github/markup'
|
require 'github/markup'
|
||||||
require 'rhino' if RUBY_PLATFORM == 'java'
|
require 'rhino' if RUBY_PLATFORM == 'java'
|
||||||
|
|
||||||
# internal
|
# internal
|
||||||
require File.expand_path('../gollum/uri_encode_component', __FILE__)
|
require ::File.expand_path('../gollum/uri_encode_component', __FILE__)
|
||||||
|
|
||||||
module Gollum
|
module Gollum
|
||||||
VERSION = '5.2.1'
|
VERSION = '5.2.3'
|
||||||
|
|
||||||
|
::I18n.available_locales = [:en]
|
||||||
|
::I18n.load_path = Dir[::File.expand_path("lib/gollum/locales") + "/*.yml"]
|
||||||
|
|
||||||
def self.assets_path
|
def self.assets_path
|
||||||
::File.expand_path('gollum/public', ::File.dirname(__FILE__))
|
::File.expand_path('gollum/public', ::File.dirname(__FILE__))
|
||||||
end
|
end
|
||||||
|
|
||||||
class Error < StandardError;
|
|
||||||
end
|
|
||||||
|
|
||||||
class DuplicatePageError < Error
|
|
||||||
attr_accessor :dir
|
|
||||||
attr_accessor :existing_path
|
|
||||||
attr_accessor :attempted_path
|
|
||||||
|
|
||||||
def initialize(dir, existing, attempted, message = nil)
|
|
||||||
@dir = dir
|
|
||||||
@existing_path = existing
|
|
||||||
@attempted_path = attempted
|
|
||||||
super(message || "Cannot write #{@dir}/#{@attempted_path}, found #{@dir}/#{@existing_path}.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class TemplateFilter
|
class TemplateFilter
|
||||||
@@filters = {}
|
@@filters = {}
|
||||||
|
|
||||||
@@ -48,5 +36,4 @@ module Gollum
|
|||||||
data
|
data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+16
-7
@@ -1,4 +1,5 @@
|
|||||||
# ~*~ encoding: utf-8 ~*~
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
require 'sinatra'
|
require 'sinatra'
|
||||||
require 'sinatra/namespace'
|
require 'sinatra/namespace'
|
||||||
@@ -14,12 +15,15 @@ require 'pathname'
|
|||||||
require 'gollum'
|
require 'gollum'
|
||||||
require 'gollum/assets'
|
require 'gollum/assets'
|
||||||
require 'gollum/views/helpers'
|
require 'gollum/views/helpers'
|
||||||
|
require 'gollum/views/helpers/locale_helpers'
|
||||||
require 'gollum/views/layout'
|
require 'gollum/views/layout'
|
||||||
require 'gollum/views/editable'
|
require 'gollum/views/editable'
|
||||||
require 'gollum/views/has_page'
|
require 'gollum/views/has_page'
|
||||||
require 'gollum/views/has_user_icons'
|
require 'gollum/views/has_user_icons'
|
||||||
|
require 'gollum/views/has_math'
|
||||||
require 'gollum/views/pagination'
|
require 'gollum/views/pagination'
|
||||||
require 'gollum/views/rss.rb'
|
require 'gollum/views/rss.rb'
|
||||||
|
require 'gollum/views/template_cascade'
|
||||||
|
|
||||||
require File.expand_path '../helpers', __FILE__
|
require File.expand_path '../helpers', __FILE__
|
||||||
|
|
||||||
@@ -69,6 +73,8 @@ module Precious
|
|||||||
register Sinatra::Namespace
|
register Sinatra::Namespace
|
||||||
include Precious::Helpers
|
include Precious::Helpers
|
||||||
|
|
||||||
|
Encoding.default_external = "UTF-8"
|
||||||
|
|
||||||
dir = File.dirname(File.expand_path(__FILE__))
|
dir = File.dirname(File.expand_path(__FILE__))
|
||||||
|
|
||||||
set :sprockets, ::Precious::Assets.sprockets(dir)
|
set :sprockets, ::Precious::Assets.sprockets(dir)
|
||||||
@@ -106,7 +112,11 @@ module Precious
|
|||||||
@wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki')
|
@wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki')
|
||||||
|
|
||||||
forbid unless @allow_editing || request.request_method == 'GET'
|
forbid unless @allow_editing || request.request_method == 'GET'
|
||||||
Precious::App.set(:mustache, {:templates => settings.wiki_options[:template_dir]}) if settings.wiki_options[:template_dir]
|
|
||||||
|
if settings.wiki_options[:template_dir]
|
||||||
|
Precious::Views::Layout.extend Precious::Views::TemplateCascade
|
||||||
|
Precious::Views::Layout.template_priority_path = settings.wiki_options[:template_dir]
|
||||||
|
end
|
||||||
|
|
||||||
@base_url = url('/', false).chomp('/').force_encoding('utf-8')
|
@base_url = url('/', false).chomp('/').force_encoding('utf-8')
|
||||||
@page_dir = settings.wiki_options[:page_file_dir].to_s
|
@page_dir = settings.wiki_options[:page_file_dir].to_s
|
||||||
@@ -116,8 +126,9 @@ module Precious
|
|||||||
@css = settings.wiki_options[:css]
|
@css = settings.wiki_options[:css]
|
||||||
@js = settings.wiki_options[:js]
|
@js = settings.wiki_options[:js]
|
||||||
@mathjax_config = settings.wiki_options[:mathjax_config]
|
@mathjax_config = settings.wiki_options[:mathjax_config]
|
||||||
|
@mathjax = settings.wiki_options[:mathjax]
|
||||||
|
|
||||||
@use_static_assets = settings.wiki_options.fetch(:static, settings.environment == :production || settings.environment == :staging)
|
@use_static_assets = settings.wiki_options.fetch(:static, settings.environment != :development)
|
||||||
@static_assets_path = settings.wiki_options.fetch(:static_assets_path, ::File.join(File.dirname(__FILE__), 'public/assets'))
|
@static_assets_path = settings.wiki_options.fetch(:static_assets_path, ::File.join(File.dirname(__FILE__), 'public/assets'))
|
||||||
@mathjax_path = ::File.join(File.dirname(__FILE__), 'public/gollum/javascript/MathJax')
|
@mathjax_path = ::File.join(File.dirname(__FILE__), 'public/gollum/javascript/MathJax')
|
||||||
|
|
||||||
@@ -208,7 +219,6 @@ module Precious
|
|||||||
if page = wikip.page
|
if page = wikip.page
|
||||||
@page = page
|
@page = page
|
||||||
@content = page.text_data
|
@content = page.text_data
|
||||||
@mathjax = wiki.mathjax
|
|
||||||
@etag = page.sha
|
@etag = page.sha
|
||||||
mustache :edit
|
mustache :edit
|
||||||
else
|
else
|
||||||
@@ -230,7 +240,7 @@ module Precious
|
|||||||
halt 500 unless tempfile.is_a? Tempfile
|
halt 500 unless tempfile.is_a? Tempfile
|
||||||
|
|
||||||
if wiki.per_page_uploads
|
if wiki.per_page_uploads
|
||||||
dir = request.referer.sub(request.base_url, '')
|
dir = request.referer.match(/^https?:\/\/#{request.host_with_port}\/(.*)/)[1]
|
||||||
# remove base path if it is set
|
# remove base path if it is set
|
||||||
dir.sub!(/^#{wiki.base_path}/, '') if wiki.base_path
|
dir.sub!(/^#{wiki.base_path}/, '') if wiki.base_path
|
||||||
# remove base_url and gollum/* subpath if necessary
|
# remove base_url and gollum/* subpath if necessary
|
||||||
@@ -604,7 +614,6 @@ module Precious
|
|||||||
# Extensions and layout data
|
# Extensions and layout data
|
||||||
@editable = true
|
@editable = true
|
||||||
@toc_content = wiki.universal_toc ? @page.toc_data : nil
|
@toc_content = wiki.universal_toc ? @page.toc_data : nil
|
||||||
@mathjax = wiki.mathjax
|
|
||||||
@h1_title = wiki.h1_title
|
@h1_title = wiki.h1_title
|
||||||
@bar_side = wiki.bar_side
|
@bar_side = wiki.bar_side
|
||||||
@allow_uploads = wiki.allow_uploads
|
@allow_uploads = wiki.allow_uploads
|
||||||
@@ -638,7 +647,7 @@ module Precious
|
|||||||
|
|
||||||
def load_template(path)
|
def load_template(path)
|
||||||
template_page = wiki_page(::File.join(path, '_Template')).page || wiki_page('/_Template').page
|
template_page = wiki_page(::File.join(path, '_Template')).page || wiki_page('/_Template').page
|
||||||
template_page ? Gollum::TemplateFilter.apply_filters(template_page.raw_data) : nil
|
template_page ? Gollum::TemplateFilter.apply_filters(template_page.text_data) : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_wiki_page(wiki, page, content, commit, name = nil, format = nil)
|
def update_wiki_page(wiki, page, content, commit, name = nil, format = nil)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{"files":{"app-7a4bd115f4bc7ece39bc8073ca0ffad7c5e55cc5837b1464a12dead4905cefb2.js":{"logical_path":"app.js","mtime":"2021-02-24T23:16:14-08:00","size":135925,"digest":"7a4bd115f4bc7ece39bc8073ca0ffad7c5e55cc5837b1464a12dead4905cefb2","integrity":"sha256-ekvRFfS8fs45vIBzyg/618XlXMWDexRkoS3q1JBc77I="},"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js":{"logical_path":"editor.js","mtime":"2021-02-24T23:16:14-08:00","size":744866,"digest":"db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf","integrity":"sha256-2xDINRMG6S8ZJroiXQzZyOiGSCs7mCCoWCXsOrq18c8="},"app-7a0bbff2e8bad3033e7c17e0e0f886f336a9d23d3b912dcd2ae389c48b4b63e6.css":{"logical_path":"app.css","mtime":"2021-02-24T23:16:14-08:00","size":396661,"digest":"7a0bbff2e8bad3033e7c17e0e0f886f336a9d23d3b912dcd2ae389c48b4b63e6","integrity":"sha256-egu/8ui60wM+fBfg4PiG8zap0j07kS3NKuOJxItLY+Y="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2021-02-24T23:16:14-08:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2021-02-24T23:16:14-08:00","size":75,"digest":"512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb","integrity":"sha256-USSYw2i+DT+xuhBd+oQomuSDgOyfy++Ui9TiOwsJW/s="}},"assets":{"app.js":"app-7a4bd115f4bc7ece39bc8073ca0ffad7c5e55cc5837b1464a12dead4905cefb2.js","editor.js":"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js","app.css":"app-7a0bbff2e8bad3033e7c17e0e0f886f336a9d23d3b912dcd2ae389c48b4b63e6.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"files":{"app-f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5.js":{"logical_path":"app.js","mtime":"2021-07-10T00:40:20+09:00","size":136040,"digest":"f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5","integrity":"sha256-8FQB7jdPDH9I/CvAjjC09NtwWGH9WJXtcJmGg7ODv7U="},"editor-9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a.js":{"logical_path":"editor.js","mtime":"2021-07-10T00:42:29+09:00","size":744886,"digest":"9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a","integrity":"sha256-mIHQx65mMpPw46fnJynux+lA+mExhcB2cJt20pL1cDo="},"app-cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694.css":{"logical_path":"app.css","mtime":"2021-07-10T00:39:36+09:00","size":396625,"digest":"cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694","integrity":"sha256-yxIrTBdQD6peATy0MzT6/PLdfXL2lLBtlhb4sz/vtpQ="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2021-07-08T05:19:03+09:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2021-07-08T05:19:03+09:00","size":75,"digest":"512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb","integrity":"sha256-USSYw2i+DT+xuhBd+oQomuSDgOyfy++Ui9TiOwsJW/s="}},"assets":{"app.js":"app-f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5.js","editor.js":"editor-9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a.js","app.css":"app-cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
+2
-2
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
-2
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -218,7 +218,7 @@
|
|||||||
$form.attr('action', this.href || routePath('preview'));
|
$form.attr('action', this.href || routePath('preview'));
|
||||||
$form.attr('target', '_blank');
|
$form.attr('target', '_blank');
|
||||||
var paths = window.location.pathname.split('/');
|
var paths = window.location.pathname.split('/');
|
||||||
$form.attr('page', paths[ paths.length - 1 ] || '')
|
$form.attr('page', decodeURIComponent(paths[ paths.length - 1 ]) || '')
|
||||||
$form.submit();
|
$form.submit();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ $(document).ready(function() {
|
|||||||
var formData = new FormData($('#gollum-editor-form').get(0));
|
var formData = new FormData($('#gollum-editor-form').get(0));
|
||||||
var paths = window.location.pathname.split('/');
|
var paths = window.location.pathname.split('/');
|
||||||
var sectionAnchor = window.location.hash.substr(1);
|
var sectionAnchor = window.location.hash.substr(1);
|
||||||
formData.append('page', paths[ paths.length - 1 ] || '')
|
formData.append('page', decodeURIComponent(paths[ paths.length - 1 ]) || '')
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: routePath('preview'),
|
url: routePath('preview'),
|
||||||
data: formData,
|
data: formData,
|
||||||
@@ -380,8 +380,12 @@ $(document).ready(function() {
|
|||||||
active_tab = '#edit.tabnav-tab';
|
active_tab = '#edit.tabnav-tab';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.tabnav-tab.selected').removeAttr('aria-current');
|
||||||
$('.tabnav-tab.selected').removeClass('selected');
|
$('.tabnav-tab.selected').removeClass('selected');
|
||||||
|
|
||||||
|
$(active_tab).attr('aria-current', 'page');
|
||||||
$(active_tab).addClass('selected');
|
$(active_tab).addClass('selected');
|
||||||
|
|
||||||
$('.tabnav-div').hide();
|
$('.tabnav-div').hide();
|
||||||
$(active_div).show();
|
$(active_div).show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#gollum-dialog-dialog-buttons {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ a.tabnav-tab:focus {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gollum-editor {
|
#gollum-editor {
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
<h1 class="py-4">Create New Page</h1>
|
<h1 class="py-4">Create New Page</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="wiki-content" class="create edit">
|
<div id="wiki-content" class="create edit">
|
||||||
<div class="tabnav">
|
<div class="tabnav">
|
||||||
<nav class="tabnav-tabs" aria-label="Foo bar">
|
<nav class="tabnav-tabs" aria-label="Toggle edit or preview mode">
|
||||||
<a href="#" id="edit" class="tabnav-tab selected" aria-current="edit">Edit</a>
|
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page">
|
||||||
<a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
|
Edit
|
||||||
</nav>
|
</a>
|
||||||
</div>
|
<a href="#" id="preview" class="tabnav-tab">Preview</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="has-sidebar tabnav-div" id="edit-content">
|
<div class="has-sidebar tabnav-div" id="edit-content">
|
||||||
{{>editor}}
|
{{>editor}}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tabnav">
|
<div class="tabnav">
|
||||||
<nav class="tabnav-tabs">
|
<nav class="tabnav-tabs">
|
||||||
<a href="#" id="edit" class="tabnav-tab selected" aria-current="edit">Edit</a>
|
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page">
|
||||||
<a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
|
Edit
|
||||||
|
</a>
|
||||||
|
<a href="#" id="preview" class="tabnav-tab">Preview</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div class="tabnav-div" id="edit-content">{{>editor}}</div>
|
<div class="tabnav-div" id="edit-content">{{>editor}}</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<button class="btn btn-sm function-button" id="function-h3" title="Heading 3">h3</button>
|
<button class="btn btn-sm function-button" id="function-h3" title="Heading 3">h3</button>
|
||||||
<span class="pr-2"></span>
|
<span class="pr-2"></span>
|
||||||
<button class="btn btn-sm function-button" id="function-link" title="Link">{{#octicon}}link{{/octicon}}</button>
|
<button class="btn btn-sm function-button" id="function-link" title="Link">{{#octicon}}link{{/octicon}}</button>
|
||||||
<button class="btn btn-sm function-button" id="function-image" title="Image">{{#octicon}}file-media{{/octicon}}</button>
|
<button class="btn btn-sm function-button" id="function-image" title="Image">{{#octicon}}image{{/octicon}}</button>
|
||||||
<span class="pr-2"></span>
|
<span class="pr-2"></span>
|
||||||
{{#critic_markup}}
|
{{#critic_markup}}
|
||||||
<button class="btn btn-sm function-button" id="function-critic-accept" title="Accept Selected CriticMarkup">{{#octicon}}plus{{/octicon}}</button>
|
<button class="btn btn-sm function-button" id="function-critic-accept" title="Accept Selected CriticMarkup">{{#octicon}}plus{{/octicon}}</button>
|
||||||
|
|||||||
@@ -1,105 +1,103 @@
|
|||||||
<nav class="actions pt-4 px-2 px-lg-0 overflow-x-scroll">
|
<nav class="TableObject actions pt-4 px-2 px-lg-0 overflow-x-scroll">
|
||||||
<div class="TableObject">
|
<div class="TableObject-item hide-lg hide-xl">
|
||||||
<div class="TableObject-item hide-lg hide-xl">
|
{{>mobilenav}}
|
||||||
{{>mobilenav}}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="TableObject-item hide-sm hide-md">
|
<div class="TableObject-item hide-sm hide-md">
|
||||||
<a class="btn btn-sm" id="minibutton-home" href="{{page_route}}">
|
<a class="btn btn-sm" id="minibutton-home" href="{{page_route}}">
|
||||||
Home
|
Home
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="TableObject-item TableObject-item--primary px-2"
|
class="TableObject-item TableObject-item--primary px-2"
|
||||||
{{^search}}style="visibility:hidden"{{/search}}
|
{{^search}}style="visibility:hidden"{{/search}}
|
||||||
>
|
>
|
||||||
{{>searchbar}}
|
{{>searchbar}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="TableObject-item hide-sm hide-md">
|
<div class="TableObject-item hide-sm hide-md">
|
||||||
<div class="BtnGroup" style="display: flex;">
|
<div class="BtnGroup d-flex">
|
||||||
{{#overview}}
|
{{#overview}}
|
||||||
<a
|
|
||||||
class="btn BtnGroup-item btn-sm"
|
|
||||||
href="{{overview_path}}"
|
|
||||||
id="minibutton-overview"
|
|
||||||
>
|
|
||||||
Overview
|
|
||||||
</a>
|
|
||||||
{{/overview}}
|
|
||||||
|
|
||||||
{{#latest_changes}}
|
|
||||||
<a
|
|
||||||
class="btn BtnGroup-item btn-sm"
|
|
||||||
href="{{latest_changes_path}}"
|
|
||||||
id="minibutton-latest-changes"
|
|
||||||
>
|
|
||||||
Latest Changes
|
|
||||||
</a>
|
|
||||||
{{/latest_changes}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#history}}
|
|
||||||
<div class="TableObject-item pl-2 hide-sm hide-md">
|
|
||||||
<a
|
<a
|
||||||
class="btn btn-sm"
|
class="btn BtnGroup-item btn-sm"
|
||||||
|
href="{{overview_path}}"
|
||||||
|
id="minibutton-overview"
|
||||||
|
>
|
||||||
|
Overview
|
||||||
|
</a>
|
||||||
|
{{/overview}}
|
||||||
|
|
||||||
|
{{#latest_changes}}
|
||||||
|
<a
|
||||||
|
class="btn BtnGroup-item btn-sm"
|
||||||
|
href="{{latest_changes_path}}"
|
||||||
|
id="minibutton-latest-changes"
|
||||||
|
>
|
||||||
|
Latest Changes
|
||||||
|
</a>
|
||||||
|
{{/latest_changes}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="TableObject-item px-2">
|
||||||
|
<div class="BtnGroup d-flex">
|
||||||
|
{{#history}}
|
||||||
|
<a
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md"
|
||||||
href="{{history_path}}/{{escaped_url_path}}"
|
href="{{history_path}}/{{escaped_url_path}}"
|
||||||
id="minibutton-history"
|
id="minibutton-history"
|
||||||
>
|
>
|
||||||
Page History
|
History
|
||||||
|
</a>
|
||||||
|
{{/history}}
|
||||||
|
|
||||||
|
{{#allow_editing}}
|
||||||
|
{{#allow_uploads}}
|
||||||
|
<button
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md
|
||||||
|
minibutton-upload-page"
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</button>
|
||||||
|
{{/allow_uploads}}
|
||||||
|
|
||||||
|
{{#editable}}
|
||||||
|
<button
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md
|
||||||
|
minibutton-rename-page"
|
||||||
|
>
|
||||||
|
Rename
|
||||||
|
</button>
|
||||||
|
<a
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md"
|
||||||
|
href="{{edit_path}}/{{escaped_url_path}}"
|
||||||
|
id="minibutton-edit-page"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
{{/editable}}
|
||||||
|
{{/allow_editing}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#allow_editing}}
|
||||||
|
{{#editable}}
|
||||||
|
<div class="TableObject-item">
|
||||||
|
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
|
||||||
|
New
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{/history}}
|
{{/editable}}
|
||||||
|
|
||||||
{{#allow_editing}}
|
{{^editable}}
|
||||||
<div class="TableObject-item px-2">
|
{{#newable}}
|
||||||
<div class="BtnGroup" style="display: flex;">
|
|
||||||
{{#allow_uploads}}
|
|
||||||
<a
|
|
||||||
class="btn BtnGroup-item btn-sm hide-sm hide-md
|
|
||||||
minibutton-upload-page"
|
|
||||||
>
|
|
||||||
Upload
|
|
||||||
</a>
|
|
||||||
{{/allow_uploads}}
|
|
||||||
|
|
||||||
{{#editable}}
|
|
||||||
<a
|
|
||||||
class="btn BtnGroup-item btn-sm hide-sm hide-md
|
|
||||||
minibutton-rename-page"
|
|
||||||
>
|
|
||||||
Rename
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="btn BtnGroup-item btn-sm hide-sm hide-md"
|
|
||||||
href="{{edit_path}}/{{escaped_url_path}}"
|
|
||||||
id="minibutton-edit-page"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</a>
|
|
||||||
{{/editable}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#editable}}
|
|
||||||
<div class="TableObject-item">
|
<div class="TableObject-item">
|
||||||
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
|
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
|
||||||
New
|
New
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{/editable}}
|
{{/newable}}
|
||||||
|
{{/editable}}
|
||||||
{{^editable}}
|
{{/allow_editing}}
|
||||||
{{#newable}}
|
|
||||||
<div class="TableObject-item">
|
|
||||||
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
|
|
||||||
New
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{/newable}}
|
|
||||||
{{/editable}}
|
|
||||||
{{/allow_editing}}
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module Precious
|
|||||||
module Views
|
module Views
|
||||||
class Create < Layout
|
class Create < Layout
|
||||||
include Editable
|
include Editable
|
||||||
|
include HasMath
|
||||||
|
|
||||||
attr_reader :page, :name
|
attr_reader :page, :name
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ module Precious
|
|||||||
class Edit < Layout
|
class Edit < Layout
|
||||||
include Editable
|
include Editable
|
||||||
include HasPage
|
include HasPage
|
||||||
|
include HasMath
|
||||||
|
|
||||||
attr_reader :page, :content
|
attr_reader :page, :content
|
||||||
|
|
||||||
@@ -19,10 +20,6 @@ module Precious
|
|||||||
@name
|
@name
|
||||||
end
|
end
|
||||||
|
|
||||||
def mathjax
|
|
||||||
@mathjax
|
|
||||||
end
|
|
||||||
|
|
||||||
def header
|
def header
|
||||||
if @header.nil?
|
if @header.nil?
|
||||||
if page = @page.header
|
if page = @page.header
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module Precious
|
||||||
|
module HasMath
|
||||||
|
def mathjax
|
||||||
|
@mathjax
|
||||||
|
end
|
||||||
|
|
||||||
|
def mathjax_config
|
||||||
|
@mathjax_config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
module Precious
|
||||||
|
module Views
|
||||||
|
module LocaleHelpers
|
||||||
|
NO_METHOD_MESSAGE = 'Argument must be a view method'
|
||||||
|
YAML_VARIABLE_REGEXP = /\%\{[\w]+\}/
|
||||||
|
|
||||||
|
# Returns all I18n translation strings for the current view class.
|
||||||
|
# This method support YAML arguments. For example:
|
||||||
|
#
|
||||||
|
# last_edited: This content was last edited at %{date}.
|
||||||
|
#
|
||||||
|
# Where the `date` argument must be a method available on the current
|
||||||
|
# class.
|
||||||
|
#
|
||||||
|
# Use this interface within Mustache templates to render any user
|
||||||
|
# interface strings in the current locale. For example:
|
||||||
|
#
|
||||||
|
# {{ t.last_edited }}
|
||||||
|
#
|
||||||
|
def t
|
||||||
|
autofill I18n.t(locale_klass_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Recursively looks up I18n translation values and autofills any YAML
|
||||||
|
# arguments with the return value of the current class's matching method.
|
||||||
|
#
|
||||||
|
# When a translation value with an argument has no matching method, we
|
||||||
|
# then return that value transformed to include the `no_method_message`
|
||||||
|
#
|
||||||
|
def autofill(yaml)
|
||||||
|
yaml.map { |i18n_key, i18n_value|
|
||||||
|
if i18n_value.is_a? Hash
|
||||||
|
[i18n_key, autofill(i18n_value)]
|
||||||
|
elsif has_arguments?(i18n_value)
|
||||||
|
fill_argument_content(i18n_key, i18n_value)
|
||||||
|
else
|
||||||
|
[i18n_key, i18n_value]
|
||||||
|
end
|
||||||
|
}.to_h
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_argument_content(i18n_key, i18n_value)
|
||||||
|
i18n_value.gsub!(YAML_VARIABLE_REGEXP) do |argument|
|
||||||
|
method_name = argument.gsub(/[^\w]/, '')
|
||||||
|
|
||||||
|
next if method_name.nil?
|
||||||
|
|
||||||
|
begin
|
||||||
|
self.public_send(method_name)
|
||||||
|
rescue NoMethodError => error
|
||||||
|
no_method_message(method_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[i18n_key, i18n_value]
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_arguments?(i18n_value)
|
||||||
|
i18n_value.match?(YAML_VARIABLE_REGEXP)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the current class name in a format that is acceptable in YAML.
|
||||||
|
# To summarize its function:
|
||||||
|
#
|
||||||
|
# NameOfConstant => name_of_constant
|
||||||
|
#
|
||||||
|
def locale_klass_name
|
||||||
|
@locale_klass_name ||= self.class.name.gsub(/::/, '/').
|
||||||
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
||||||
|
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
||||||
|
tr('-', '_').
|
||||||
|
downcase
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_method_message(method_name, message = NO_METHOD_MESSAGE)
|
||||||
|
"[#{message}: #{method_name}]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -6,6 +6,7 @@ module Precious
|
|||||||
include Rack::Utils
|
include Rack::Utils
|
||||||
include Sprockets::Helpers
|
include Sprockets::Helpers
|
||||||
include Precious::Views::AppHelpers
|
include Precious::Views::AppHelpers
|
||||||
|
include Precious::Views::LocaleHelpers
|
||||||
include Precious::Views::SprocketsHelpers
|
include Precious::Views::SprocketsHelpers
|
||||||
include Precious::Views::RouteHelpers
|
include Precious::Views::RouteHelpers
|
||||||
include Precious::Views::OcticonHelpers
|
include Precious::Views::OcticonHelpers
|
||||||
@@ -47,7 +48,7 @@ module Precious
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mathjax_js
|
def mathjax_js
|
||||||
page_route("gollum/assets/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
|
"#{page_route('gollum/assets/mathjax/MathJax.js')}?config=TeX-AMS-MML_HTMLorMML"
|
||||||
end
|
end
|
||||||
|
|
||||||
def css # custom css
|
def css # custom css
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module Precious
|
|||||||
module Views
|
module Views
|
||||||
class Page < Layout
|
class Page < Layout
|
||||||
include HasPage
|
include HasPage
|
||||||
|
include HasMath
|
||||||
|
|
||||||
attr_reader :content, :page, :header, :footer, :preview, :historical
|
attr_reader :content, :page, :header, :footer, :preview, :historical
|
||||||
|
|
||||||
@@ -16,6 +17,11 @@ module Precious
|
|||||||
DEFAULT_AUTHOR = 'you'
|
DEFAULT_AUTHOR = 'you'
|
||||||
@@to_xml = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' }
|
@@to_xml = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' }
|
||||||
|
|
||||||
|
def title
|
||||||
|
h1 = @h1_title ? page_header_from_content(@content) : false
|
||||||
|
h1 || @page.url_path_title # url_path_title is the metadata title if present, otherwise the filename-based title
|
||||||
|
end
|
||||||
|
|
||||||
def page_header
|
def page_header
|
||||||
title
|
title
|
||||||
end
|
end
|
||||||
@@ -152,14 +158,6 @@ module Precious
|
|||||||
@toc_content
|
@toc_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def mathjax
|
|
||||||
@mathjax
|
|
||||||
end
|
|
||||||
|
|
||||||
def mathjax_config
|
|
||||||
@mathjax_config
|
|
||||||
end
|
|
||||||
|
|
||||||
def use_identicon
|
def use_identicon
|
||||||
@page.wiki.user_icons == 'identicon'
|
@page.wiki.user_icons == 'identicon'
|
||||||
end
|
end
|
||||||
@@ -263,11 +261,6 @@ module Precious
|
|||||||
end
|
end
|
||||||
result << "</tr>\n</table>\n"
|
result << "</tr>\n</table>\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def title
|
|
||||||
h1 = @h1_title ? page_header_from_content(@content) : false
|
|
||||||
h1 || @page.url_path_title # url_path_title is the metadata title if present, otherwise the filename-based title
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
module Precious
|
||||||
|
module Views
|
||||||
|
module TemplateCascade
|
||||||
|
def template_priority_path
|
||||||
|
@@template_priority_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_priority_path=(path)
|
||||||
|
@@template_priority_path = File.expand_path(path)
|
||||||
|
@template = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def first_path_available(name)
|
||||||
|
priority = File.join(template_priority_path, "#{name}.#{template_extension}")
|
||||||
|
default = File.join(template_path, "#{name}.#{template_extension}")
|
||||||
|
File.exists?(priority) ? priority : default
|
||||||
|
end
|
||||||
|
|
||||||
|
# Method should track lib/mustache/settings.rb from Mustache project.
|
||||||
|
def template_file
|
||||||
|
@template_file || first_path_available(template_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Method should track lib/mustache.rb from Mustache project.
|
||||||
|
def partial(name)
|
||||||
|
path = first_path_available(name)
|
||||||
|
begin
|
||||||
|
File.read(path)
|
||||||
|
rescue
|
||||||
|
raise if raise_on_context_miss?
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<nav>
|
||||||
|
<div style="background-color: red;">NAVBAR_OVERRIDE</div>
|
||||||
|
|
||||||
|
<p>Still include an original partial to ensure the fallback works even when nested from an overriden partial:</p>
|
||||||
|
<div>
|
||||||
|
{{>mobilenav}}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<div id="wiki-wrapper" class="page">
|
||||||
|
|
||||||
|
<p>Include an overridden partial:</p>
|
||||||
|
<div id="head">
|
||||||
|
{{#navbar?}}{{>navbar}}{{/navbar?}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background-color: red;">PAGE_OVERRIDE</div>
|
||||||
|
|
||||||
|
{{>wiki_content}}
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
require_relative "../../helper"
|
||||||
|
require_relative "../../../lib/gollum/views/helpers"
|
||||||
|
|
||||||
|
describe Precious::Views::LocaleHelpers do
|
||||||
|
class TestClass < Mustache
|
||||||
|
include Precious::Views::LocaleHelpers
|
||||||
|
|
||||||
|
def author
|
||||||
|
"J.R.R."
|
||||||
|
end
|
||||||
|
|
||||||
|
def location
|
||||||
|
"Bloemfontein"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
::I18n.available_locales = [:en, :de]
|
||||||
|
::I18n.load_path = Dir[File.expand_path("test/support/locales" + "/*.yml")]
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
I18n.locale = :en
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:dummy_instance) { TestClass.new }
|
||||||
|
|
||||||
|
describe "#t" do
|
||||||
|
describe "mustache usage" do
|
||||||
|
let(:subject) { dummy_instance.render(mustache_template) }
|
||||||
|
|
||||||
|
let(:mustache_template) { "{{ t.hello_world }}" }
|
||||||
|
|
||||||
|
describe "in the default locale" do
|
||||||
|
it "returns the translation string" do
|
||||||
|
_(subject).must_equal "Hello world"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "in the configured locale" do
|
||||||
|
it "returns the translation string" do
|
||||||
|
I18n.locale = :de
|
||||||
|
|
||||||
|
_(subject).must_equal "Hallo Welt"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "translations with YAML arguments" do
|
||||||
|
let(:mustache_template) { "{{ t.author_info.full }}" }
|
||||||
|
|
||||||
|
describe "in the default locale" do
|
||||||
|
it "autofills YAML arguments" do
|
||||||
|
_(subject).must_equal "Author J.R.R. is from Bloemfontein"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "in the configured locale" do
|
||||||
|
it "autofills YAML arguments" do
|
||||||
|
I18n.locale = :de
|
||||||
|
|
||||||
|
_(subject).must_equal "Autor J.R.R. ist vom Bloemfontein"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "translations with invalid arguments" do
|
||||||
|
let(:mustache_template) { "{{ t.has_invalid_argument }}" }
|
||||||
|
|
||||||
|
it "fails gracefully with embedded error message" do
|
||||||
|
expected_string = "Welcome to " \
|
||||||
|
"[#{TestClass::NO_METHOD_MESSAGE}: no_matching_method]"
|
||||||
|
|
||||||
|
_(subject).must_equal expected_string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "out of scope translations" do
|
||||||
|
let(:mustache_template) { "{{ t.never_called }}" }
|
||||||
|
|
||||||
|
it "does not include translation keys from other classes" do
|
||||||
|
_(subject).must_be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "missing translations" do
|
||||||
|
let(:mustache_template) { "{{ t.nested.nonexistent_key }}" }
|
||||||
|
|
||||||
|
it "outputs an empty string" do
|
||||||
|
_(subject).must_be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "usage" do
|
||||||
|
let(:subject) { dummy_instance.t }
|
||||||
|
|
||||||
|
it "returns a hash" do
|
||||||
|
_(subject).must_be_kind_of Hash
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns translation keys under 'test_class'" do
|
||||||
|
i18n_keys = I18n.t("test_class").keys
|
||||||
|
|
||||||
|
_(subject.keys).must_equal i18n_keys
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not return translation keys under other classes" do
|
||||||
|
other_i18n_keys = I18n.t("nonexistant_test_class").keys
|
||||||
|
|
||||||
|
_(subject.keys).wont_include other_i18n_keys
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nested keys" do
|
||||||
|
nested_keys = subject[:author_info].keys
|
||||||
|
|
||||||
|
_(nested_keys).must_equal [:full]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "auto-filled YAML arguments" do
|
||||||
|
let(:subject) { dummy_instance.t[:author_info][:full] }
|
||||||
|
|
||||||
|
it "auto-fills in the default locale" do
|
||||||
|
_(subject).must_equal "Author J.R.R. is from Bloemfontein"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "auto-fills in a configured locale" do
|
||||||
|
I18n.locale = :de
|
||||||
|
|
||||||
|
_(subject).must_equal "Autor J.R.R. ist vom Bloemfontein"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
+1
-1
@@ -5,7 +5,7 @@ require 'shoulda'
|
|||||||
require 'mocha/setup'
|
require 'mocha/setup'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'minitest/reporters'
|
require 'minitest/reporters'
|
||||||
require 'twitter_cldr'
|
require 'minitest/spec'
|
||||||
require 'tmpdir'
|
require 'tmpdir'
|
||||||
|
|
||||||
# Silence locale validation warning
|
# Silence locale validation warning
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
de:
|
||||||
|
test_class:
|
||||||
|
author_info:
|
||||||
|
full: Autor %{author} ist vom %{location}
|
||||||
|
has_invalid_argument: Willkommen in %{no_matching_method}
|
||||||
|
hello_world: Hallo Welt
|
||||||
|
nonexistant_test_class:
|
||||||
|
never_called: Nie angerufen
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
en:
|
||||||
|
test_class:
|
||||||
|
author_info:
|
||||||
|
full: Author %{author} is from %{location}
|
||||||
|
has_invalid_argument: Welcome to %{no_matching_method}
|
||||||
|
hello_world: Hello world
|
||||||
|
nonexistant_test_class:
|
||||||
|
never_called: Never called
|
||||||
+29
-16
@@ -39,29 +39,27 @@ context "Frontend" do
|
|||||||
assert_match /<pre><code>one\ntwo\nthree\nfour\n<\/code><\/pre>\n/m, last_response.body
|
assert_match /<pre><code>one\ntwo\nthree\nfour\n<\/code><\/pre>\n/m, last_response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def nfd utf8
|
|
||||||
TwitterCldr::Normalization.normalize(utf8, using: :nfd)
|
|
||||||
end
|
|
||||||
|
|
||||||
test 'mathjax assets are served' do
|
test 'mathjax assets are served' do
|
||||||
get '/gollum/assets/mathjax/MathJax.js'
|
get '/gollum/assets/mathjax/MathJax.js'
|
||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "UTF-8 headers href preserved" do
|
test "UTF-8 headers href preserved" do
|
||||||
page = 'utfh1'
|
page_content = <<~TEXT
|
||||||
text = nfd('한글')
|
## 한글
|
||||||
|
|
||||||
# don't use h1 or it will be promoted to replace file name
|
Test page "utfh1" content.
|
||||||
# which doesn't generate a normal header link
|
TEXT
|
||||||
@wiki.write_page(page, :markdown, '## ' + text,
|
|
||||||
{ :name => 'user1', :email => 'user1' });
|
|
||||||
|
|
||||||
get page
|
@wiki.write_page('utfh1',
|
||||||
expected = "<h2 class=\"editable\"><a class=\"anchor\" (href|id)=\"(#)?#{text}\" (href|id)=\"(#)?#{text}\"></a>#{text}</h2>"
|
:markdown,
|
||||||
actual = nfd(last_response.body)
|
page_content,
|
||||||
|
{name: 'user1', email: 'user1'})
|
||||||
|
|
||||||
assert_match /#{expected}/, actual
|
get 'utfh1'
|
||||||
|
expected = "<h2 class=\"editable\"><a class=\"anchor\" (href|id)=\"(#)?한글\" (href|id)=\"(#)?한글\"></a>한글</h2>"
|
||||||
|
|
||||||
|
assert_match /#{expected}/, last_response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'rss feed' do
|
test 'rss feed' do
|
||||||
@@ -328,7 +326,7 @@ EOF
|
|||||||
test "create with template succeed if template exists" do
|
test "create with template succeed if template exists" do
|
||||||
Precious::App.set(:wiki_options, { :template_page => true })
|
Precious::App.set(:wiki_options, { :template_page => true })
|
||||||
page='_Template'
|
page='_Template'
|
||||||
post '/gollum/create', :content => 'fake template', :page => page,
|
post '/gollum/create', :content => 'fake template with some Utf-8: Ü', :page => page,
|
||||||
:path => '/', :format => 'markdown', :message => ''
|
:path => '/', :format => 'markdown', :message => ''
|
||||||
follow_redirect!
|
follow_redirect!
|
||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
@@ -447,6 +445,21 @@ EOF
|
|||||||
Precious::App.set(:wiki_options, {allow_uploads: false, per_page_uploads: false})
|
Precious::App.set(:wiki_options, {allow_uploads: false, per_page_uploads: false})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "upload a file with https referer" do
|
||||||
|
temp_upload_file = Tempfile.new(['https_upload', '.file']) << 'abc'
|
||||||
|
temp_upload_file.close
|
||||||
|
Precious::App.set(:wiki_options, {allow_uploads: true, per_page_uploads: true})
|
||||||
|
post "/gollum/upload_file", {:file => Rack::Test::UploadedFile.new(::File.open(temp_upload_file))}, {'HTTP_REFERER' => 'https://localhost:4567/Home.md', 'HTTP_HOST' => 'localhost:4567'}
|
||||||
|
|
||||||
|
assert_equal 302, last_response.status # redirect is expected
|
||||||
|
@wiki.clear_cache
|
||||||
|
# Find the file in a page-specific subdir (here: Home), based on referer
|
||||||
|
file = @wiki.file("uploads/Home/#{::File.basename(temp_upload_file.path)}")
|
||||||
|
assert_equal 'abc', file.raw_data
|
||||||
|
Precious::App.set(:wiki_options, {allow_uploads: false, per_page_uploads: false})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
test "guard against uploading an existing file" do
|
test "guard against uploading an existing file" do
|
||||||
temp_upload_file = Tempfile.new(['upload', '.file']) << 'abc'
|
temp_upload_file = Tempfile.new(['upload', '.file']) << 'abc'
|
||||||
temp_upload_file.close
|
temp_upload_file.close
|
||||||
@@ -953,7 +966,7 @@ context 'Frontend with base path' do
|
|||||||
test 'base path mathjax assets' do
|
test 'base path mathjax assets' do
|
||||||
get '/wiki/Home'
|
get '/wiki/Home'
|
||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
assert last_response.body.include?('<script defer src="/wiki/gollum/assets/mathjax/MathJax.js')
|
assert last_response.body.include?('<script defer src="/wiki/gollum/assets/mathjax/MathJax.js?config=')
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'compare view' do
|
test 'compare view' do
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def load_script(**args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless ENV['TRAVIS']
|
unless ENV['CI']
|
||||||
|
|
||||||
context '4.x -> 5.x tag migrator' do
|
context '4.x -> 5.x tag migrator' do
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|||||||
+25
-1
@@ -38,7 +38,31 @@ context "Precious::Views::Page" do
|
|||||||
assert_include @view.breadcrumb, "数学 📘"
|
assert_include @view.breadcrumb, "数学 📘"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "page header retains unicde and ASCII characters" do
|
test 'page <title> is the page header from content, if present' do
|
||||||
|
page_title = 'Page header from content'
|
||||||
|
@wiki.write_page(page_title, :markdown, 'Contents', commit_details)
|
||||||
|
|
||||||
|
@view = Precious::Views::Page.new.tap do |view|
|
||||||
|
view.instance_variable_set :@page, @wiki.page(page_title)
|
||||||
|
view.instance_variable_set :@h1_title, true
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal @view.title, 'Page header from content'
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'page <title> is URL path title if no h1 present' do
|
||||||
|
@wiki.write_page('dir/My path title', :markdown, 'Contents', commit_details)
|
||||||
|
page = @wiki.page('dir/My path title')
|
||||||
|
|
||||||
|
@view = Precious::Views::Page.new.tap do |view|
|
||||||
|
view.instance_variable_set :@page, page
|
||||||
|
view.instance_variable_set :@h1_title, false
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal @view.title, 'My path title'
|
||||||
|
end
|
||||||
|
|
||||||
|
test "page header retains unicode and ASCII characters" do
|
||||||
title = "数学 📘"
|
title = "数学 📘"
|
||||||
@wiki.write_page(title, :markdown, "How old is Bilbo?")
|
@wiki.write_page(title, :markdown, "How old is Bilbo?")
|
||||||
page = @wiki.page(title)
|
page = @wiki.page(title)
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# ~*~ encoding: utf-8 ~*~
|
||||||
|
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||||
|
|
||||||
|
class TestTemplateCascade < Minitest::Unit::TestCase
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@path = cloned_testpath('examples/lotr.git')
|
||||||
|
Precious::App.set(:gollum_path, @path)
|
||||||
|
Precious::App.set(:wiki_options, {template_dir: testpath('examples/template_cascade')})
|
||||||
|
@wiki = Gollum::Wiki.new(@path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.rm_rf(@path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def app
|
||||||
|
Precious::App
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_overridden_page_template_is_used
|
||||||
|
get '/Home'
|
||||||
|
|
||||||
|
assert last_response.body.include?('PAGE_OVERRIDE')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_overridden_navbar_partial_is_used
|
||||||
|
get '/Home'
|
||||||
|
|
||||||
|
assert last_response.body.include?('NAVBAR_OVERRIDE')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_overridden_templates_are_ignore_without_template_dir_set
|
||||||
|
Precious::App.set(:wiki_options, {template_dir: nil})
|
||||||
|
|
||||||
|
get '/Home'
|
||||||
|
assert_equal '/Home', last_request.fullpath
|
||||||
|
assert last_response.ok?
|
||||||
|
assert_no_match /PAGE_OVERRIDE/, last_response.body
|
||||||
|
assert_no_match /NAVBAR_OVERRIDE/, last_response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user