Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
13 posts Page 1 of 2
Hey folks,

It's been a widely requested feature and I am proud to deliver it right now as in screenshots.
download (2).png
download (2).png (12.18 KiB) Viewed 4096 times

download (3).png
download (3).png (27.34 KiB) Viewed 4096 times

download (4).png
download (4).png (6.63 KiB) Viewed 4096 times

Pagination between cloned pages in admin panel is a time-saver and makes it easier to navigate, edit, view etc. No more hitting back and forth, I guess. Hope to hear your feedbacks, guys :D

My Documentation, Addons, Functions.
Join COUCH telegram channel
I did use this function today, and i must say WOW. Makes the experience better and you can work more efficiant. If you have many pages like blog posts you can easyli just go back and forward without going out and then inn again like before.

Thank Trendoman for this on the current project :)
Thank you, @kimheggen :D

Today I worked on a very long page and it was pain to scroll down to view the page. So I added new links to my pagination: Open template, Open Page.
download.png (3.54 KiB) Viewed 4065 times

Also, I thought, sometimes it is very comfy to Delete Page, especially while in development. It would be nice for super-admin mostly, and I added this link with a simple check to make sure clients (logged-in as admins only) won't delete anything by chance.

Updated the whole code in the first post and fixed behavior for system-reserved template 'Users', which doesn't report much info about itself and therefore the code was not working correctly there. Now, pagination shouldn't appear in such places.

My Documentation, Addons, Functions.
Join COUCH telegram channel
Complete overhaul was needed to increase the speed of code. It was too slow for a 1000 clonable pages, almost several seconds (5-6 sec) to calculate positions etc. Very ineffective!

Actually, the original code was over 20 sec, then optimized with parameter of cms:pages skip_custom_fields='1' it was close to reality with around 10 sec and best result 5-6 sec.
download (2).png
download (2).png (2.29 KiB) Viewed 4016 times

Now the thing is over 200 times faster!

download.png (4.98 KiB) Viewed 4016 times

It was possible thanks to earlier examples provided by @KK and a tag custom SQL queries from 2013 :D I really should think about using it more often as complexity grows. It is not only hundreds time faster, it's also very nice looking and beautifully coded. Art of the Speed :twisted: Rrrmm, Rmmm, Weeeaouww :lol:

Seriously, crazy stuff :)

A hint: to write the beautiful sql code it is not needed to write it actually :) return_sql='1' for cms:pages will show full sql query.
Code: Select all
<cms:pages start_on=k_page_date return_sql='1'  />

CouchCMS with no knowledge of PHP or SQL required :D

3a1f512d18d63c097653e820fc6e44342d9f70e8.jpg (26.87 KiB) Viewed 4020 times

My Documentation, Addons, Functions.
Join COUCH telegram channel
Thanks Anton - this code works beautifully!
I must say that there is little problem in version 2, however!
<cms:admin_delete_link /> not works, my question is - this tag will support in version 2?

trendoman wrote: Hey folks...I have also added titles for pages, truncated to 20 chars, to make everything more UI-friendly. Hope to hear your feedbacks, guys :D

First, thanks for putting this together. I have found it very helpful.

Even though I'm not using your revised version, with the SQL query, I modified your original snippet to look and feel more like the admin theme, with a bit of CSS, uses icons, without the delete button as it didn't work, and with the use of localization strings where possible ("view" and "page"; but not for "first", "of" or "last").

