Line # Revision Author
1 8 ahitrov@rambler.ru <fieldset>
2 <legend>Документы\
3 % if ( ref $link_class eq 'ARRAY' ) {
4 разрешенных классов
5 % } elsif ( $link_class ) {
6 класс <% $link_class %>\
7 % if ($use_section) {
8 c учетом текущей секции\
9 % }
10 % } else {
11 в разделе\
12 % }
13 % if ($total > 0) {
14 (всего: <% $total %>, показано с <% $first + 1 %> по <% ($first + $n > $total) ? $total : $first + $n %>)
15 % }
16 </legend>
17 % if ( ref $link_class eq 'ARRAY' && @$link_class ) {
18 <div class="textnorm"><b>Разрешены классы:</b><br>
19 % if ( scalar @desired_class == 1 ) {
20 <b style="color:olive;"><% $desired_class[0] %></b>
21 % } else {
22 % my $i = 0;
23 % foreach my $dclass ( @desired_class ) {
24 % $m->out (', ') if $i++;
25 % if ( $restrict_class eq $dclass ) {
26 105 ahitrov <b style="color:olive;"><% $dclass %></b>
27 8 ahitrov@rambler.ru % } else {
28 <a href="?class=<% $class %>&restrict_class=<% $dclass %>"><% $dclass %></a>
29 % }
30 % }
31 % }
32 </div>
33 % }
34 % if ( $total or defined $alpha or defined $search ) {
35 117 ahitrov <div style="font-size:12px; font-family:Arial;">
36 8 ahitrov@rambler.ru <table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0 0; border:1px solid gray;">
37 <tr bgcolor="#e0e0e0"><th colspan="4">Поиск по букве:&nbsp;&nbsp;[<a href="?class=<% $class %>" style="font-weight:normal;">сброс фильтра</a>]</th></tr>
38 117 ahitrov <tr><td style="font-size:12px; font-family:Arial; padding:2px 4px;">
39 8 ahitrov@rambler.ru <& /inc/alpha.msn, alpha=>$alpha, params=>\%ARGS, &>
40 </td></tr></table>
41
42 % ## Форма поиска. Работает при включенном фильтре класса
43 % ## и описанной для класса функции search_fields
44 % ########################################################
45 % if ( $filter{class} && (!ref $filter{class} || ( ref $filter{class} eq 'ARRAY' && scalar @{ $filter{class} } == 1 ) ) ) {
46 % my $search_class = ref $filter{class} eq 'ARRAY' ? $filter{class}->[0] : $filter{class};
47 % my $document = $search_class->new ($keeper);
48 % my @fields = $document->search_fields;
49 % if ( @fields ) {
50 % my @props = $document->required_properties;
51 <form action="<% $dest_class ? 'destination' : 'source' %>.html">
52 <table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0; border:1px solid gray;">
53 <tr bgcolor="#e0e0e0"><th colspan="4">Поиск по полю:&nbsp;&nbsp;[<a href="?class=<% $class %>" style="font-weight:normal;">сброс фильтра</a>]</th></tr><tr>
54 <td width="1%" nowrap style="padding:2px 0 2px 4px;"><select name="search_by">
55 % foreach my $field ( @fields ) {
56 % my ($prop) = grep { $_->{'attr'} eq $field } @props;
57 % my $selected = $field eq $search_by ? ' selected' : '';
58 <option value="<% $field %>"<% $selected %>><% $prop->{'rusname'} %>
59 % }
60 </td><td width="0">:</td>
61 <td width="98%"><input type="text" name="search" value="<% $search %>" style="width:100%"></td>
62 <td width="1%" style="padding:2px 4px 2px 0;"><input type="submit" value=" &raquo; " style="border:1px solid gray;"></td>
63 </tr></table>
64 % if ( $id ) {
65 <input type="hidden" name="id" value="<% $id %>">
66 % }
67 % if ( $class ) {
68 <input type="hidden" name="class" value="<% $class %>">
69 % }
70 % if ( $use_section ) {
71 <input type="hidden" name="use_section" value="<% $use_section %>">
72 % }
73 </form>
74 % }
75 % }
76
77 <div style="height:5px"><spacer type="block" height="5"></div>
78 <& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, params=>\%ARGS, &>
79 </div>
80
81 <table width="100%" border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
82 <tr bgcolor="#efefef">
83 %
84 % foreach (@columns) {
85 %
86 <th><% $_->{rusname} %></th>
87 %
88 % }
89 %
90 </tr>
91 %
92 % foreach my $document (@documents) {
93 %
94 % next unless ref($document);
95 % my $document_access = $user->section_accesses($user, $document->section);
96 %
97 <tr valign="top">
98 %
99 % for my $col (@columns) {
100 %
101 % if ($col->{attr} eq '_sort_') {
102 %
103 <td width="20px"><% $document->{sorder} %>&nbsp;<a href="document_move.html?id=<% $document->{id} %>&move=up&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-up-9x10.gif" border=0 alt="Переместить документ на шаг вверх"></a>&nbsp;<a href="document_move.html?id=<% $document->{id} %>&move=down&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-down-9x10.gif" border=0 alt="Переместить документ на шаг вниз"></a>\
104 %
105 % } elsif ($col->{attr} eq 'dtime') {
106 %
107 <td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{dtime} &>\
108 %
109 % if ($document->{ctime} ne $document->{mtime}) {
110 %
111 % my $colortime = '#c66';
112 %
113 <div style="color:<% $colortime %>;"><& "/contenido/components/show_dtime.msn", dtime=>$document->{mtime} &></div>\
114 %
115 % }
116 %
117 % } elsif ($col->{attr} eq 'name') {
118 %
119 <td><span class="<% $document->status ? '':'hiddensect' %>">\
120 %
121 % my $name=$document->name ? $document->name : 'Безымянный документ N'.$document->id;
122 % $name =~ s/'/\\'/g;
123 % $name =~ s/"/&quot;/g;
124 % if ($document_access == 2) {
125 %
126 <a href="#" onclick="<% $dest_class ? 'AppendDest' : 'AppendSource' %>(<% $document->id %>, '<% $document->class %>','<% $name %>');"><% $name %>&nbsp;</a>\
127 %
128 % } else {
129 %
130 <% $name %>&nbsp;\
131 %
132 % }
133 %
134 </span>\
135 %
136 % } elsif ($col->{attr} eq 'id') {
137 %
138 <td><span class="<% $document->status ? '':'hiddensect' %>">\
139 %
140 % if ($document_access == 2) {
141 %
142 <a href="document.html?id=<% $document->id %>&class=<% $document->class %>"><% $document->id %>&nbsp;</a>\
143 %
144 % } else {
145 %
146 <% $document->id %>&nbsp;\
147 %
148 % }
149 %
150 </span>\
151 %
152 % } elsif ($col->{attr} eq 'class') {
153 %
154 <td><% $document->class_name %>&nbsp;<font color="#999999">(<% $document->class %>)</font>\
155 %
156 % } elsif ($col->{type} eq 'datetime') {
157 %
158 <td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{$col->{attr}} &>\
159 %
160 % } elsif ($col->{attr} eq '_act_') {
161 %
162 <td>\
163 % if ($document_access == 2) {
164 % my $name=$document->name ? $document->name : 'Безымянный документ N'.$document->id;
165 % $name =~ s/'/\\'/g;
166 % $name =~ s/"/&quot;/g;
167 %
168 <a href="#" onclick="<% $dest_class ? 'AppendDest' : 'AppendSource' %>(<% $document->id %>, '<% $document->class %>', '<% $name %>');">связать</a>\
169 %
170 % } else {
171 &nbsp;\
172 % }
173 %
174 % } else {
175 %
176 % if ($col->{type} eq 'date') {
177 % my $date=$document->{$col->{attr}};
178 % $date=~/(\d{4}-\d{2}-\d{2})/;
179 <td nowrap align="right"><% $1 || '&nbsp;' %>\
180 % } elsif ($col->{type} eq 'datetime') {
181 <td nowrap align="right"><% $document->{$col->{attr}} || '&nbsp;' %>\
182 % } elsif ($col->{type} eq 'integer') {
183 <td align="right"><% $document->{$col->{attr}} %>&nbsp;\
184 % } elsif ($col->{type} eq 'lookup') {
185 <td align="left">\
186 % my $id = $document->{$col->{attr}};
187 % if ($id) {
188 % my ($doc)=$keeper->get_documents( ( ref($col->{lookup_opts}) ? %{$col->{lookup_opts}} : () ), id=>$id);
189 % if ($doc) {
190 <a href="document.html?id=<% $doc->id %>&class=<% $doc->class %>"><% $doc->name || $doc->id %></a>&nbsp;\
191 % } else {
192 <span class="hiddensect"><% $document->{$col->{attr}} %>???</span>\
193 % }
194 % } else {
195 <span class="hiddensect">NULL</span>\
196 % }
197 % } elsif ($col->{type} eq 'status') {
198 % my $status_map = ref $col->{cases} eq 'ARRAY' ? $col->{cases} : $keeper->default_status();
199 % my ($doc_status) = grep { $_->[0] == $document->{$col->{attr}} } @$status_map;
200 % $doc_status ||= [$document->{$col->{attr}}, 'Неизвестный'];
201 <td nowrap><% $doc_status->[1].'('.$doc_status->[0].')' %>\
202 % } else {
203 <td><% defined($document->{$col->{attr}}) ? $document->{$col->{attr}} : '&nbsp;' %>\
204 % }
205 % }
206 %
207 </td>
208 %
209 % } #- for @columns
210 %
211 </tr>
212 % } #- foreach @documents
213 </table>
214
215 117 ahitrov <div style="font-size:12px; font-family:Arial;">
216 8 ahitrov@rambler.ru <& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, params=>\%ARGS, &>
217 <div style="height:5px"><spacer type="block" height="5"></div>
218 </div>
219
220 % } else {
221 <h4 align="center"><i>---- Нет документов -----</i></h4>
222 % }
223 %
224
225 </fieldset>
226 <%args>
227
228 $id => 1
229 $p => 1
230 $class => undef
231 $source_class => undef
232 $dest_class => undef
233 $use_section => undef
234 $alpha => undef
235 $alpha_search => undef
236 $search_by => undef
237 $search => undef
238 $restrict_class => undef
239
240 </%args>
241 <%init>
242
243 my @desired_class = @{ $source_class || $dest_class };
244 my $link_class = []; @$link_class = map { $_ } @desired_class;
245 if ( ref $link_class eq 'ARRAY' && scalar @$link_class > 1 && $restrict_class ) {
246 @$link_class = grep { $_ eq $restrict_class } @$link_class;
247 }
248 my $owner;
249 # Операции...
250 if ($id && ($id > 0)) {
251 $owner = $keeper->get_section_by_id($id);
252 }
253 if (! ref($owner)) {
254 return undef;
255 }
256 # Фильтры работают в любом случае...
257 my $filter = $m->comp('/contenido/components/context.msn', name => 'filter');
258 my $profile = $m->comp('/contenido/components/context.msn', name => 'profile');
259
260 unless (defined $request->{section_accesses}->{$id}) {
261 $request->{section_accesses}->{$id} = $user->get_section_access($id);
262 }
263 my $section_access = $request->{section_accesses}->{$id};
264 my (@documents, $total);
265
266 my $s = $owner->id;
267 my $sorted = $owner->_sorted();
268 $s .= ",$filter" if ($filter > 0);
269
270 my %filter=();
271 21 ahitrov@rambler.ru my %order = (not $link_class and $owner->order_by) ? (order_by => $owner->order_by) : (order_by => 'id desc');
272 8 ahitrov@rambler.ru if ($alpha) {
273 $filter{ilike}=1;
274 $filter{ $alpha_search || 'name' }="$alpha%";
275 $order{order}=['name','reverse'];
276 delete $order{order_by};
277 }
278
279 $filter{class} = $owner->default_document_class if $owner->default_document_class;
280 $filter{class}=$link_class if ($link_class || (ref $link_class eq 'ARRAY' && @$link_class) );
281 $filter{s}=$s unless ($link_class && !$use_section);
282 if ( $search_by && $search ) {
283 $filter{$search_by}='%'.$search.'%';
284 $filter{ilike} = 1;
285 }
286
287 $total = $keeper->get_documents(%filter, count=>1);
288
289 my $n = 40;
290 my $first = $n * ($p - 1);
291 ($first,$p)=(0,0) if ($first>$total);
292
293 if ($link_class && !$use_section) {
294 @documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
295 } elsif ($sorted) {
296 @documents = $keeper->get_sorted_documents(%filter, limit=>$n, offset=>$first, light=>1);
297 } else {
298 @documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
299 }
300
301 # набор колонок таблицы документов...
302 my @columns;
303
304 #работаем по 1 полученному документу (если таковой есть в наличии)
305 if (@documents and (ref $documents[0])) {
306 @columns = $sorted ? ({attr => '_sort_', name => 'N'}) : ();
307
308 # пытаемся найти колонки, которые документ сам пожелал показать (required_properties -> column)...
309 push @columns,
310 sort {$a->{column} <=> $b->{column}}
311 grep {$_->{column}} $documents[0]->structure;
312
313 # стандартная жопка таблицы...
314 @columns = (@columns,
315 {attr => '_act_', rusname => 'Действия'},
316 );
317 }
318
319 </%init>

Небольшая справка по веткам

cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.

koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.

utf8 – актуальная ветка, заточенная под UTF-8.

Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.