Action: imageslider

Compatible with: R6.1
Current version: 0.9
Credits: WikiAdmin

Repo: action/imageslider.php


CSS image slider


{{imageslider}}


action/imageslider.php

<?php

if (!defined('IN_WACKO'))
{
    exit;
}

/*
    images as slider

    The sole condition is that all the images must be exactly the same size.

    version: 0.9

    https://wackowiki.org/doc/Dev/PatchesHacks/ImageSlider
 */

$info = <<<EOD
Description:
    Showing images as slider for uploaded files.

Usage:
    {{imageslider}}

Options:
    [page="PageName" or global=1]
    [order="time|name_desc|size|size_desc|ext"]
    [owner="UserName"]
    [media=1]
    [max=number]
EOD;

// set defaults
$global        ??= 0;
$help        ??= 0;
$max        ??= null;
$media        ??= 1;
$order        ??= '';
$owner        ??= '';
$page        ??= '';
$track        ??= 0;

if ($help)
{
    $tpl->help    = $this->help($info, 'imageslider');
    return;
}

if ($max)
{
    $limit = $max;
}
else
{
    $limit    = 50;
}

$order_by        = match($order) {
    'ext'            => 'file_ext ASC',
    'name_desc'        => 'file_name DESC',
    'size'            => 'file_size ASC',
    'size_desc'        => 'file_size DESC',
    'time'            => 'created ASC',
    'time_desc'        => 'created DESC',
    default            => 'file_name ASC',
};

$width_settings            = '100%'; // 100%, 300px, etc.
$files                    = [];
$page_id                = null;

// default options for slider
$time_on_slide            = 6;
$time_between_slides    = 1;
$animation_timing        = 'ease';
$slidy_direction        = 'left';
$css_animation_name        = 'slidy';

// options: data-caption, alt, none
$caption_source            = 'data-caption';
$caption_background        = 'rgba(0,0,0,0.3)';
$caption_color            = '#fff';
$caption_font            = 'Avenir, Avenir Next, Droid Sans, DroidSansRegular, Corbel, Tahoma, Geneva, sans-serif';

// options: top, bottom
$caption_position        = 'bottom';

// options: slide, perm, fade
$caption_appear            = 'slide';
$caption_size            = '1.6rem';

// same units
$caption_padding        = '.6rem';

if (!$global)
{
    if ($page == '')
    {
        $tag        = $this->tag;
        $page_id    = $this->page['page_id'];
    }
    else
    {
        $tag        = $this->unwrap_link($page);

        if ($_page_id = $this->get_page_id($tag))
        {
            $page_id    = $_page_id;
        }
    }

    $can_view    = $this->has_access('read', $page_id) || $this->is_admin() || $this->is_owner($page_id);
}
else
{
    $can_view    = true;
    $tag        = $this->tag;
}

