Bug 26942: Allow style and link tags in NewsEditor TinyMCE
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / tools / koha-news.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE Koha %]
4 [% USE KohaDates %]
5 [% USE Branches %]
6 [% SET footerjs = 1 %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>Koha &rsaquo; Tools &rsaquo; News</title>
9 [% INCLUDE 'doc-head-close.inc' %]
10 [% IF ( opac_news_count ) %]
11 [% END %]
12 [% UNLESS ( wysiwyg ) %]
13     [% Asset.css("lib/codemirror/codemirror.css") | $raw %]
14     [% Asset.css("lib/codemirror/lint.min.css") | $raw %]
15     <style>
16         .CodeMirror {
17             resize: vertical;
18             z-index: 0;
19         }
20     </style>
21 [% END %]
22 </head>
23
24 <body id="tools_koha-news" class="tools">
25 [% INCLUDE 'header.inc' %]
26 [% INCLUDE 'cat-search.inc' %]
27
28 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF ( add_form ) %]<a href="/cgi-bin/koha/tools/koha-news.pl">News</a> &rsaquo; [% IF ( id ) %]
29 Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
30
31 [% IF ( add_form ) %]
32     <div class="main container-fluid">
33         <div class="row">
34             <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
35 [% ELSE %]
36     <div class="main container-fluid">
37         <div class="row">
38             <div class="col-sm-10 col-sm-push-2">
39 [% END %]
40                 <main>
41
42 [% UNLESS ( add_form ) %]
43     [% IF error_message == 'title_missing' %]
44         <div class="dialog alert">Error: Required news title missing!</div>
45     [% END %]
46 <h2>News</h2>
47 <div id="toolbar" class="btn-toolbar">
48     <a class="btn btn-default" id="newentry" href="/cgi-bin/koha/tools/koha-news.pl?op=add_form&amp;lang=[% lang | html %]"><i class="fa fa-plus"></i> New entry</a>
49 </div>
50 [% END %]
51
52 [% IF ( add_form ) %]
53     [% IF ( op == 'add' ) %]
54         [% default_lang = lang %]
55     [% ELSE %]
56         [% default_lang = new_detail.lang %]
57     [% END %]
58         <form name="add_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl" >
59             <input type="hidden" name="op" value="[% op | html %]" />
60             <input type="hidden" name="id" value="[% id | html %]" />
61                         <fieldset class="rows">
62             <legend>OPAC and Koha news</legend>
63            <ol> <li>
64             <label for="lang">Display location:</label>
65             <select id="lang" name="lang">
66                 [% PROCESS lang_locations language => default_lang %]
67             </select>
68             </li>
69             <li>
70                 <label for="branch">Library: </label>
71                 <select id="branch" name="branch">
72                     [% IF ( new_detail.branchcode == '' ) %]
73                         <option value="" selected="selected">All libraries</option>
74                     [% ELSE %]
75                         <option value=""         >All libraries</option>
76                     [% END %]
77                     [% PROCESS options_for_libraries libraries => Branches.all( selected => new_detail.branchcode, unfiltered => 1, ) %]
78                 </select>
79             </li>
80             <li>
81                 <label for="title" class="required">Title: </label>
82                 <input id="title" size="30" type="text" name="title" value="[% new_detail.title | html %]" required="required" class="required" /> <span class="required">Required</span>
83             </li>
84             <li>
85                 <label for="from">Publication date: </label>
86                 <input id="from" type="text" name="published_on" size="15" value="[% new_detail.published_on | html %]" class="datepickerfrom" />
87                                 <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
88             </li>
89             <li>
90                 <label for="to">Expiration date: </label>
91                 <input id="to" type="text" name="expirationdate" size="15" value="[% new_detail.expirationdate | html %]" class="datepickerto" />
92                 <div class="hint">
93                     [% INCLUDE 'date-format.inc' %]
94                     <br>News will still be accessible by direct URL if expired.
95                 </div>
96             </li>
97             <li>
98                 <label for="number">Appear in position: </label>
99                 [% IF ( new_detail.number ) %]
100                     <input id="number" size="3" name="number" type="text" value="[% new_detail.number | html %]" />
101                 [% ELSE %]
102                     <input id="number" size="3" name="number" type="text" />
103                 [% END %]
104             </li>
105             <li><label for="content">News: </label>
106             <textarea name="content" id="content"  cols="75" rows="10">[% new_detail.content | html %]</textarea>
107             </li>
108             </ol>
109                         </fieldset>
110   
111                 <fieldset class="action"><input class="button" type="submit" value="Submit" /> <a class="cancel" href="/cgi-bin/koha/tools/koha-news.pl">Cancel</a></fieldset>
112         </form>
113     [% ELSE %]
114         [% IF ( opac_news_count ) %]
115         <form id="del_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl">
116                 <table id="newst">
117                    <thead> <tr>
118                         <th class="NoSort">&nbsp;</th>
119                         <th>Location</th>
120                         <th>Library</th>
121                         <th>Number</th>
122                         <th class="title-string">Publication date</th>
123                         <th class="title-string">Expiration date</th>
124                         <th class="anti-the">Title</th>
125                         <th>Author</th>
126                         <th class="anti-the">News</th>
127                         <th class="NoSort noExport">Actions</th>
128                     </tr></thead>
129                     <tbody>[% FOREACH opac_new IN opac_news %]
130                          [% IF ( opac_new.expired ) %]
131                             <tr class="expired">
132                             [% ELSE %]
133                             <tr>
134                             [% END %]
135                             <td>
136                                 <input type="checkbox" name="ids" value="[% opac_new.idnew | html %]" />
137                             </td>
138                             <td>[% SWITCH opac_new.lang %]
139                                 [%   CASE "koha" %]
140                                     Librarian interface
141                                 [%   CASE "slip" %]
142                                     Slip
143                                 [%   CASE "" %]
144                                     All
145                                 [%   CASE %]
146                                     OPAC ([% opac_new.lang | html %])
147                                 [% END %]
148                              </td>
149                             <td>[% IF ( opac_new.branchcode == "" ) -%]
150                                 All libraries
151                                 [% ELSE %][% opac_new.branchname | html %]
152                                 [% END %]</td>
153                             <td>[% opac_new.number | html %]</td>
154                             <td><span title="[% opac_new.newdate | html %]">[% opac_new.newdate | $KohaDates %]</span></td>
155                             <td><span title="[% opac_new.expirationdate | html %]">[% opac_new.expirationdate | $KohaDates %] [% IF ( opac_new.expired ) %](<span class="expired">expired</span>)[% END %]</span></td>
156                             <td>[% opac_new.title | html %]</td>
157                             <td>[% opac_new.author_title | html %] [% opac_new.author_firstname | html %] [% opac_new.author_surname | html %]</td>
158                             <td>
159                                 <div class="btn-group">
160                                     <a class="preview_news btn btn-default btn-xs" data-number="[% loop.count | html %]"><i class="fa fa-eye" aria-hidden="true"></i> Preview content</a>
161                                 </div>
162                                 <div id="contentModal[% loop.count | html %]" class="modal" tabindex="-1" role="dialog" data-number="[% loop.count | html %]">
163                                     <div class="modal-dialog" role="document">
164                                         <div class="modal-content modal-lg">
165                                             <div class="modal-header">
166                                                 <h5 class="modal-title">Preview of: "[% opac_new.title | html %]"</h5>
167                                             </div>
168                                         <div class="modal-body">
169                                             [% opac_new.content | $raw %]
170                                         </div>
171                                         <div class="modal-footer">
172                                             <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
173                                         </div>
174                                     </div>
175                                 </div>
176                             </td>
177                             <td class="actions">
178                                 [% IF ( wysiwyg ) %]
179                                     [% SET editmode = "wysiwyg" %]
180                                 [% ELSE %]
181                                     [% SET editmode = "text" %]
182                                 [% END %]
183                                 <div class="btn-group dropup">
184                                     <a href="/cgi-bin/koha/tools/koha-news.pl?op=add_form&amp;id=[% opac_new.idnew | uri %]&editmode=[% editmode | uri %]" class="btn btn-default btn-xs"> <i class="fa fa-pencil"></i> Edit</a><button class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
185                                         <span class="caret"></span>
186                                     </button>
187                                     <ul class="dropdown-menu pull-right">
188                                         <li>
189                                             [% IF ( wysiwyg ) %]
190                                                 <a href="/cgi-bin/koha/tools/koha-news.pl?op=add_form&amp;id=[% opac_new.idnew | uri %]&editmode=text"><i class="fa fa-pencil"></i> Edit with text editor</a>
191                                             [% ELSE %]
192                                                 <a href="/cgi-bin/koha/tools/koha-news.pl?op=add_form&amp;id=[% opac_new.idnew | uri %]&editmode=wysiwyg"><i class="fa fa-pencil"></i> Edit with WYSIWYG editor</a>
193                                             [% END %]
194                                         </li>
195                                     </ul>
196                                 </div>
197                                 <div class="btn-group">
198                                     <a href="/cgi-bin/koha/tools/koha-news.pl?op=del&amp;ids=[% opac_new.idnew | uri %]" class="delete_news btn btn-default btn-xs"><i class="fa fa-trash"></i> Delete</a>
199                                 </div>
200                             </td>
201                         </tr>
202                     [% END %]</tbody>
203                 </table>
204                 <input type="hidden" name="op" value="del" />
205                 <fieldset class="action"><input type="submit" class="button" value="Delete selected" /></fieldset>
206             </form>
207         [% ELSE %]
208             <div class="dialog message">There are no news items.</div>
209         [% END %]
210     [% END %]
211
212                 </main>
213             [% UNLESS ( add_form ) %]
214                 </div> <!-- /.col-sm-10.col-sm-push-2 -->
215
216                 <div class="col-sm-2 col-sm-pull-10">
217                     <aside>
218
219                         <div id="news-filter">
220                             <form action="/cgi-bin/koha/tools/koha-news.pl" method="get">
221                                 <h4>Filter</h4>
222                                 <fieldset class="brief">
223                                     <ol>
224                                         <li>
225                                             <label for="news_keyword">Keyword:</label>
226                                             <input type="text" name="news_keyword" id="news_keyword" />
227                                         </li>
228                                         <li>
229                                             <label for="news_display_location">Display location:</label>
230                                             <select name="news_display_location" id="news_display_location">
231                                                 [% PROCESS lang_locations %]
232                                             </select>
233                                         </li>
234                                         <li>
235                                             <label for="news_library">Library: </label>
236                                             <select id="news_library" name="news_library">
237                                                 <option value=""></option>
238                                                 <option value="">All libraries</option>
239                                                 [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
240                                             </select>
241                                         </li>
242                                         <li>
243                                             <label>
244                                                 <input type="checkbox" name="show_expired" id="show_expired" /> Show expired
245                                             </label>
246                                         </li>
247                                     </ol>
248                                 </fieldset>
249                             </form>
250                         </div>
251
252                         [% INCLUDE 'tools-menu.inc' %]
253                     </aside>
254                 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
255             [% END %]
256         </div> <!-- /.row -->
257     </div> <!-- /.main.container-fluid -->
258
259
260 [% MACRO jsinclude BLOCK %]
261     [% INCLUDE 'calendar.inc' %]
262     [% Asset.js("js/tools-menu.js") | $raw %]
263     [% IF ( opac_news_count ) %]
264         [% INCLUDE 'datatables.inc' %]
265         <script>
266             $('.preview_news').click( function() {
267                 modalNumber = $(this).attr('data-number');
268                 $('.modal[data-number="'+modalNumber+'"]').modal('show');
269             })
270             function Checkbox(){
271                 var form = document.getElementById('del_form');
272                 var inputs = form.getElementsByTagName('input');
273                 var checked = false;
274                 for (var i=0; i<inputs.length; i++) {
275                     if (inputs[i].type == 'checkbox' && inputs[i].name == 'ids') {
276                         checked = inputs[i].checked;
277                         if (checked) return true;
278                     }
279                 }
280             }
281
282             function filterDataTable( table, column, term ){
283                 if( column ){
284                     table.column( column ).search( term ).draw();
285                 } else {
286                     table.search( term ).draw();
287                 }
288                 clearFilter( term );
289             }
290
291             function clearFilter( term ){
292                 if( term == "" ){
293                     $(".dt_button_clear_filter").addClass("disabled");
294                 } else {
295                     $(".dt_button_clear_filter").removeClass("disabled");
296                 }
297             }
298
299             /* Custom table search configuration: If a table row
300                has an "expired" class, hide it UNLESS the
301                show_expired checkbox is checked */
302             $.fn.dataTable.ext.search.push(
303                 function( settings, searchData, index, rowData, counter ) {
304                     var row = $(settings.aoData[index].nTr);
305                     if( row.hasClass("expired") && !$("#show_expired").prop("checked") ){
306                         return false;
307                     } else {
308                         return true;
309                     }
310                 }
311             );
312
313             $(document).ready(function() {
314                 var newst = $("#newst").DataTable($.extend(true, {}, dataTablesDefaults, {
315                     "order": [[ 4, "desc" ]],
316                     "aoColumnDefs": [
317                         { "sortable": false, "searchable": false, 'targets': [ 'NoSort' ] },
318                         { "type": "anti-the", "targets": [ "anti-the" ] },
319                         { "type": "title-string", "targets" : [ "title-string"] }
320                     ],
321                     "sPaginationType": "full_numbers"
322                 }));
323
324                 $(".delete_news").on("click", function(){
325                     return confirmDelete( _("Are you sure you want to delete this news item? This cannot be undone.") );
326                 });
327
328                 $("#del_form").on("submit",function(){
329                     if ( Checkbox() ) {
330                         return confirmDelete( _("Are you sure you want to delete the selected news?") );
331                     } else {
332                         alert(_("Please select a news item to delete."));
333                         return false;
334                     }
335                 });
336
337                 $("#show_expired").on("change", function(){
338                     /* redraw the DataTable according to the custom search function */
339                     newst.draw();
340                 });
341
342                 newst.on( 'search.dt', function () {
343                     var term = newst.search();
344                     $("#news_keyword").val( term );
345                 });
346
347                 $("#news_keyword").on("keyup", function(){
348                     var term = $(this).val();
349                     filterDataTable( newst, null, term );
350                 });
351
352                 $("#news_display_location").on("change", function(){
353                     var term = $(this).val();
354                     filterDataTable( newst, 1, term );
355                 });
356
357                 $("#news_library").on("change", function(){
358                     // Table must be filtered by the <option>'s text, not its value
359                     var opt = $(this).find("option:selected").text();
360                     filterDataTable( newst, 2, opt );
361                 });
362
363                 $(".dt_button_clear_filter").on("click", function(){
364                     newst.search('').columns().search('').draw();
365                     $("#news-filter select").each(function(){
366                         $(this).val("");
367                     });
368                 });
369             });
370         </script>
371     [% END %]
372     [% UNLESS ( wysiwyg ) %]
373         [% Asset.js( "lib/codemirror/codemirror.min.js" ) | $raw %]
374         [% Asset.js( "lib/codemirror/xml.min.js" ) | $raw %]
375         [% Asset.js( "lib/codemirror/lint.min.js" ) | $raw %]
376         [% Asset.js( "lib/linters/htmlhint.min.js" ) | $raw %]
377         [% Asset.js( "lib/codemirror/html-lint.min.js" ) | $raw %]
378         <script>
379             var editor = CodeMirror.fromTextArea(document.getElementById('content'), {
380                 lineNumbers: true,
381                 lineWrapping: true,
382                 lint: true,
383                 mode: "text/html",
384                 gutters: ["CodeMirror-lint-markers"],
385                 viewportMargin: Infinity,
386             });
387         </script>
388     [% ELSE %]
389         [% Asset.js("lib/tiny_mce/tinymce.min.js") | $raw %]
390         [% INCLUDE 'str/tinymce_i18n.inc' %]
391         <script>
392             tinyMCE.init({
393                 verify_html: false,
394                 force_br_newlines : false,
395                 force_p_newlines : false,
396                 forced_root_block : '',
397                 branding : false,
398                 relative_urls : false,
399                 content_css : "[% interface | html %]/[% theme | html %]/css/tinymce.css",
400                 menubar : "file edit view insert format tools table",
401                 mode : "specific_textareas",
402                 plugins : "autoresize table hr link image charmap lists code emoticons",
403                 extended_valid_elements:"style,link[href|rel]",
404                 custom_elements:"style,link,~link",
405                 toolbar : [
406                     "formatselect | bold italic | cut copy paste | alignleft aligncenter alignright | outdent indent | image link unlink anchor cleanup hr",
407                     "table | bullist numlist | undo redo | removeformat | emoticons charmap | forecolor backcolor | code visualaid help"
408                 ],
409             });
410         </script>
411     [% END # /IF NewsToolEditor %]
412 [% END %]
413
414 [% BLOCK lang_locations %]
415     [% IF ( language == "" ) %]
416         <option value="" selected="selected"></option>
417     [% ELSE %]
418         <option value="">All</option>
419     [% END %]
420     [% IF ( language == "koha" ) %]
421         <option value="koha" selected="selected">Librarian interface</option>
422     [% ELSE %]
423         <option value="koha">Librarian interface</option>
424     [% END %]
425     [% IF ( language == "slip" ) %]
426         <option value="slip" selected="selected">Slip</option>
427     [% ELSE %]
428         <option value="slip">Slip</option>
429     [% END %]
430     [% FOREACH lang_lis IN lang_list %]
431         <optgroup label="[% lang_lis.language | html %]">
432             [% FOREACH location IN [ '', 'OpacNavRight', 'opacheader', 'OpacCustomSearch', 'OpacMainUserBlock', 'opaccredits', 'OpacLoginInstructions', 'OpacSuggestionInstructions'] %]
433                 [% IF ( location == '' ) %]
434                     [% SET location_lang = lang_lis.language %]
435                     [% location = BLOCK %]OPAC news[% END %]
436                 [% ELSE %]
437                     [% SET location_lang = location _ "_" _ lang_lis.language %]
438                 [% END %]
439                 [% IF ( location_lang == language ) %]
440                     <option value="[% location_lang | html %]" selected="selected">[% location | html %] ([% lang_lis.language | html %])</option>
441                 [% ELSE %]
442                     <option value="[% location_lang | html %]">[% location | html %] ([% lang_lis.language | html %])</option>
443                 [% END %]
444             [% END %]
445         </optgroup>
446     [% END %]
447 [% END %]
448
449 [% INCLUDE 'intranet-bottom.inc' %]