Compare commits

..

27 Commits

Author SHA1 Message Date
benjamin wil 851f53194e Fix failing spec
My changes to the header layout seem to changed where the spaces in
`last_response.body` are placed. So let's assert only that the content
is present, since that's all this test should actually care about.
2021-12-30 14:30:20 -08:00
benjamin wil d3a709c4d3 Recompile assets 2021-12-30 14:30:20 -08:00
benjamin wil 0b75a47750 Adjust padding and presentation of mobile menu
To give mobile page headers more structure, this commit adjusts the
padding to be more symmetrical. It also adds a `border-bottom` on mobile
only. In my opinion this improves readability by telling the reader,
"This is where the navigation menu ends and the page content begins."
2021-12-30 14:30:20 -08:00
benjamin wil 4fcc72078b Use .header-title for all #head headings
This commit:

  1. Updates all main templates to use the new `.header-title` class,
     making these titles less disruptively large on mobile devices.
  2. Centers these titles for mobile breakpoints only, re-setting them
     back to left-aligned text for `md-` breakpoints and up.

Note that in `lib/gollum/templates/wiki_contentf.mustache`, the
`.header-title` is not a `#head .header-title`, so it doesn't inherit
all of the new styles added in this commit.
2021-12-30 14:30:20 -08:00
benjamin wil 9b4755e822 Add .header-title style
This style shows smaller text on mobile devices. It reverts back to the
`2em` size used in Primer for H1 tags.
2021-12-30 14:30:20 -08:00
benjamin wil 9c574fd760 Improve test suite and CI run performance (#1796)
* Simplify test

I came across this test because it was failing JRuby CI runs. I should
emphasize, though, that this test was only failing due do an upstream
bug in Nokogiri v1.12.5.

When I was reviewing the test, to understand why it was failing at all,
I noticed that the assertion was rather obfuscated.  Specifically, we
were post-processing the entire `response.body` and using that as an
expectation.

* Use an older version of Nokogiri in our test env

This is a temporary fix. See the commit diff for more information.

* Split JRuby CI runs from MRI CI runs

We can improve the performance of our MRI test runs by not installing
Java as part of their run. (Java is only required for JRuby.)

* Use latest Ruby patch versions during CI runs

* Simplify GitHub Action workflow steps

Judging by the output in the GitHub Actions workflow UI, the `echo`
steps were not providing much value to us.

We can get rid of them to slightly increase run performance.

I've also named the other steps to make it easier to skim the Actions
workflow output.

* Remove `twitter_cldr` development dependency

This is no longer being used.

* Change GitHub Actions workflow Ruby matrix

We can drop Ruby 2.4 from our test run matrix. It is beyond EOL.
Let's add 2.7 instead.
2021-12-30 14:21:23 -08:00
Dawa Ometto 46c22a8b87 Take account of possible https referer in upload route (#1787) 2021-12-23 12:18:30 +01:00
Ryan Govostes 7e379cfab1 Reduce size of container image (#1777)
* Reduce size of container image
* Add deprecation message for automatic --mathjax
2021-12-22 20:54:29 +01:00
Dawa Ometto 93d3d10453 Update gollum (#1786)
Exit with code 1 (error) when invalid option is given
2021-12-22 18:08:20 +01:00
fhchl 98a0006c86 Fix mathjax on edit and create pages (#1773)
* Fix mathjax on edit and create pages
2021-12-22 17:00:31 +01:00
Dawa Ometto d97721f38b Update test.yaml
Update JDK
2021-11-06 13:32:13 +01:00
Aaron Wallentine 8d3ec8605e Small grammar fix in README.md (#1776) 2021-10-28 13:55:32 +02:00
Brian Porter 7517389072 Allow for overriding only specific Mustache templates/partials. (#1719)
* Allow for overriding only specific templates/partials. Resolves  #1450.
2021-09-07 17:32:46 +02:00
Dawa Ometto b7011139cf Create release.yml (#1760) 2021-09-06 11:30:56 +02:00
Dawa Ometto 6e8a68dd0d Delete .travis.yml 2021-09-02 21:04:30 +02:00
Dawa Ometto 4e8309d3e4 Load template page as utf-8 (#1758) 2021-08-30 11:09:29 +02:00
Dawa Ometto 371ab21d16 Add SauceLab attribution 2021-08-28 17:36:06 +02:00
yy0931 cbcbc4bc3f unescape page names in the preview tab (#1739)
* Unescape page names in the preview tab

* Execute rake precompile
2021-08-28 17:24:00 +02:00
Dawa Ometto dc9b2e1766 Update gollum.gemspec (#1749) 2021-08-28 17:21:44 +02:00
Darless 334df62651 Docker support within the repository (#1732)
- Adds a Dockerfile within this repository
- GitHub actions to build and test the image
2021-08-03 12:52:47 +02:00
yy0931 046353cf7e Fix an IME rendering issue (#1735)
* Fix an IME rendering issue

* Execute rake precompile
2021-07-09 07:52:38 -07:00
benjamin wil 51f2f032d7 Add I18n interface for use in Mustache templates (#1679)
* Add `i18n` dependency

We will use `i18n` to provide localization for Gollum's frontend. I
chose this because it's a well-supported, pretty normal Ruby library.

* Configure I18n

- Locale files will be kept in `lib/gollum/locales/[lang].yml`
- The available locales, to start, will be English (`en`).

* Add I18n interface for mustache templates

This commit adds an interface that allows mustache templates to get I18n
translation strings, transform any arguments that may be present in
them, and then render them on the frontend.

This is our first real step to getting internationalizing the Gollum
frontend.
2021-06-27 09:26:45 -07:00
Dawa Ometto 70360edb96 Update test.yaml (#1734) 2021-06-26 22:06:34 +02:00
benjamin wil 2b12ab9206 Explicitly set encoding for Precious::App (#1731)
An issue was reported (see #1721) where, in docker containers where the
`LANG` was not being set, `Precious::App` would serve Mustache templates
in an ASCII encoding. This caused templates to error out.

In the past, this would have happened in environments where `LANG` was
not set and the Gollum applciation configuration had enabled MathJax.
Now, it happens even if MathJax is disabled because of a UTF-8 character
I added to the mobile navigation menu.

Basically, we should enforce a UTF-8 encoding from now on to avoid
runtime errors related to ASCII encoding.
2021-06-14 21:28:12 +02:00
Darless 87a01e04ce fixes #1723: Github Actions Supported (#1729)
* fixes #1723: Github Actions Supported

- This is to switch from Travis CI which is shutting down the org version,
  and the .com version, a free account is limited.
- Switch test environment variable from TRAVIS to CI to be more generic.

* Adding jruby-9.2.18.0 to matrix for github actions
2021-06-14 21:21:40 +02:00
Sam 5f04200bd0 README.md: Clarify that Gollum should run against an already-initialized Git repository. (#1722) 2021-06-13 14:34:28 -07:00
benjamin wil aa823b5a2d Use recent JRuby release for Travis CI (#1730)
Our JRuby CI runs have been errorring due to what I think is an issue
with an older `jruby-openssl` version.
2021-06-13 14:17:18 -07:00
54 changed files with 747 additions and 127 deletions
+39
View File
@@ -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 }}
+38
View File
@@ -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
+25
View File
@@ -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
+46
View File
@@ -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
+1
View File
@@ -8,3 +8,4 @@ Gemfile.lock
.*
!.sprockets*
!lib/gollum/public/gollum/stylesheets/_styles.css
!.github*
-10
View File
@@ -1,10 +0,0 @@
rvm:
- 2.4.0
- 2.6.0
- 3.0.0
- jruby-9.2.9.0
jdk:
- oraclejdk9
before_install:
- sudo apt-get update
- sudo apt-get install libicu-dev
+40
View File
@@ -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"]
+21 -4
View File
@@ -1,9 +1,26 @@
source 'https://rubygems.org'
if RUBY_PLATFORM == 'java'
gem 'warbler'
end
gem 'warbler', platforms: :jruby
# 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
gem 'rake', '~> 13.0'
gem 'rake', '~> 13.0'
+14 -9
View File
@@ -2,10 +2,11 @@ gollum -- A git-based Wiki
====================================
[![Gem Version](https://badge.fury.io/rb/gollum.svg)](http://badge.fury.io/rb/gollum)
[![Build Status](https://travis-ci.org/gollum/gollum.svg?branch=master)](https://travis-ci.org/gollum/gollum)
![Build Status](https://github.com/gollum/gollum/actions/workflows/test.yaml/badge.svg)
[![Open Source Helpers](https://www.codetriage.com/gollum/gollum/badges/users.svg)](https://www.codetriage.com/gollum/gollum)
[![Cutting Edge Dependency Status](https://dometto-cuttingedge.herokuapp.com/github/gollum/gollum/svg 'Cutting Edge Dependency Status')](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.
## DESCRIPTION
@@ -36,16 +37,16 @@ Gollum runs on Unix-like systems using its [adapter](https://github.com/gollum/r
## INSTALLATION
1. Ruby is best installed either via [RVM](https://rvm.io/) or a package manager of choice.
2. Gollum is best installed via RubyGems:
2. Gollum is best installed via RubyGems:
```
[sudo] gem install gollum
```
Installation examples for individual systems can be seen [here](https://github.com/gollum/gollum/wiki/Installation).
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.
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
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
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
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
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
@@ -125,7 +126,7 @@ Gollum comes with the following command line options:
| --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`. |
| --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. |
| --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. |
@@ -149,3 +150,7 @@ When `--config` option is used, certain inner parts of Gollum can be customized.
## CONTRIBUTING
Please consider helping out! See [CONTRIBUTING](CONTRIBUTING.md) for information on how to submit issues, and how to start hacking on gollum.
## THANKS TO
[![Testing Powered By SauceLabs](https://opensource.saucelabs.com/images/opensauce/powered-by-saucelabs-badge-gray.png?sanitize=true "Testing Powered By SauceLabs")](https://saucelabs.com)
+2 -3
View File
@@ -149,7 +149,7 @@ MSG
'Can be set to \'gravatar\' or \'identicon\'. Default: standard avatar.') do |mode|
wiki_options[:user_icons] = mode.to_s
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
end
opts.on('--template-page', 'Use _Template.{ext} as a template for new pages.') do
@@ -206,7 +206,7 @@ begin
rescue OptionParser::InvalidOption => e
puts "gollum: #{e.message}"
puts 'gollum: try \'gollum --help\' for more information'
exit
exit 1
end
# --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(:gollum_path, gollum_path)
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 the path begins with a '/' it will be considered an absolute path,
Executable
+10
View File
@@ -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
+2 -2
View File
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
s.add_dependency 'kramdown-parser-gfm', '~> 1.1.0'
s.add_dependency 'sinatra', '~> 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 'gemojione', '~> 4.1'
s.add_dependency 'octicons', '~> 12.0'
@@ -39,11 +39,11 @@ Gem::Specification.new do |s|
s.add_dependency 'rss', '~> 0.2.9'
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 'shoulda', '~> 3.6.0'
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 'test-unit', '~> 3.3.0'
+6 -3
View File
@@ -5,19 +5,23 @@ require 'digest/sha1'
require 'ostruct'
# external
require 'i18n'
require 'github/markup'
require 'rhino' if RUBY_PLATFORM == 'java'
# internal
require File.expand_path('../gollum/uri_encode_component', __FILE__)
require ::File.expand_path('../gollum/uri_encode_component', __FILE__)
module Gollum
VERSION = '5.2.3'
::I18n.available_locales = [:en]
::I18n.load_path = Dir[::File.expand_path("lib/gollum/locales") + "/*.yml"]
def self.assets_path
::File.expand_path('gollum/public', ::File.dirname(__FILE__))
end
class TemplateFilter
@@filters = {}
@@ -32,5 +36,4 @@ module Gollum
data
end
end
end
+27 -18
View File
@@ -1,4 +1,5 @@
# ~*~ encoding: utf-8 ~*~
# encoding: UTF-8
require 'cgi'
require 'sinatra'
require 'sinatra/namespace'
@@ -14,12 +15,15 @@ require 'pathname'
require 'gollum'
require 'gollum/assets'
require 'gollum/views/helpers'
require 'gollum/views/helpers/locale_helpers'
require 'gollum/views/layout'
require 'gollum/views/editable'
require 'gollum/views/has_page'
require 'gollum/views/has_user_icons'
require 'gollum/views/has_math'
require 'gollum/views/pagination'
require 'gollum/views/rss.rb'
require 'gollum/views/template_cascade'
require File.expand_path '../helpers', __FILE__
@@ -40,7 +44,7 @@ Gollum::set_git_max_filesize(190 * 10**6)
# See the wiki.rb file for more details on wiki options
module Precious
# For use with the --base-path option.
class MapGollum
def initialize(base_path)
@@ -63,12 +67,14 @@ module Precious
@mg.call(env)
end
end
class App < Sinatra::Base
register Mustache::Sinatra
register Sinatra::Namespace
include Precious::Helpers
Encoding.default_external = "UTF-8"
dir = File.dirname(File.expand_path(__FILE__))
set :sprockets, ::Precious::Assets.sprockets(dir)
@@ -102,11 +108,15 @@ module Precious
@critic_markup = settings.wiki_options[:critic_markup]
@redirects_enabled = settings.wiki_options.fetch(:redirects_enabled, true)
@per_page_uploads = settings.wiki_options[:per_page_uploads]
@wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki')
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')
@page_dir = settings.wiki_options[:page_file_dir].to_s
@@ -116,11 +126,12 @@ module Precious
@css = settings.wiki_options[:css]
@js = settings.wiki_options[:js]
@mathjax_config = settings.wiki_options[:mathjax_config]
@mathjax = settings.wiki_options[:mathjax]
@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'))
@mathjax_path = ::File.join(File.dirname(__FILE__), 'public/gollum/javascript/MathJax')
Sprockets::Helpers.configure do |config|
config.environment = settings.sprockets
config.environment.context_class.class_variable_set(:@@base_url, @base_url)
@@ -208,7 +219,6 @@ module Precious
if page = wikip.page
@page = page
@content = page.text_data
@mathjax = wiki.mathjax
@etag = page.sha
mustache :edit
else
@@ -219,7 +229,7 @@ module Precious
# AJAX calls only
post '/upload_file' do
wiki = wiki_new
halt 405 unless wiki.allow_uploads
@@ -230,12 +240,12 @@ module Precious
halt 500 unless tempfile.is_a? Tempfile
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
dir.sub!(/^#{wiki.base_path}/, '') if wiki.base_path
# remove base_url and gollum/* subpath if necessary
dir.sub!(/^\/gollum\/[-\w]+\//, '')
# remove file extension
# remove file extension
dir.sub!(/#{::File.extname(dir)}$/, '')
# revert escaped whitespaces
dir.gsub!(/%20/, ' ')
@@ -317,7 +327,7 @@ module Precious
end
post '/edit/*' do
etag = params[:etag]
etag = params[:etag]
path = "/#{clean_url(sanitize_empty_params(params[:path]))}"
wiki = wiki_new
page = wiki.page(::File.join(path, params[:page]))
@@ -327,7 +337,7 @@ module Precious
# Signal edit collision and return the page's most recent version
halt 412, {etag: page.sha, text_data: page.text_data}.to_json
end
committer = Gollum::Committer.new(wiki, commit_message)
commit = { :committer => committer }
@@ -348,7 +358,7 @@ module Precious
commit[:message] = "Deleted #{filepath}"
wiki.delete_file(filepath, commit)
end
end
end
get '/create/*' do
forbid unless @allow_editing
@@ -604,7 +614,6 @@ module Precious
# Extensions and layout data
@editable = true
@toc_content = wiki.universal_toc ? @page.toc_data : nil
@mathjax = wiki.mathjax
@h1_title = wiki.h1_title
@bar_side = wiki.bar_side
@allow_uploads = wiki.allow_uploads
@@ -625,7 +634,7 @@ module Precious
end
end
end
def show_file(file)
return unless file
if file.on_disk?
@@ -638,7 +647,7 @@ module Precious
def load_template(path)
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
def update_wiki_page(wiki, page, content, commit, name = nil, format = nil)
@@ -683,4 +692,4 @@ module Precious
end
end
end
end
@@ -0,0 +1 @@
{"files":{"app-f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5.js":{"logical_path":"app.js","mtime":"2021-11-15T20:08:30-08:00","size":136040,"digest":"f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5","integrity":"sha256-8FQB7jdPDH9I/CvAjjC09NtwWGH9WJXtcJmGg7ODv7U="},"editor-9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a.js":{"logical_path":"editor.js","mtime":"2021-11-15T20:08:30-08:00","size":744886,"digest":"9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a","integrity":"sha256-mIHQx65mMpPw46fnJynux+lA+mExhcB2cJt20pL1cDo="},"app-309be032396e783b13a47df58f389b7c8e11c2b2d42640560b874f677c25f6e5.css":{"logical_path":"app.css","mtime":"2021-11-15T20:08:30-08:00","size":396731,"digest":"309be032396e783b13a47df58f389b7c8e11c2b2d42640560b874f677c25f6e5","integrity":"sha256-MJvgMjlueDsTpH31jzibfI4RwrLUJkBWC4dPZ3wl9uU="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2021-08-22T15:24:51-07:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2021-08-22T15:24:51-07: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-309be032396e783b13a47df58f389b7c8e11c2b2d42640560b874f677c25f6e5.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
@@ -1 +0,0 @@
{"files":{"app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js":{"logical_path":"app.js","mtime":"2021-03-23T08:40:11-07:00","size":136020,"digest":"0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838","integrity":"sha256-D9Io4mv75v4xotomjrDpjngMEZHBqRit84M3eUbpyDg="},"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js":{"logical_path":"editor.js","mtime":"2021-02-24T23:16:14-08:00","size":744866,"digest":"db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf","integrity":"sha256-2xDINRMG6S8ZJroiXQzZyOiGSCs7mCCoWCXsOrq18c8="},"app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css":{"logical_path":"app.css","mtime":"2021-03-23T08:40:11-07:00","size":396615,"digest":"ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2","integrity":"sha256-rUPKZLKV2ERLEPIu6GjxhCkmivSY8bxRVDSHi2kON6I="},"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-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js","editor.js":"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js","app.css":"app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
@@ -218,7 +218,7 @@
$form.attr('action', this.href || routePath('preview'));
$form.attr('target', '_blank');
var paths = window.location.pathname.split('/');
$form.attr('page', paths[ paths.length - 1 ] || '')
$form.attr('page', decodeURIComponent(paths[ paths.length - 1 ]) || '')
$form.submit();
@@ -345,7 +345,7 @@ $(document).ready(function() {
var formData = new FormData($('#gollum-editor-form').get(0));
var paths = window.location.pathname.split('/');
var sectionAnchor = window.location.hash.substr(1);
formData.append('page', paths[ paths.length - 1 ] || '')
formData.append('page', decodeURIComponent(paths[ paths.length - 1 ]) || '')
$.ajax({
url: routePath('preview'),
data: formData,
@@ -29,6 +29,7 @@ a.tabnav-tab:focus {
overflow: hidden;
font-family: Consolas, "Liberation Mono", Courier, monospace;
font-size: 1em;
padding: 0;
}
#gollum-editor {
@@ -510,6 +510,14 @@ a {
border: none;
}
#head .header-title {
font-size: 1.5em;
@include largemobile-breakpoint {
font-size: 32px;
}
}
/* Highlights */
.highlight {
+3 -1
View File
@@ -1,6 +1,8 @@
<div id="wiki-wrapper" class="compare">
<div id="head">
<h1 class="py-4">{{message}}</h1>
<h1 class="header-title text-center text-md-left py-4">
{{message}}
</h1>
{{author}} commited {{authored_date}}
<span class="px-2 float-right">commit <code>{{version}}</code></span>
</div>
+10 -4
View File
@@ -1,8 +1,14 @@
<div id="wiki-wrapper" class="compare">
<div id="head">
{{>navbar}}
<h1 class="py-4"><span class="f1-light text-gray-light">Comparing versions of</span> {{name}}</h1>
</div>
<div id="head">
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
<span class="f1-light text-gray-light">
Comparing versions of
</span>
{{name}}
</h1>
</div>
{{#message}}
<p>{{message}}</p>
+7 -4
View File
@@ -1,8 +1,11 @@
<div id="wiki-wrapper" class="create">
<div id="head">
{{>navbar}}
<h1 class="py-4">Create New Page</h1>
</div>
<div id="head">
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
Create New Page
</h1>
</div>
<div id="wiki-content" class="create edit">
<div class="tabnav">
<nav class="tabnav-tabs" aria-label="Toggle edit or preview mode">
+7 -4
View File
@@ -1,8 +1,11 @@
<div id="wiki-wrapper" class="edit">
<div id="head">
{{>navbar}}
<h1 class="py-4">Editing <strong>{{title}}</strong></h1>
</div>
<div id="head">
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
Editing <strong>{{title}}</strong>
</h1>
</div>
<div class="tabnav">
<nav class="tabnav-tabs">
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page">
+9 -2
View File
@@ -1,8 +1,15 @@
<div id="wiki-wrapper" class="history">
<div id="head">
{{>navbar}}
<h1 class="py-4"><span class="f1-light text-gray-light">History for</span> {{name}}</h1>
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
<span class="f1-light text-gray-light">
History for
</span>
{{name}}
</h1>
</div>
<div id="page-history">
{{>pagination}}
+7 -4
View File
@@ -1,8 +1,11 @@
<div id="wiki-wrapper" class="history">
<div id="head">
{{>navbar}}
<h1 class="py-4">{{title}}</h1>
</div>
<div id="head">
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
{{title}}
</h1>
</div>
{{>pagination}}
+8 -1
View File
@@ -1,4 +1,11 @@
<nav class="TableObject actions pt-4 px-2 px-lg-0 overflow-x-scroll">
<nav class="TableObject
actions
border-bottom
border-md-0
p-2
pt-lg-4
px-lg-0
overflow-x-scroll">
<div class="TableObject-item hide-lg hide-xl">
{{>mobilenav}}
</div>
+7 -4
View File
@@ -1,8 +1,11 @@
<div id="wiki-wrapper" class="results">
<div id="head" class="overview">
{{>navbar}}
<h1 class="py-4">{{title}}</h1>
</div>
<div id="head" class="overview">
{{>navbar}}
<h1 class="header-title text-center text-md-left py-4">
{{title}}
</h1>
</div>
<div id="overview">
{{#has_results}}
+7 -1
View File
@@ -1,7 +1,13 @@
<div id="wiki-wrapper" class="results">
<div id="head">
{{>navbar}}
<h1 class="py-4"><span class="f1-light text-gray-light">Search results for</span> {{name}}</h1>
<h1 class="header-title text-center text-md-left py-4">
<span class="f1-light text-gray-light">
Search results for
</span>
{{name}}
</h1>
</div>
{{#has_results}}
+3 -1
View File
@@ -1,5 +1,7 @@
<div id="wiki-content" class="px-2 px-lg-0">
<h1 class="pt-4">{{page_header}}</h1>
<h1 class="header-title text-center text-md-left pt-4">
{{page_header}}
</h1>
<div class="breadcrumb">{{{breadcrumb}}}</div>
<div class="{{#has_header}}has-header{{/has_header}}{{#has_footer}} has-footer{{/has_footer}}{{#has_sidebar}} has-sidebar has-{{bar_side}}bar{{/has_sidebar}}{{#has_toc}} has-toc{{/has_toc}}">
+3 -2
View File
@@ -2,6 +2,7 @@ module Precious
module Views
class Create < Layout
include Editable
include HasMath
attr_reader :page, :name
@@ -41,9 +42,9 @@ module Precious
def content
@template_page
end
private
def find_format
@found_format ||= (Gollum::Page.format_for("#{@name}#{@ext}") || default_markup)
end
+2 -5
View File
@@ -3,6 +3,7 @@ module Precious
class Edit < Layout
include Editable
include HasPage
include HasMath
attr_reader :page, :content
@@ -18,10 +19,6 @@ module Precious
def page_name
@name
end
def mathjax
@mathjax
end
def header
if @header.nil?
@@ -67,7 +64,7 @@ module Precious
def etag
@etag
end
def allow_uploads
@allow_uploads
end
+11
View File
@@ -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
+2 -1
View File
@@ -6,10 +6,11 @@ module Precious
include Rack::Utils
include Sprockets::Helpers
include Precious::Views::AppHelpers
include Precious::Views::LocaleHelpers
include Precious::Views::SprocketsHelpers
include Precious::Views::RouteHelpers
include Precious::Views::OcticonHelpers
alias_method :h, :escape_html
attr_reader :name, :path
+8 -15
View File
@@ -2,9 +2,10 @@ module Precious
module Views
class Page < Layout
include HasPage
include HasMath
attr_reader :content, :page, :header, :footer, :preview, :historical
VALID_COUNTER_STYLES = ['decimal', 'decimal-leading-zero', 'arabic-indic', 'armenian', 'upper-armenian',
'lower-armenian', 'bengali', 'cambodian', 'khmer', 'cjk-decimal', 'devanagari', 'georgian', 'gujarati', 'gurmukhi',
'hebrew', 'kannada', 'lao', 'malayalam', 'mongolian', 'myanmar', 'oriya', 'persian', 'lower-roman', 'upper-roman',
@@ -61,11 +62,11 @@ module Precious
def editable
@editable
end
def search
true
end
def history
true
end
@@ -73,11 +74,11 @@ module Precious
def latest_changes
true
end
def overview
true
true
end
def allow_editing
@allow_editing
end
@@ -157,14 +158,6 @@ module Precious
@toc_content
end
def mathjax
@mathjax
end
def mathjax_config
@mathjax_config
end
def use_identicon
@page.wiki.user_icons == 'identicon'
end
@@ -182,7 +175,7 @@ module Precious
# Returns Hash.
def metadata
@page.metadata
end
end
# Access to embedded metadata.
#
+36
View File
@@ -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>
+134
View File
@@ -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
+2 -2
View File
@@ -5,7 +5,7 @@ require 'shoulda'
require 'mocha/setup'
require 'fileutils'
require 'minitest/reporters'
require 'twitter_cldr'
require 'minitest/spec'
require 'tmpdir'
# Silence locale validation warning
@@ -93,4 +93,4 @@ def context(*args, &block)
klass.class_eval &block
end
$contexts = []
$contexts = []
+8
View File
@@ -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
+8
View File
@@ -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
+31 -18
View File
@@ -39,31 +39,29 @@ context "Frontend" do
assert_match /<pre><code>one\ntwo\nthree\nfour\n<\/code><\/pre>\n/m, last_response.body
end
def nfd utf8
TwitterCldr::Normalization.normalize(utf8, using: :nfd)
end
test 'mathjax assets are served' do
get '/gollum/assets/mathjax/MathJax.js'
assert last_response.ok?
end
test "UTF-8 headers href preserved" do
page = 'utfh1'
text = nfd('한글')
page_content = <<~TEXT
## 한글
# don't use h1 or it will be promoted to replace file name
# which doesn't generate a normal header link
@wiki.write_page(page, :markdown, '## ' + text,
{ :name => 'user1', :email => 'user1' });
Test page "utfh1" content.
TEXT
get page
expected = "<h2 class=\"editable\"><a class=\"anchor\" (href|id)=\"(#)?#{text}\" (href|id)=\"(#)?#{text}\"></a>#{text}</h2>"
actual = nfd(last_response.body)
@wiki.write_page('utfh1',
:markdown,
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
test 'rss feed' do
channel_title = <<EOF
<title>Gollum Wiki Latest Changes</title>
@@ -328,7 +326,7 @@ EOF
test "create with template succeed if template exists" do
Precious::App.set(:wiki_options, { :template_page => true })
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 => ''
follow_redirect!
assert last_response.ok?
@@ -447,6 +445,21 @@ EOF
Precious::App.set(:wiki_options, {allow_uploads: false, per_page_uploads: false})
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
temp_upload_file = Tempfile.new(['upload', '.file']) << 'abc'
temp_upload_file.close
@@ -476,9 +489,9 @@ EOF
test "previews content" do
post "/gollum/preview", :content => 'abc', :format => 'markdown', :page => 'Samewise Gamgee.mediawiki'
assert last_response.ok?
assert last_response.body.include?('Samewise Gamgee</h1>')
assert last_response.body.include?('Samewise Gamgee')
end
test 'throws an error when comparing two identical revisions for a page' do
get '/gollum/compare/A.md/fc66539528eb96f21b2bbdbf557788fe8a1196ac...fc66539528eb96f21b2bbdbf557788fe8a1196ac'
assert last_response.ok?
+1 -1
View File
@@ -44,7 +44,7 @@ def load_script(**args)
end
end
unless ENV['TRAVIS']
unless ENV['CI']
context '4.x -> 5.x tag migrator' do
include Rack::Test::Methods
+43
View File
@@ -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