if ($can_view)
{
    if ($global || ($tag == $this->tag))
    {
        $filepage = $this->page;
    }
    else
    {
        $filepage = $this->load_page($tag, 0, null, LOAD_CACHE, LOAD_META);
    }

    if (!$global && !isset($filepage['page_id']))
    {
        return;
    }

    $selector =
        "FROM " . $this->prefix . "file f " .
            "INNER JOIN " . $this->prefix . "user u ON (f.user_id = u.user_id) " .
        "WHERE f.page_id = " . ($global ? 0 : (int) $filepage['page_id']) . " " .
            "AND f.picture_w <> 0 " .
            ($owner
                ? "AND u.user_name = " . $this->db->q($owner) . " "
                : '') .
            "AND f.deleted <> 1 ";

    $count = $this->db->load_single(
        "SELECT COUNT(f.file_id) AS n " .
        $selector, true);

    $pagination = $this->pagination($count['n'], $limit, 'f');

    // load files list
    $files = $this->db->load_all(
        "SELECT f.file_id, f.page_id, f.user_id, f.file_size, f.picture_w, f.picture_h, f.file_ext, f.file_lang, f.file_name, f.file_description, f.created, u.user_name AS user " .
        $selector .
        "ORDER BY f." . $order_by . " " .
        "LIMIT {$pagination['offset']}, {$limit}", true);

    // display
    if (!$global)
    {
        $path2 = 'file:/' . $tag . '/';
    }
    else
    {
        $path2 = 'file:/';
    }

    if ($factor = count($files))
    {
        // calculate data for image slider CSS

        // count the number of images in the slide, including the new cloned element
        $img_count            = $factor + 1;
        // calculate the total length of the animation by multiplying the number of _actual_ images by the amount of time for both static display of each image and motion between them
        $total_time            = ($time_on_slide + $time_between_slides) * ($img_count - 1);
        // determine the percentage of time an individual image is held static during the animation
        $slide_ratio        = ($time_on_slide / $total_time) * 100;
        // determine the percentage of time for an individual movement
        $move_ratio            = ($time_between_slides / $total_time) * 100;
        // work out how wide each image should be in the slidy, as a percentage.
        $base_percentage    = 100 / $img_count;
        // set the initial position of the slidy element
        $position            = 0;

        $img_width    = $img_count * 100;
        $slidy        = '';

        if ($slidy_direction == 'right')
        {
            $slidy .= "0% \t{ left: -" . (($img_count - 1) * 100) . "%; }\n";

            for ($i = $img_count - 1; $i > 0; $i--)
            {
                $position += $slide_ratio;
                // make the keyframe the position of the image
                $slidy .= "\t\t" . $position . "% \t{ left: -" . ($i * 100) . "%; }\n";
                $position += $move_ratio;
                // make the postion for the _next_ slide
                $slidy .= "\t\t" . $position . "% \t{ left: -" . (($i - 1) * 100) . "%; }\n";
            }
        }
        else
        {
            $slidy .= "0% \t{ left: 0%; }\n";

            // the slider is moving to the left
            for ($i = 0; $i < ($img_count - 1); $i++)
            {
                $position += $slide_ratio;
                // make the keyframe the position of the image
                $slidy .= "\t\t" . $position . "% \t{ left: -" . ($i * 100) . "%; }\n";
                $position += $move_ratio;
                // make the postion for the _next_ slide
                $slidy .= "\t\t" . $position . "% \t{ left: -" . (($i + 1) * 100) . "%; }\n";
            }
        }

        $tpl->css = <<<EOD
    <style>

    div#captioned-gallery {
        width: 100%;
        overflow: hidden;
    }
    figure {
        margin: 0;
    }
    figure.slider {
        position: relative;
        width: {$img_width}%;
        font-size: 0;
        animation: {$total_time}s {$animation_timing} slidy infinite;
    }
    figure.slider:hover {
        /* animation: animation 1s  16 ease; */
        animation-play-state: paused;
    }
    figure.slider figure {
        width: {$base_percentage}%;
        height: auto;
        display: inline-block;
        position: inherit;
    }
    figure.slider img {
        width: {$width_settings};
        height: auto;
    }
    figure.slider figure figcaption {
        position: absolute;
        bottom: 0;
        background: rgba(0,0,0,0.3);
        color: #fff;
        width: 100%;
        font-size: 1rem;
        padding: .6rem;
    }
    div#slider figure {
        position: relative;
        width: {$img_width}%;
        margin: 0;
        padding: 0;
        font-size: 0;
        left: 0;
        text-align: left;
        animation: {$total_time}s {$animation_timing} slidy infinite;
    }

    @media screen and (max-width: 500px) {
        figure.slider figure figcaption {
            font-size: 1.2rem;
        }
    }

    /* figure.slider figure figcaption {
        position: absolute;
        bottom: -3.5rem;
        background: rgba(0,0,0,0.3);
        color: #fff;
        width: 100%;
        font-size: 2rem;
        padding: .6rem;
        transition: .5s bottom;
    }
    figure.slider figure:hover figcaption {
        bottom: 0;
    }

    figure.slider figure:hover + figure figcaption {
        bottom: 0;
    } */

    @keyframes slidy {
        {$slidy}
    }

    </style>