Code: Select all
<cms:set page_translated="<cms:php>
  $words = array_map('strtolower', array_map('trim', array(\"<cms:localize 'pages'/>\",\"<cms:localize 'original_page'/>\",\"<cms:localize 'parent_page'/>\",\"<cms:localize 'points_to_another_page'/>\")));
  $sort_by_strlen = create_function('$a, $b', 'if (strlen($a) == strlen($b)) { return strcmp($a, $b); } return (strlen($a) < strlen($b)) ? -1 : 1;');
  usort($words, $sort_by_strlen);
  $longest_common_substring = array();
  $shortest_string = str_split(array_shift($words));
  while (sizeof($shortest_string)) { array_unshift($longest_common_substring, ''); foreach ($shortest_string as $ci => $char) { foreach ($words as $wi => $word) { if (!strstr($word, $longest_common_substring[0] . $char)) { break 2; } } $longest_common_substring[0].= $char; } array_shift($shortest_string); }
  usort($longest_common_substring, $sort_by_strlen);
  echo ucfirst(array_pop($longest_common_substring));
</cms:php>" />
<cms:if k_template_is_clonable>
  <cms:set total_pages = "<cms:pages count_only='1' skip_custom_fields='1'/>" scope='global'/>
  <cms:if total_pages>
    <style>.panel{padding:15px;border:1px solid #ddd;border-radius:2px;}.pull-right{float:right !important;}.pagination>li>a{margin-right:0px;}.pagination>li{display:inline;}.btn-icon-right{margin:0 -15px 0 10px;}</style>
    <cms:set edited_page_id = k_page_id scope='global'/>
    <cms:pages paginate='0' limit='1000000' orderby='publish_date' order='desc' skip_custom_fields='1'><cms:if k_page_id = edited_page_id><cms:set current_position = k_current_record scope='global'/></cms:if></cms:pages>
    <cms:set prev_page_num = "<cms:sub current_position '1'/>"/>
    <cms:set next_page_num = "<cms:add current_position '1'/>"/>
    <div class="panel">
      <a class="btn btn-success" href="<cms:show k_template_link/>" target="_blank"><span class="btn-icon"><cms:show_icon 'magnifying-glass'/></span><cms:localize 'view'/> <cms:show k_template_title/></a>
      <ul class="pagination pull-right">
        <cms:pages paginate='0' limit='1000000' orderby='publish_date' order='desc' skip_custom_fields='1'><cms:if k_current_record = prev_page_num>
          <a class="btn" href='<cms:pages masterpage=k_template_name offset="<cms:sub current_page_num prev_page_num/>"  limit='1' skip_custom_fields='1'><cms:admin_link/><cms:set title=k_page_title scope="global"/></cms:pages>'><span class="btn-icon"><cms:show_icon 'media-step-backward'/></span>First</a>
          <a class="btn" href='<cms:pages masterpage=k_template_name offset="<cms:sub prev_page_num '1'/>"  limit='1' skip_custom_fields='1'><cms:admin_link/><cms:set title=k_page_title scope="global"/></cms:pages>'><span class="btn-icon"><cms:show_icon 'arrow-circle-left'/></span>"<cms:excerpt count='20' truncate_chars='1'><cms:show title/></cms:excerpt>"</a>
        </cms:if><cms:if k_current_record = current_position>
          <a class="btn btn-success" href='<cms:show k_page_link/>'><span class="btn-icon"><cms:show_icon 'magnifying-glass'/></span><cms:show page_translated /> <cms:show current_position/> of <cms:show total_pages/></a>
        </cms:if><cms:if k_current_record = next_page_num>
          <a class="btn" href='<cms:pages masterpage=k_template_name offset=current_position  limit='1' skip_custom_fields='1'><cms:admin_link/><cms:set title=k_page_title scope="global"/></cms:pages>'>"<cms:excerpt count='20' truncate_chars='1'><cms:show title/></cms:excerpt>"<span class="btn-icon btn-icon-right"><cms:show_icon 'arrow-circle-right'/></span></a>
          <a class="btn" href='<cms:pages masterpage=k_template_name offset="<cms:sub total_pages '1'/>" limit='1' skip_custom_fields='1'><cms:admin_link/><cms:set title=k_page_title scope="global"/></cms:pages>'>Last<span class="btn-icon btn-icon-right"><cms:show_icon 'media-step-forward'/></span></a>

Hope this can be of use to someone!


den0x, thank you very much for adapting original concept to CouchCMS 2. I tested it and found it looks and works just awesome (at first glance). Nice and thoughtful!

SQL version was needed for a job with thousands of cloned pages and older version of CMS. If something similar appears at hands with modern version of Couch, I'll try to revisit this topic and post changes.

Also, limit='0' equals to limit='1000' in Couch. In SQL version I didn't use limit at all, because number of pages was well above 1000. In short, changing in your code (and my original non-sql code) limit='0' to limit='10000000000000' :) should help try pagination correctly for such cases.

My Documentation, Addons, Functions.
Join COUCH telegram channel
You're welcome and good point with regards to limit. I updated my post with both limits increased to 1000000.

I'm only just starting to explore CouchCMS in more detail and don't have something with that many pages yet.
I'd be curious if anyone's experience points to it still causing a poor performance at some point, and thus requiring SQL.
We'll find out here at some point I suppose!
@den0x, I found (again) your post very valuable. I have merged another code from post viewtopic.php?f=8&t=11665 to Approve-Un-approve pages. I.e. publish-unpublish.

2018-08-05-004.png (26.63 KiB) Viewed 2852 times

2018-08-05-005.png (20.12 KiB) Viewed 2852 times

My use-case is that I quickly review a page and do the 'unpublish' thing. Page has a link to video and a zip and my backend code checks if file is indeed present (viewtopic.php?f=8&t=11691). Pages were auto-generated from external source and some files are missing. This combined setup helps immensely.

My Documentation, Addons, Functions.
Join COUCH telegram channel
@den0x, I am back to this topic..

I have reviewed (again) your snippet very thoughtfully, diving deep into whatever you were trying to achieve with raw php. I have to say, there is too much effort put in place to find a translation for 'Page' word. I am going to replace the whole php thing with a statement -
Code: Select all
<cms:set page_translated='Page' scope='global' />

Maybe you agree that it's easy for the superadmin to set whatever localized word is desired, because setting it automatically looks a bit weird and an overkill for the task. (Note for @KK to add a word 'Page' to localization files).

In my next effort, I removed several extra cms:pages calls which greatly optimized the code readability and performance. Also, there is a lack of show_unpublished='1' show_future_entries='1' params, which skips some pages unintentionally. Finally, if user configures list-view of a template by cms:config_list_view, we must follow its 'order', 'orderby' and 'exclude' parameters, don't you agree? I have written a function that helps get those params -
Code: Select all
<cms:func 'get_config_list' masterpage='' var='' >

When I got the final result of my rewriting (and extra styling to cater for mobiles), I couldn't help myself but test it on a bigger scale template. Of course, cmspages-based snippet failed miserably if the limit was correct (not 1000/0, but a real one = k_total_records). I have checked my previous sql-version, but it also is not up to expectations, because it is not based on real ranking of pages in list-view (it positioned pages by id, which of course doesn't always look the same as in list-view).

So, I am now back at point blank, with the SQL which assigns each page an incremented position according to the current position of pages in backend.

It is really fast for a 100k list (half a second). Now I am struggling with the next step - I must find a way to squeeze into a single query - first, last, prev, next markers and retrieve only these 5 (+current page id) positions.

My Documentation, Addons, Functions.
Join COUCH telegram channel
13 posts Page 1 of 2