hyde_admin 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.rspec +3 -0
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +56 -0
- data/Gemfile +8 -0
- data/bin/admin_views/admin_layout.html.erb +76 -51
- data/bin/admin_views/configuration.erb +4 -4
- data/bin/admin_views/dashboard.erb +37 -1
- data/bin/admin_views/editor_html.erb +21 -18
- data/bin/admin_views/editor_js.erb +112 -111
- data/bin/admin_views/files/edit.erb +4 -4
- data/bin/admin_views/files/listing.erb +14 -14
- data/bin/admin_views/posts/edit.erb +159 -62
- data/bin/admin_views/posts/listing.erb +10 -10
- data/bin/admin_views/search.erb +42 -0
- data/bin/admin_views/upload_image_form.erb +5 -5
- data/bin/hyde_admin.ru +165 -11
- data/bin/hyde_assets/hyde_admin.css +58 -0
- data/bin/hyde_assets/hyde_admin.js +121 -18
- data/bin/i18n/en.yml +20 -1
- data/bin/i18n/fr.yml +21 -2
- data/hyde_admin.gemspec +6 -8
- data/lib/hyde_admin/version.rb +1 -1
- data/spec/files/create_file_spec.rb +92 -0
- data/spec/mid_helpers_spec.rb +105 -0
- data/spec/posts/create_draft_spec.rb +77 -0
- data/spec/posts/create_page_spec.rb +75 -0
- data/spec/posts/create_post_spec.rb +100 -0
- data/spec/search/global_search_spec.rb +92 -0
- data/spec/spec_helper.rb +25 -0
- metadata +26 -34
- data/.idea/.gitignore +0 -8
- data/.idea/hyde_admin.iml +0 -25
- data/.idea/misc.xml +0 -4
- data/.idea/modules.xml +0 -8
- data/.idea/vcs.xml +0 -6
|
@@ -1,130 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
window.myCodeMirror.redo();
|
|
6
|
-
});
|
|
7
|
-
$(document).on('click', '.codemirror-toolbar .fa-file-image', function(){
|
|
8
|
-
$('.modal-image').modal('show');
|
|
9
|
-
});
|
|
10
|
-
$(document).on('click', '.modal-image img', function(){
|
|
11
|
-
let img_src = '<img src="' + $(this).attr('src') + '" alt="<%= EscapeUtils.escape_html t.default_alt_img %>" title="<%= EscapeUtils.escape_html t.default_title_img %>" />';
|
|
12
|
-
if(window.mode_markdown){
|
|
13
|
-
img_src = '.attr('src') + ')';
|
|
1
|
+
document.addEventListener('click', function(e){
|
|
2
|
+
if(e.target.closest('.codemirror-toolbar .fa-undo-alt')){
|
|
3
|
+
window.myCodeMirror.undo();
|
|
4
|
+
return;
|
|
14
5
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
$(document).on('click', '.codemirror-toolbar .fa-heading', function(){
|
|
19
|
-
let obj_cursor = window.myCodeMirror.getCursor();
|
|
20
|
-
|
|
21
|
-
let heading_number = 0;
|
|
22
|
-
if($(this).hasClass('cmt-heading-1')){
|
|
23
|
-
heading_number = 1;
|
|
24
|
-
}else if($(this).hasClass('cmt-heading-2')){
|
|
25
|
-
heading_number = 2;
|
|
26
|
-
}else if($(this).hasClass('cmt-heading-3')){
|
|
27
|
-
heading_number = 3;
|
|
28
|
-
}else if($(this).hasClass('cmt-heading-4')){
|
|
29
|
-
heading_number = 4;
|
|
30
|
-
}else if($(this).hasClass('cmt-heading-5')){
|
|
31
|
-
heading_number = 5;
|
|
6
|
+
if(e.target.closest('.codemirror-toolbar .fa-redo-alt')){
|
|
7
|
+
window.myCodeMirror.redo();
|
|
8
|
+
return;
|
|
32
9
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
begin_str = '#';
|
|
38
|
-
for (let i = 1; i < heading_number; i++) {
|
|
39
|
-
begin_str = begin_str + '#';
|
|
40
|
-
}
|
|
41
|
-
begin_str = begin_str + ' ';
|
|
42
|
-
end_str = '';
|
|
43
|
-
}
|
|
44
|
-
window.myCodeMirror.replaceSelection(begin_str + window.myCodeMirror.getSelection() + end_str);
|
|
45
|
-
if(!window.myCodeMirror.somethingSelected()){
|
|
46
|
-
window.myCodeMirror.setCursor({ line: obj_cursor.line, ch: obj_cursor.ch + begin_str.length });
|
|
10
|
+
if(e.target.closest('.codemirror-toolbar .fa-file-image')){
|
|
11
|
+
var modal = new bootstrap.Modal(document.querySelector('.modal-image'));
|
|
12
|
+
modal.show();
|
|
13
|
+
return;
|
|
47
14
|
}
|
|
48
|
-
window.myCodeMirror.focus();
|
|
49
|
-
});
|
|
50
|
-
$(document).on('click', '.codemirror-toolbar .cmt-replace', function(){
|
|
51
|
-
let begin_str = '';
|
|
52
|
-
let end_str = '';
|
|
53
15
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
begin_str = '';
|
|
59
|
-
end_str = '';
|
|
60
|
-
}*/
|
|
61
|
-
}else if($(this).hasClass('fa-bold')){
|
|
62
|
-
begin_str = '<b>';
|
|
63
|
-
end_str = '</b>';
|
|
64
|
-
if(window.mode_markdown){
|
|
65
|
-
begin_str = '**';
|
|
66
|
-
end_str = '**';
|
|
67
|
-
}
|
|
68
|
-
}else if($(this).hasClass('fa-italic')){
|
|
69
|
-
begin_str = '<i>';
|
|
70
|
-
end_str = '</i>';
|
|
71
|
-
if(window.mode_markdown){
|
|
72
|
-
begin_str = '*';
|
|
73
|
-
end_str = '*';
|
|
74
|
-
}
|
|
75
|
-
}else if($(this).hasClass('fa-strikethrough')){
|
|
76
|
-
begin_str = '<s>';
|
|
77
|
-
end_str = '</s>';
|
|
16
|
+
var imgTarget = e.target.closest('.modal-image img');
|
|
17
|
+
if(imgTarget){
|
|
18
|
+
var src = imgTarget.getAttribute('src');
|
|
19
|
+
var img_src = '<img src="' + src + '" alt="<%= CGI.escapeHTML t.default_alt_img %>" title="<%= CGI.escapeHTML t.default_title_img %>" />';
|
|
78
20
|
if(window.mode_markdown){
|
|
79
|
-
|
|
80
|
-
end_str = '~~';
|
|
21
|
+
img_src = '';
|
|
81
22
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
23
|
+
window.myCodeMirror.replaceSelection(img_src);
|
|
24
|
+
bootstrap.Modal.getInstance(document.querySelector('.modal-image')).hide();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var headingBtn = e.target.closest('.codemirror-toolbar .fa-heading');
|
|
29
|
+
if(headingBtn){
|
|
30
|
+
var obj_cursor = window.myCodeMirror.getCursor();
|
|
31
|
+
var heading_number = 0;
|
|
32
|
+
for(var i = 1; i <= 5; i++){
|
|
33
|
+
if(headingBtn.classList.contains('cmt-heading-' + i)){
|
|
34
|
+
heading_number = i;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
88
37
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
end_str = '</p>\n</blockquote>';
|
|
38
|
+
var begin_str = '<h' + heading_number + '>';
|
|
39
|
+
var end_str = '</h' + heading_number + '>';
|
|
92
40
|
if(window.mode_markdown){
|
|
93
|
-
begin_str = '
|
|
41
|
+
begin_str = '#'.repeat(heading_number) + ' ';
|
|
94
42
|
end_str = '';
|
|
95
43
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if(window.mode_markdown){
|
|
100
|
-
begin_str = '- ';
|
|
101
|
-
end_str = '';
|
|
44
|
+
window.myCodeMirror.replaceSelection(begin_str + window.myCodeMirror.getSelection() + end_str);
|
|
45
|
+
if(!window.myCodeMirror.somethingSelected()){
|
|
46
|
+
window.myCodeMirror.setCursor({ line: obj_cursor.line, ch: obj_cursor.ch + begin_str.length });
|
|
102
47
|
}
|
|
103
|
-
|
|
104
|
-
|
|
48
|
+
window.myCodeMirror.focus();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var replaceBtn = e.target.closest('.codemirror-toolbar .cmt-replace');
|
|
53
|
+
if(replaceBtn){
|
|
54
|
+
var begin_str = '';
|
|
55
|
+
var end_str = '';
|
|
56
|
+
|
|
57
|
+
if(replaceBtn.classList.contains('fa-underline')){
|
|
58
|
+
begin_str = '<u>';
|
|
59
|
+
end_str = '</u>';
|
|
60
|
+
}else if(replaceBtn.classList.contains('fa-bold')){
|
|
61
|
+
begin_str = '<b>';
|
|
62
|
+
end_str = '</b>';
|
|
63
|
+
if(window.mode_markdown){
|
|
64
|
+
begin_str = '**';
|
|
65
|
+
end_str = '**';
|
|
66
|
+
}
|
|
67
|
+
}else if(replaceBtn.classList.contains('fa-italic')){
|
|
68
|
+
begin_str = '<i>';
|
|
69
|
+
end_str = '</i>';
|
|
70
|
+
if(window.mode_markdown){
|
|
71
|
+
begin_str = '*';
|
|
72
|
+
end_str = '*';
|
|
73
|
+
}
|
|
74
|
+
}else if(replaceBtn.classList.contains('fa-strikethrough')){
|
|
75
|
+
begin_str = '<s>';
|
|
76
|
+
end_str = '</s>';
|
|
77
|
+
if(window.mode_markdown){
|
|
78
|
+
begin_str = '~~';
|
|
79
|
+
end_str = '~~';
|
|
80
|
+
}
|
|
81
|
+
}else if(replaceBtn.classList.contains('fa-link')){
|
|
82
|
+
begin_str = '<a href="https://www.example.com/">';
|
|
83
|
+
end_str = '</a>';
|
|
84
|
+
if(window.mode_markdown){
|
|
85
|
+
begin_str = '[';
|
|
86
|
+
end_str = '](https://www.example.com/)';
|
|
87
|
+
}
|
|
88
|
+
}else if(replaceBtn.classList.contains('fa-quote-left')){
|
|
89
|
+
begin_str = '<blockquote>\n <p>';
|
|
90
|
+
end_str = '</p>\n</blockquote>';
|
|
91
|
+
if(window.mode_markdown){
|
|
92
|
+
begin_str = '>';
|
|
93
|
+
end_str = '';
|
|
94
|
+
}
|
|
95
|
+
}else if(replaceBtn.classList.contains('fa-list')){
|
|
96
|
+
begin_str = '<ul>\n <li>';
|
|
97
|
+
end_str = '</li>\n</ul>';
|
|
98
|
+
if(window.mode_markdown){
|
|
99
|
+
begin_str = '- ';
|
|
100
|
+
end_str = '';
|
|
101
|
+
}
|
|
102
|
+
}else if(replaceBtn.classList.contains('fa-list-ol')){
|
|
103
|
+
begin_str = '<ol>\n <li>';
|
|
105
104
|
end_str = '</li>\n</ol>';
|
|
106
105
|
if(window.mode_markdown){
|
|
107
106
|
begin_str = '1. ';
|
|
108
107
|
end_str = '';
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
}else if(replaceBtn.classList.contains('fa-code')){
|
|
110
|
+
begin_str = '{% highlight ruby linenos %}\n';
|
|
111
|
+
end_str = '{% endhighlight %}\n';
|
|
112
|
+
}else if(replaceBtn.classList.contains('fa-terminal')){
|
|
113
|
+
begin_str = '<pre>\n';
|
|
114
|
+
end_str = '\n</pre>';
|
|
115
|
+
if(window.mode_markdown){
|
|
116
|
+
begin_str = '```';
|
|
117
|
+
end_str = '```';
|
|
118
|
+
}
|
|
119
119
|
}
|
|
120
|
-
}
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
var obj_cursor = window.myCodeMirror.getCursor();
|
|
122
|
+
window.myCodeMirror.replaceSelection(begin_str + window.myCodeMirror.getSelection() + end_str);
|
|
123
|
+
if(!window.myCodeMirror.somethingSelected()){
|
|
124
|
+
var moreline = (begin_str.split('\n').length > 1 ? begin_str.split('\n').length / 2 : 0);
|
|
125
|
+
var morech = (moreline > 0 ? begin_str.split('\n')[begin_str.split('\n').length - 1].length : begin_str.length);
|
|
126
|
+
window.myCodeMirror.setCursor({ line: obj_cursor.line + moreline, ch: obj_cursor.ch + morech });
|
|
127
|
+
}
|
|
128
|
+
window.myCodeMirror.focus();
|
|
129
|
+
return;
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
});
|
|
131
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<h2><%=
|
|
1
|
+
<h2><%= CGI.escapeHTML t.edit.capitalize %></h2>
|
|
2
2
|
|
|
3
3
|
<form action="/files/update?file=<%= @file %>" method="post">
|
|
4
4
|
<% if @has_header %>
|
|
5
5
|
<div class="mb-3">
|
|
6
|
-
<label for="i-header" class="form-label"><%=
|
|
6
|
+
<label for="i-header" class="form-label"><%= CGI.escapeHTML t.header.capitalize %></label>
|
|
7
7
|
<textarea class="form-control text-editor" id="i-header" rows="3" name="header" style="font-family: <%= (['.html', '.xml', '.yml', '.js', '.md'].include?(File.extname(@file)) ? 'monospace' : 'inherit') %>"><%= @header %></textarea>
|
|
8
8
|
</div>
|
|
9
9
|
<% end %>
|
|
10
10
|
<div class="mb-3">
|
|
11
|
-
<label for="i-content" class="form-label"><%=
|
|
11
|
+
<label for="i-content" class="form-label"><%= CGI.escapeHTML t.content.capitalize %>
|
|
12
12
|
<% if ['.html','.md'].include?(File.extname(@file)) %>
|
|
13
13
|
<a href="https://jekyllrb.com/docs/liquid/" class="text-secondary" target="_blank"><i class="fas fa-question-circle"></i></a>
|
|
14
14
|
<% end %>
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
<%= ERB.new(File.read(path)).result(binding) %>
|
|
27
27
|
</script>
|
|
28
28
|
</div>
|
|
29
|
-
<button type="submit" class="btn btn-primary"><%=
|
|
29
|
+
<button type="submit" class="btn btn-primary"><%= CGI.escapeHTML t.submit.capitalize %></button>
|
|
30
30
|
</form>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h2><%=
|
|
1
|
+
<h2><%= CGI.escapeHTML t.files.capitalize %></h2>
|
|
2
2
|
|
|
3
3
|
<div class="row g-3">
|
|
4
4
|
<div class="col-auto">
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<input type="file" multiple name="files[]" class="form-control">
|
|
9
9
|
</div>
|
|
10
10
|
<div class="col-auto">
|
|
11
|
-
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%=
|
|
11
|
+
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%= CGI.escapeHTML t.create.capitalize %>"></i> <%= CGI.escapeHTML t.upload %></button>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
</form>
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
<form method="post" action="/files/create_dir?dir_path=<%= @dir_path %>">
|
|
20
20
|
<div class="row g-2 align-items-center">
|
|
21
21
|
<div class="col-auto">
|
|
22
|
-
<input type="text" name="directory_name" class="form-control" placeholder="<%=
|
|
22
|
+
<input type="text" name="directory_name" class="form-control" placeholder="<%= CGI.escapeHTML t.directory_input_placeholder %>">
|
|
23
23
|
</div>
|
|
24
24
|
<div class="col-auto">
|
|
25
|
-
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%=
|
|
25
|
+
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%= CGI.escapeHTML t.create.capitalize %>"></i> <%= CGI.escapeHTML t.create %></button>
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
28
|
</form>
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
<form method="post" action="/files/create_file?dir_path=<%= @dir_path %>">
|
|
34
34
|
<div class="row g-2 align-items-center">
|
|
35
35
|
<div class="col-auto">
|
|
36
|
-
<input type="text" name="file_name" class="form-control" placeholder="<%=
|
|
36
|
+
<input type="text" name="file_name" class="form-control" placeholder="<%= CGI.escapeHTML t.file_input_placeholder %>">
|
|
37
37
|
</div>
|
|
38
38
|
<div class="col-auto">
|
|
39
|
-
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%=
|
|
39
|
+
<button type="submit" class="btn btn-outline-secondary"><i class="fa fa-plus" title="<%= CGI.escapeHTML t.create.capitalize %>"></i> <%= CGI.escapeHTML t.create %></button>
|
|
40
40
|
</div>
|
|
41
41
|
</div>
|
|
42
42
|
</form>
|
|
@@ -46,23 +46,23 @@
|
|
|
46
46
|
<br>
|
|
47
47
|
|
|
48
48
|
<div class="table-responsive">
|
|
49
|
-
<table class="table table-striped table-sm">
|
|
49
|
+
<table class="table table-striped table-sm table-bordered">
|
|
50
50
|
<tr>
|
|
51
51
|
<th>
|
|
52
|
-
<%=
|
|
52
|
+
<%= CGI.escapeHTML t.file.capitalize %>
|
|
53
53
|
</th>
|
|
54
54
|
<th class="text-center">
|
|
55
|
-
<%=
|
|
55
|
+
<%= CGI.escapeHTML t.edit.capitalize %>
|
|
56
56
|
</th>
|
|
57
57
|
<th class="text-center">
|
|
58
|
-
<%=
|
|
58
|
+
<%= CGI.escapeHTML t.delete.capitalize %>
|
|
59
59
|
</th>
|
|
60
60
|
</tr>
|
|
61
61
|
<% if @parent_dir %>
|
|
62
62
|
<tr>
|
|
63
63
|
<td colspan="3">
|
|
64
64
|
<i class="fas fa-folder"></i>
|
|
65
|
-
<a href="/files/index?dir_path=<%= File.dirname(@dir_path) %>">[<%=
|
|
65
|
+
<a href="/files/index?dir_path=<%= File.dirname(@dir_path) %>">[<%= CGI.escapeHTML t.parent_dir.capitalize %>]</a>
|
|
66
66
|
</td>
|
|
67
67
|
</tr>
|
|
68
68
|
<% end %>
|
|
@@ -95,13 +95,13 @@
|
|
|
95
95
|
</td>
|
|
96
96
|
<td class="text-center">
|
|
97
97
|
<% if !File.directory?(f) %>
|
|
98
|
-
<a href="/files/edit?file=<%= f %>&dir_path=<%= @dir_path %>" class="btn btn-default"><i class="fa fa-edit" title="<%=
|
|
98
|
+
<a href="/files/edit?file=<%= f %>&dir_path=<%= @dir_path %>" class="btn btn-default"><i class="fa fa-edit" title="<%= CGI.escapeHTML t.edit %>"></i></a>
|
|
99
99
|
<% end %>
|
|
100
100
|
</td>
|
|
101
101
|
<td class="text-center">
|
|
102
|
-
<form method="post" action="/files/delete?file=<%= f %>" class="inline form-confirm" data-confirm="<%=
|
|
102
|
+
<form method="post" action="/files/delete?file=<%= f %>" class="inline form-confirm" data-confirm="<%= CGI.escapeHTML t.are_you_sure %>">
|
|
103
103
|
<input name="path" type="hidden" value="<%= @dir_path %>">
|
|
104
|
-
<button type="submit" class="btn btn-default"><i class="fa fa-trash" title="<%=
|
|
104
|
+
<button type="submit" class="btn btn-default"><i class="fa fa-trash" title="<%= CGI.escapeHTML t.delete %>"></i></button>
|
|
105
105
|
</form>
|
|
106
106
|
</td>
|
|
107
107
|
</tr>
|