Skip to content

Commit c1c8b67

Browse files
show internal links in contentsviewer
1 parent 8785894 commit c1c8b67

File tree

8 files changed

+139
-32
lines changed

8 files changed

+139
-32
lines changed

Client/ContentsViewer/ContentsViewerStandard.css

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,11 @@ ul.tag-list.removable li a:hover::before{
623623
url('data:image/svg+xml;charset=utf8,%3Csvg%20aria-hidden%3D%22true%22%20focusable%3D%22false%22%20data-prefix%3D%22fas%22%20data-icon%3D%22tag%22%20class%3D%22svg-inline--fa%20fa-tag%20fa-w-16%22%20role%3D%22img%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M0%20252.118V48C0%2021.49%2021.49%200%2048%200h204.118a48%2048%200%200%201%2033.941%2014.059l211.882%20211.882c18.745%2018.745%2018.745%2049.137%200%2067.882L293.823%20497.941c-18.745%2018.745-49.137%2018.745-67.882%200L14.059%20286.059A48%2048%200%200%201%200%20252.118zM112%2064c-26.51%200-48%2021.49-48%2048s21.49%2048%2048%2048%2048-21.49%2048-48-21.49-48-48-48z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E')
624624
}
625625

626+
.link-icon::before{
627+
background-image: linear-gradient(transparent, transparent),
628+
url('data:image/svg+xml;charset=utf8,%3Csvg%20aria-hidden%3D%22true%22%20focusable%3D%22false%22%20data-prefix%3D%22fas%22%20data-icon%3D%22link%22%20class%3D%22svg-inline--fa%20fa-link%20fa-w-16%22%20role%3D%22img%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M326.612%20185.391c59.747%2059.809%2058.927%20155.698.36%20214.59-.11.12-.24.25-.36.37l-67.2%2067.2c-59.27%2059.27-155.699%2059.262-214.96%200-59.27-59.26-59.27-155.7%200-214.96l37.106-37.106c9.84-9.84%2026.786-3.3%2027.294%2010.606.648%2017.722%203.826%2035.527%209.69%2052.721%201.986%205.822.567%2012.262-3.783%2016.612l-13.087%2013.087c-28.026%2028.026-28.905%2073.66-1.155%20101.96%2028.024%2028.579%2074.086%2028.749%20102.325.51l67.2-67.19c28.191-28.191%2028.073-73.757%200-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037%2016.037%200%200%201-6.947-12.606c-.396-10.567%203.348-21.456%2011.698-29.806l21.054-21.055c5.521-5.521%2014.182-6.199%2020.584-1.731a152.482%20152.482%200%200%201%2020.522%2017.197zM467.547%2044.449c-59.261-59.262-155.69-59.27-214.96%200l-67.2%2067.2c-.12.12-.25.25-.36.37-58.566%2058.892-59.387%20154.781.36%20214.59a152.454%20152.454%200%200%200%2020.521%2017.196c6.402%204.468%2015.064%203.789%2020.584-1.731l21.054-21.055c8.35-8.35%2012.094-19.239%2011.698-29.806a16.037%2016.037%200%200%200-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639%200-101.83l67.2-67.19c28.239-28.239%2074.3-28.069%20102.325.51%2027.75%2028.3%2026.872%2073.934-1.155%20101.96l-13.087%2013.087c-4.35%204.35-5.769%2010.79-3.783%2016.612%205.864%2017.194%209.042%2034.999%209.69%2052.721.509%2013.906%2017.454%2020.446%2027.294%2010.606l37.106-37.106c59.271-59.259%2059.271-155.699.001-214.959z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E')
629+
}
630+
626631
.header-link-button {
627632
display: block;
628633
-webkit-transform: perspective(1px) translateZ(0);
@@ -1812,12 +1817,15 @@ a.directory .name, a.file .name{
18121817
top:50%;
18131818
transform: translateY(-50%);
18141819
}
1815-
.card-item.head .tag-icon{
1820+
.card-item.head .icon{
18161821
font-size: 30px;
18171822
}
18181823
.card-item.head.tag{
18191824
background-color: #3498db;
18201825
}
1826+
.card-item.head.link{
1827+
background-color: #dbac34;
1828+
}
18211829
.card-item.head .title{
18221830
color:white;
18231831
}
@@ -2250,9 +2258,15 @@ a.directory .name, a.file .name{
22502258
[theme="dark"] #layer-selector ul li:hover{
22512259
background-color: #2d3539;
22522260
}
2261+
[theme="dark"] .card-item.head {
2262+
background-color: #6d7784;
2263+
}
22532264
[theme="dark"] .card-item.head.tag{
22542265
background-color: var(--tag-background-color);
22552266
}
2267+
[theme="dark"] .card-item.head.link{
2268+
background-color: #b18d32;
2269+
}
22562270
[theme="dark"] .card-item:not(.head){
22572271
background-color: #1f1f1f;
22582272
border-top: #3e3e3e solid 10px;

Client/ContentsViewer/ContentsViewerStandard.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,13 +674,23 @@ function GetRelatedContents() {
674674
title.className = 'title';
675675
title.textContent = each.keyword;
676676
inner.appendChild(title);
677+
677678
if (each.detailURL !== false) {
678679
head.href = each.detailURL;
680+
}
681+
682+
if (each.type == 'tag') {
679683
head.classList.add('tag');
680684
var icon = document.createElement('div');
681685
icon.className = 'tag-icon icon'
682686
inner.appendChild(icon);
683687
}
688+
else if (each.type == 'link') {
689+
head.classList.add('link');
690+
var icon = document.createElement('div');
691+
icon.className = 'link-icon icon'
692+
inner.appendChild(icon);
693+
}
684694
head.appendChild(inner);
685695
wrapper.appendChild(head);
686696

Frontend/preview.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require_once(MODULE_DIR . '/Authenticator.php');
44
require_once(MODULE_DIR . '/ContentsDatabaseManager.php');
5-
require_once(MODULE_DIR . '/OutlineText.php');
5+
require_once(MODULE_DIR . '/ContentTextParser.php');
66

77
Authenticator::RequireLoginedSession();
88

@@ -23,19 +23,16 @@
2323
// --- 前処理 -------------
2424
// 改行LFのみ
2525
$plainText = str_replace("\r", "", $plainText);
26-
2726
// end 前処理 -----
2827

29-
$context = new OutlineText\Context();
30-
$context->pathMacros = ContentsDatabaseManager::CreatePathMacros($vars['contentPath']);
28+
ContentTextParser::Init();
29+
$context = ContentTextParser::CreateContext($vars['contentPath']);
3130

3231
$vars['layerName'] = ContentsDatabaseManager::GetRelatedLayerName($vars['contentPath']);
3332
if($vars['layerName'] === false){
3433
$vars['layerName'] = DEFAULT_LAYER_NAME;
3534
}
3635

37-
OutlineText\Parser::Init();
38-
3936
?>
4037
<!DOCTYPE html>
4138
<html lang="<?=$vars['layerName']?>">
@@ -67,7 +64,7 @@
6764
</head>
6865

6966
<body>
70-
<?=OutlineText\Parser::Parse($plainText, $context);?>
67+
<?=ContentTextParser::Parse($plainText, $vars['contentPath'], $context);?>
7168

7269
<!-- SyntaxHighlighter 有効化 -->
7370
<script>

Module/ContentTextParser.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
require_once dirname(__FILE__) . "/Debug.php";
4+
require_once dirname(__FILE__) . "/OutlineText.php";
5+
require_once dirname(__FILE__) . "/ContentsDatabaseManager.php";
6+
require_once dirname(__FILE__) . "/ContentsViewerUtils.php";
7+
require_once dirname(__FILE__) . "/Utils.php";
8+
9+
/**
10+
* Content記法拡張
11+
*/
12+
class ContentTextParser {
13+
/**
14+
* [
15+
* 'path' => true, 'path' => true
16+
* ]
17+
*/
18+
public static $contentLinks = [];
19+
public static $currentRootDirectory='';
20+
public static $isInitialized = false;
21+
22+
public static function Init() {
23+
if(static::$isInitialized) return;
24+
25+
OutlineText\Parser::$inlineElementPatternTable[] = [
26+
"/\[(.*?)\]/", null, ['ContentTextParser', 'ParseContentLink']
27+
];
28+
OutlineText\Parser::Init();
29+
static::$isInitialized = true;
30+
}
31+
32+
public static function Parse($text, $contentPath, &$context) {
33+
if(!static::$isInitialized) static::Init();
34+
static::$currentRootDirectory = substr(GetTopDirectory($contentPath), 1);
35+
return OutlineText\Parser::Parse($text, $context);
36+
}
37+
38+
public static function CreateContext($contentPath) {
39+
$context = new OutlineText\Context();
40+
$context->pathMacros = static::CreatePathMacros($contentPath);
41+
return $context;
42+
}
43+
44+
public static function ParseContentLink($matches, $context) {
45+
$contentPath = URI2Path(static::$currentRootDirectory . '/' . $matches[1][0]);
46+
$content = new Content();
47+
if(!$content->SetContent($contentPath)) {
48+
// if not exists, return the text that matched the full pattern.
49+
return $matches[0][0];
50+
}
51+
if(!array_key_exists($content->path, static::$contentLinks)) {
52+
static::$contentLinks[$content->path] = true;
53+
}
54+
$title = '';
55+
$parent = $content->Parent();
56+
if($parent !== false) {
57+
$title .= $parent->title . '-';
58+
}
59+
$title .= $content->title;
60+
$href = CreateContentHREF($content->path);
61+
return '<a href="' . $href .'">' . $title . '</a>';
62+
}
63+
64+
public static function CreatePathMacros($contentPath) {
65+
return [
66+
['CURRENT_DIR', 'ROOT_URI'],
67+
[ROOT_URI . Path2URI(dirname($contentPath)), ROOT_URI]
68+
];
69+
}
70+
}

Module/ContentsDatabaseManager.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,6 @@ public static function GetSortedContentsByUpdatedTime($pathList) {
337337
return ['sorted' => $sorted, 'notFounds' => $notFounds];
338338
}
339339

340-
public static function CreatePathMacros($contentPath) {
341-
return [
342-
['CURRENT_DIR', 'ROOT_URI'],
343-
[ROOT_URI . Path2URI(dirname($contentPath)), ROOT_URI]
344-
];
345-
}
346-
347340
public static function GetSuggestedTags($content, $tag2path, $excludeOriginal=true, &$fullMatchTag=false) {
348341
$suggestedTags = [];
349342
$title = NotBlankText(

Module/ContentsViewerUtils.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
require_once dirname(__FILE__) . "/../CollabCMS.php";
88
require_once dirname(__FILE__) . "/Authenticator.php";
99
require_once dirname(__FILE__) . "/ContentsDatabaseManager.php";
10-
require_once dirname(__FILE__) . "/OutlineText.php";
10+
require_once dirname(__FILE__) . "/ContentTextParser.php";
1111
require_once dirname(__FILE__) . "/CacheManager.php";
1212
require_once dirname(__FILE__) . "/Utils.php";
1313
require_once dirname(__FILE__) . "/Localization.php";
@@ -280,7 +280,7 @@ function GetTextHead($text, $wordCount) {
280280
* @return array array['summary'], array['body']
281281
*/
282282
function GetDecodedText($content) {
283-
OutlineText\Parser::Init();
283+
ContentTextParser::Init();
284284

285285
// キャッシュの読み込み
286286
$cache = new Cache;
@@ -298,12 +298,13 @@ function GetDecodedText($content) {
298298
) {
299299

300300
$text = [];
301-
$context = new OutlineText\Context();
302-
$context->pathMacros = ContentsDatabaseManager::CreatePathMacros($content->path);
303-
304-
$text['summary'] = OutlineText\Parser::Parse($content->summary, $context);
305-
$text['body'] = OutlineText\Parser::Parse($content->body, $context);
306-
301+
$context = ContentTextParser::CreateContext($content->path);
302+
ContentTextParser::$contentLinks = [];
303+
$text['summary'] = ContentTextParser::Parse($content->summary, $content->path, $context);
304+
$text['body'] = ContentTextParser::Parse($content->body, $content->path, $context);
305+
306+
$cache->data['contentLinks'] = ContentTextParser::$contentLinks;
307+
Debug::Log(ContentTextParser::$contentLinks);
307308
$cache->data['text'] = $text;
308309

309310
// 読み込み時の時間を使う

Service/outlinetext-decode-service.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@
1919

2020
// end 前処理 -----
2121

22-
$context = new OutlineText\Context();
23-
if(isset($_POST['contentPath'])){
24-
$context->pathMacros = ContentsDatabaseManager::CreatePathMacros($_POST['contentPath']);
25-
}
26-
2722
$language = 'en';
2823
if(isset($_POST['language'])){
2924
$language = H($_POST['language']);
@@ -59,7 +54,7 @@
5954

6055
</head>
6156
<body>
62-
<?=OutlineText\Parser::Parse($plainText, $context);?>
57+
<?=OutlineText\Parser::Parse($plainText);?>
6358

6459
<!-- SyntaxHighlighter 有効化 -->
6560
<script>

Service/related-search-service.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
require_once dirname(__FILE__) . '/../Module/SearchEngine.php';
2222
require_once dirname(__FILE__) . '/../Module/ContentsViewerUtils.php';
23+
require_once dirname(__FILE__) . '/../Module/CacheManager.php';
2324

2425
/**
2526
* 'related' => [
2627
* [
2728
* 'keyword' => '',
29+
* 'type' => '',
2830
* 'detailURL' => '',
2931
* 'contents' => [
3032
* [
@@ -79,6 +81,7 @@
7981
$suggestedTagSuggestions = [];
8082
$tagSuggestions = [];
8183
$titleSuggestions = [];
84+
$linkSuggestions = [];
8285

8386
// "<title> <parent.title> で検索
8487
// ただし, parent は rootではない
@@ -128,28 +131,52 @@
128131
);
129132
}
130133

134+
$contentCache = new Cache;
135+
$contentCache->Connect($currentContent->path);
136+
$contentCache->Lock(LOCK_SH); $contentCache->Fetch(); $contentCache->Unlock();
137+
$contentCache->Disconnect();
138+
if(array_key_exists('contentLinks', $contentCache->data)) {
139+
$contentLinks = $contentCache->data['contentLinks'];
140+
foreach($contentLinks as $path => $_) {
141+
$linkSuggestions[] = ['id' => $path];
142+
}
143+
}
144+
131145
// === Set Response ==================================================
132-
if(count($titleSuggestions) > 0) {
146+
147+
if(!empty($linkSuggestions)) {
148+
$response['related'][] = [
149+
'keyword' => 'Links',
150+
'detailURL' => false,
151+
'type' => 'link',
152+
'contents' => CreateSuggestedContents($linkSuggestions)
153+
];
154+
}
155+
156+
if(!empty($titleSuggestions)) {
133157
$response['related'][] = [
134158
'keyword' => $titleQuery,
135159
'detailURL' => false,
160+
'type' => 'page',
136161
'contents' => CreateSuggestedContents($titleSuggestions)
137162
];
138163
}
139164
foreach($tagSuggestions as $each){
140-
if(count($each['suggestions']) > 0) {
165+
if(!empty($each['suggestions'])) {
141166
$response['related'][] = [
142167
'keyword' => $each['tag'],
143168
'detailURL' => CreateTagMapHREF([[$each['tag']]], $rootDirectory, $layerName),
169+
'type' => 'tag',
144170
'contents' => CreateSuggestedContents($each['suggestions'])
145171
];
146172
}
147173
}
148174
foreach($suggestedTagSuggestions as $each){
149-
if(count($each['suggestions']) > 0) {
175+
if(!empty($each['suggestions'])) {
150176
$response['related'][] = [
151177
'keyword' => $each['tag'],
152178
'detailURL' => CreateTagMapHREF([[$each['tag']]], $rootDirectory, $layerName),
179+
'type' => 'tag',
153180
'contents' => CreateSuggestedContents($each['suggestions'])
154181
];
155182
}

0 commit comments

Comments
 (0)