EOD;

        // adding at the end a clone of the first array for transition loop
        $files[]    = $files[0];
        $n            = 0;

        $tpl->enter('n_');

        foreach($files as $file)
        {
            if ($file['picture_h']) // missing: svg!
            {
                $n++;

                $this->file_cache[$file['page_id']][$file['file_name']] = $file;

                $desc        = $this->format($file['file_description'], 'typografica', ['lang' => $file['file_lang']]);

                if ($desc == '')
                {
                    $desc = NBSP;    // No-Break Space
                }

                $file_name        = $file['file_name'];
                $text            = $media ? '' : $file_name;

                $tpl->image        = $this->link($path2 . $file_name, '', $text, '', $track);
                $tpl->n            = $n;
                $tpl->count        = $count['n'];
                $tpl->desc        = $desc;
            }
        }

        $tpl->leave();    // n
    }
    else
    {
        $tpl->nofile =  $this->_t('FileNotFound');
    }

    unset($files);
}
else
{
    $tpl->noaccess = true;
}

action/template/imageslider.tpl

[ === main === ]
	[ ' help ' ]
	[ ' css ' ][ ' nofile ' ]

	<div id="captioned-gallery">
		<figure class="slider">
		[= n _ =
			<figure>
				[ ' image ' ]
				<figcaption>[ ' n ' ]/[ ' count ' ] [ ' desc ' ]</figcaption>
			</figure>
		=]
		</figure>
	</div>

	[= noaccess _ =
		[ ' _t: ActionDenied ' ]
	=]	

1. Documentation

The sole condition is that all the images must be exactly the same size.

2. How to


%%(wacko wrapper=page wrapper_width=600)
{{imageslider}}
%%

2.1. local usage of repository

symlink the gallery action from community action folder in wacko/action and wacko/action/template folder in repo
ln -s ../../community/action/imageslider.php imageslider.php
ln -s ../../../community/action/template/imageslider.tpl imageslider.tpl

3. Changelog

0.1 Initial version
0.7 Updated to work with R.6.1 (PHP 8.0, Null coalescing assignment operator)
0.8 added order="name_desc" and changed time field names
0.9 added template


4. To Do

  • make parameters like direction, size, time and caption accessible for action
  • modify the action for your purpose

Referring pages:

  1. Dev/PatchesHacks

Show Files (2 files)

Comments

  1. Arguments for image location

    {{imageslider
            [page="PageName" or global=1]
            [order="time|FILENAME|size|size_desc|ext"]
            [owner="UserName"]
            [picture=1]
            [max=number]
    }}	

    When you use the action without additional parameters, it takes the files attached to the page. To select files attached to another page, you have to use page="Cluster/OtherPage". The SQL query executes the specified arguments against the metadata in the file table. This allows you to add more arguments to filter the results, such as categories or even the filenames, by customizing the action.

    The easiest way is to attach only the images you wanna use to the page or a subpage.
    • WikiAdmin
    • 10.06.2020 16:42 edited
  2. Your unoffical beta tester

    have no bloody clue what your talking about here
    symlink imageslider.php from community action folder in wacko/action folder in repo
    ln -s ../../community/action/imageslider.php imageslider.php

    I am running on windows 7 with xampp setup
    • bear
    • 12.06.2020 10:44 edited
  3. Re: Symlinks or Symbolic Links

    ln -s ../../community/action/imageslider.php imageslider.php
    This info is there only for convenience, if you want to use the action in your development environment as is within the repository.
    Under Windows you can use mklink Link Target to create symbolic links using command prompt as administrator.

    Just copy the imageslider action to your wacko/action/ folder.

    The community folder is for code we maintain along with the code base, but is not (yet) part of the distribution.
    Do you already know our official beta tester?
    • WikiAdmin
    • 19.06.2020 17:51 edited
  4. Thank you

    I had already copied the imageslider.php to the wacko/action folder and was not able to get image slider to work.
    And I did upload 5 images of the same size to the same page that image slider would be running from

    %%(wacko wrapper=page wrapper_width=600)
    {{imageslider}}
    %%


    And I get nada on image slider
    • bear
    • 12.06.2020 09:36 edited
  5. OK got it working now just one issue

    I upload the image file while on the page wotypedia, So the image file gets associated with that page.
    When I upload the image gets associated Attached to: global instead of Attached to: WOTYpeida my first image file did attach to WOTYpedia but I cannot get other ones to.
    • bear
  6. Answered my own question

    When uploading a file check the radio box only for users allowed to view current page. This will associate the upload with that page.
    Just putting this here for the next person that has the same question!
    • bear
    • 16.06.2020 13:35 edited