Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow outputting URLs with trailing slash #692

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function renderForConsole($output, Throwable $e): void
$handler->handle();
}

public function map(Closure|string $from, Closure|string|null $to = null): static
public function map(Closure|string $from, Closure|string $to = null): static
{
if (is_string($to)) {
$to = fn ($exception) => new $to('', 0, $exception);
Expand Down
24 changes: 20 additions & 4 deletions src/PageVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public function __call($method, $args)
public function getPath($key = null)
{
if (($key || $this->_meta->extending) && $this->_meta->path instanceof IterableObject) {
return $this->_meta->path->get($key ?: $this->getExtending());
return $this->enforceTrailingSlash($this->_meta->path->get($key ?: $this->getExtending()));
}

return (string) $this->_meta->path;
return $this->enforceTrailingSlash((string) $this->_meta->path);
}

public function getPaths()
Expand All @@ -46,10 +46,10 @@ public function getPaths()
public function getUrl($key = null)
{
if (($key || $this->_meta->extending) && $this->_meta->path instanceof IterableObject) {
return $this->_meta->url->get($key ?: $this->getExtending());
return $this->enforceTrailingSlash($this->_meta->url->get($key ?: $this->getExtending()));
}

return (string) $this->_meta->url;
return $this->enforceTrailingSlash((string) $this->_meta->url);
}

public function getUrls()
Expand All @@ -61,4 +61,20 @@ protected function missingHelperError($functionName)
{
return 'No function named "' . $functionName . '" was found in the file "config.php".';
}

protected function enforceTrailingSlash($path)
{
return $path && app()->config->get('trailing_slash') && ! $this->pathIsFile($path)
? Str::finish($path, '/')
: $path;
}

protected function pathIsFile($path)
{
$final_extension = $this->_meta->extending
? (Str::contains(Str::afterLast($path, '/'), '.') ? Str::afterLast($path, '.') : null)
: Str::afterLast($this->_meta->extension, '.');

return $final_extension && $final_extension !== 'md' && $final_extension !== 'php';
}
}
1 change: 1 addition & 0 deletions tests/snapshots/default-trailing-slash/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JIGSAW_TEST_VAR=true
137 changes: 137 additions & 0 deletions tests/snapshots/default-trailing-slash/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

use Illuminate\Support\Str;

return [
'trailing_slash' => true,
'baseUrl' => 'http://jigsaw.test',
'global_array' => [1, 2, 3],
'global_variable' => 'some global variable',
'number' => '98765',
'perPage' => 4,
'viewHintPaths' => [],
'php' => '<?php',
'nested_array' => [
[
'name' => 'first name',
'position' => 'first',
'value' => 1,
],
[
'name' => 'second name',
'position' => 'second',
'value' => 2,
],
[
'name' => 'third name',
'position' => 'third',
'value' => 3,
],
],
'envVariable' => env('JIGSAW_TEST_VAR', false),
'globalPreview' => function ($data, $characters = 100) {
return substr(strip_tags($data->getContent() ?? ''), 0, $characters);
},
'helperFunction' => function ($data) {
return 'hello global! #' . $data->number;
},
'selected' => function ($data, $section) {
return strpos($data->getPath(), $section) > -1;
},
'collections' => [
'remote_test' => [
'extends' => '_layouts.remote',
'items' => function () {
$remote_post = json_decode(file_get_contents('https://jsonplaceholder.typicode.com/posts/1'));

return [
[
'var' => 'test var 1',
'content' => '### The markdown content for the 1st item',
],
[
'var' => 'test var 2',
'filename' => 'file_2',
'content' => '### The markdown content for the 2nd item',
],
[
'var' => 'test var 3',
],
[
'var' => $remote_post->title,
'content' => $remote_post->body,
],
'## This item has no content key, just string content',
];
},
],
'collection_tests' => [
'sum' => 99999,
],
'sort_tests' => [
'sort' => ['letter', '-number'],
],
'invalid_path_characters_test' => [
'path' => '{-title}',
],
'posts' => [
'helperFunction' => function ($data) {
return 'hello from posts! #' . $data->number;
},
'author' => 'Default Author',
'date_formatted' => function ($post) {
list($year, $month, $day) = parseDate($post['date']);

return sprintf('%s/%s/%s', $month, $day, $year);
},
'preview' => function ($post, $characters = 75) {
return substr(strip_tags($post->getContent() ?? ''), 0, $characters);
},
'api' => function ($post) {
return [
'slug' => Str::slug($post->title),
'title' => $post->title,
'author' => $post->author,
'date' => $post->date,
'content' => $post->getContent(),
];
},
'isSelected' => function ($post, $current_page) {
return $post->getPath() == $current_page->getPath();
},
],

'people' => [
'path' => [
'web' => 'people/web/{date|Y-m-d}/{_filename}',
'test' => 'people/test/{-filename}',
'api' => 'people/api.test/{name}/{date|Y-m-d}/{-name}',
],
'number_doubled' => function ($data) {
return $data->number * 2;
},
'api' => function ($data) {
return collect([
'name' => $data->name,
'number' => $data->number,
'role' => $data->role,
'content' => strip_tags($data->getContent() ?? ''),
])->toJson();
},
],

'dot-files-collection' => [
],
],
];

function parseDate($timestamp)
{
$date = DateTime::createFromFormat('U', $timestamp);

return [
$date->format('Y'),
$date->format('m'),
$date->format('d'),
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This should be copied to the build directory.
10 changes: 10 additions & 0 deletions tests/snapshots/default-trailing-slash/source/404.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: A 404 Page
extends: _layouts/master
section: body
permalink: 404-permalink-test.html
---

# 404

## Not Found
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
extends: _layouts.simple
title: .mdown Extension Test
author: Markdown
date: 2017-10-21
number: 100
---

Testing PR: Added support for .mdown files, the default for mac computers
https://github.com/tighten/jigsaw/pull/161
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
extends: _layouts.simple
title: Test One
author: Adam Wathan
date: 2016-01-01
number: 612
category: news
---

This is a standard **Markdown** post. Note that `section` is optional in the frontmatter if using `@yield('content')` in the parent template.

If using a different section name (e.g. `@yield('postContent')`), the `section` should be specified in the frontmatter.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus earum distinctio, laboriosam dolorem delectus voluptatem odio qui mollitia official.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Test Three
author: Keith Damiani
date: 2016-01-03
number: 333
category: faq
---
@extends('_layouts.simple')

@section('content')
<h2>Test for components and slots</h2>

@component('_components.alert')
@slot('title')
Title test
@endslot

<strong>Whoops!</strong> Something went wrong!
@endcomponent

@endsection
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
extends: _layouts.simple
title: Test Two
author: Keith Damiani
date: 2016-01-02
number: 7
category: faq
---

The second post
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="alert alert-danger">
<h3>This is the component</h3>
<h4>Named title slot: {{ $title }}</h4>
<hr>
{{ $slot }}
<hr>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
extends: _layouts/test-base
title: Collection item with dot in filename
section: content
---
### This file contains a dot in the filename
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
extends: _layouts/test-base
title: Collection item with dot in filename
section: content
---
### This file contains a dot in the filename

{{ $page->getFilename() }}

{{ $page->getPath() }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Collection item with dot in filename
---

@extends('_layouts/test-base')

@section('content')
<h3>This file contains a dot in the filename</h3>
<p>{{ $page->getFilename() }}</p>
<p>{{ $page->getPath() }}</p>
@endsection
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
extends: _layouts.simple
title: Remove® Invalid™ Characters from Paths
author: Keith Damiani
date: 2017-01-02
number: 8
category: faq
---


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{!! ($page->api()) !!}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
testvar: variable in blade markdown header
---
Some markdown included now...

### {{ $page->name }}

_the name should be above_

### {{ $page->number_doubled() }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@extends('_layouts.master')

@section('body')

<h2>Categories</h2>

<div class="border-b">
<div class="row">
<div class="col-xs-6">
<h2 class="text-brand"><em>{{ $page->getFilename() }}</em></h2>
</div>
<div class="col-xs-6 text-right">
<h2>

@foreach ($posts->pluck('category')->unique() as $category)
<a class="btn btn-primary-outline btn-sm m-xs-l-2 text-uppercase" href="{{ $page->baseUrl }}/categories/{{ $category }}">{{ $category }}</a>
@endforeach

</h2>
</div>
</div>
</div>

<blockquote class="m-xs-t-4">Demonstrates using collection methods to build pages dynamically</blockquote>

@foreach ($posts->where('category', $page->getFilename()) as $post)
<div class="row">
<div class="col-xs-12">
<h3><a href="{{ $post->getUrl() }}">{{ $post['title'] }}</a></h3>
<p class="text-sm">by {{ $post->author }} · {{ $post->date_formatted() }} · Number {{ $post->number }}</p>
<p class="p-xs-b-6 border-b">{!! $post->preview(180) !!}...</p>
</div>
</div>
@endforeach

@endsection
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@extends('_layouts.master')

@section('body')
<h2>{{ $page->title }}</h2>
@yield('content')
@endsection
Loading
Loading