Building a Weather Chart Viewer

Hello,

A employee of mine has created custom weather models based on the data from NOAA.

I need a way of displaying the images automatically once they are uploaded to my server. The files will be named the same as I think that'll help the process.

Can you suggest some code for this? I'm completely out of ideas.

  • Adam Czajczyk

    Hello Mark,

    I hope you're well today and thank you for that interesting question!

    I think this could be doable with some additional code, most likely in form of a custom plugin. However, I'd like to get to know a bit more about it. Will those files be uploaded manually or some external tool will upload them via FTP? Is there any established naming convention for files?

    If these images would be uploaded automatically, is there a chance that that external software could also call specified URL upon upload?

    Any additional information would be helpful here :slight_smile:

    Best regards,
    Adam

  • Mark Clifford

    Hi Adam,

    It is intended that the files are uploaded automatically through use of WinScp. There will be a well defined naming convention of the .png files although it has not yet been decided. It will not be easy to use a similar method to call on uploaded files given this will be done on an entirely different machine. I suspect
    the files will have to be called from the server directly using some scripting language.

  • Adam Czajczyk

    Hello Mark,

    Thank you for this additional explanation!

    I think this can be done. I think the good idea to make it work would be as follows:

    - create a separate directory inside /wp-content/uploads/ folder that would be used only for those images
    - scan that directory upon page load and pick up the newest image from that directory and e.g. return an <img> tag leading to that image.

    Here's an example code that could be used for this:

    <?php 
    
    function wpmu_return_newest_weather_image_shortcode() {
    	$path = "wp-content/uploads/weather"; 
    
    	$latest_ctime = 0;
    	$latest_filename = '';    
    
    	$d = dir($path);
    	while (false !== ($entry = $d->read())) {
    		$filepath = "{$path}/{$entry}";
    		// could do also other checks than just checking whether the entry is a file
    		if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
    			$latest_ctime = filectime($filepath);
    			$latest_filename = $entry;
    		}
    	}
    	$html = '<img src="' . site_url() . '/' . $path . '/' . $latest_filename . '" class="weather_model">';
    	return $html;
    }
    
    add_shortcode('weather-image','wpmu_return_newest_weather_image_shortcode');
    ?>

    To apply this to your site, please create the "/wp-content/uploads/weather" folder and make sure that the your weather-model images are uploaded to that folder.

    Then create an a file with .php extension (e.g. "weather-images.php"), paste the code from above to it and upload it to your server to "/wp-content/mu-plugins" folder. If there's no "mu-plugins" folder just create it.

    Last step would be to place the

    [weather-image]

    shortcode anywhere on your selected post(s)/page(s) and start uploading images. It should pickup only the recent image uploaded and place it in place of shortcode. You may also add some CSS rules to ".weather_model" class to style an image to suit your site's design.

    I hope that helps!

    Best regards,
    Adam

  • Mark Clifford

    Thank you Adam!

    While your solution is a good one, (I'll probably use it elsewhere!) it's not what we're looking for at the moment. Perhaps if I show you an example...

    http://www.netweather.tv/index.cgi?action=nwdc;sess=

    You will see that once you select a chart that each one goes in time steps. Our will take us from 0 to 240 hours. So we need to automate the image and have options to go through the hours.

    I hope I'm making sense...

  • Adam Czajczyk

    Hello Mark!

    Thanks for this explanation. This indeed changes things a bit, however the base wouldn't be much different I think.

    I've visited the site you linked to and selected "Sea pressure" chart and then clicked on "Animate" button. The image then cycled through a number of hours automatically. Is that what you're referring to?

    I'd assuming there's a number of different charts and you'd like to cycle through 240 hours (that would be images) the idea would be:

    - inside /wp-content/uploads/weather/ folder create subfolders, each for different type of of chart; for an example let's use just "temperature" (so the folder would be /wp-content/uploads/weather/temperature/)

    - change the code to take folder (chart type) as a parameter
    - find out 240 recent images instead of one
    - instead of putting those to screen add them to JS array
    - output the first image from the list to screen
    - add some JS code that will replace those images on screen, taking them from the list.

    An example code would be like this:

    <?php 
    
    function wpmu_return_newest_weather_image_shortcode($atts) {
    
    	$atts = shortcode_atts( array(
    		'dir' => 'temperature', // default folder/chart type
    		'num' => 240, //default number of images to fetch
    		'speed' => 500 //animation speed in miliseconds
    	), $atts, 'weather-image' );
    
    	$path = "wp-content/uploads/weather/" . "{$atts['dir']}"; 
    
    	$latest_ctime = 0;
    	$latest_filename = array();
    	$count = 0;
    	$max = "{$atts['num']}";
    
    	//let's now read a list of {num} of images
    
    	$d = dir($path);
    	while ((false !== ($entry = $d->read())) AND ($count<$max)) {
    		$filepath = "{$path}/{$entry}";
    		if (is_file($filepath)) {
    			$latest_ctime = filectime($filepath);
    			$latest_filename[] = $entry;
    		}
    		$count++;
    	}
    	// let's convert filenames to full image URLs
    	foreach ($latest_filename as $key=>$value) {
    		$latest_filename[$key] = site_url() . '/' . $path . '/' . $latest_filename[$key];
    	}
    	$imageList = implode(',',$latest_filename);
    	$imageSpeed = "{$atts['speed']}";
    	$html = '<img src="' . $latest_filename[0] . '" data-imagelist="' . $imageList . '" data-speed="' . $imageSpeed . '" class="weather_map">';
    	return $html;
    }
    
    /* shortcode use
    [weather-image dir="temperature" num="240"]
    where
    dir - directory  holding images for selected model
    num - number of recent images to fetch
    speed - how often images should change (in miliseconds)
    
    attributes are optional
    */
    add_shortcode('weather-image','wpmu_return_newest_weather_image_shortcode');
    
    /* let's add some jQuery that will read file list and speed
    from <img> tag and then rotate images */
    
    function wpmu_rotate_weather_maps() {
        ?>
        <script type="text/javascript">
        jQuery(function($) {
    		var wSpeed = $('.weather_map').data('speed');
    		var wImageList = $('.weather_map').data('imagelist').split(',');
    		var wImageNum = wImageList.length;
    		var i = 1;
            setInterval(function() {
                $('.weather_map').attr("src", wImageList[i]);
    			++i;
    			if (i == wImageNum) i=0;
            }, wSpeed);
        });
        </script>
        <?php
    }
    add_action('wp_footer', 'wpmu_rotate_weather_maps');
    
    ?>

    In order to use it, again upload it to your site as an "mu-plugin" (as explained previously) and use shortcode like

    [weather-image dir="temperature" num="300" speed="1000"]

    where all the attributes are optional and mean:

    dir - it's a directory containing selected weather models' images
    num - it's a max. number of images to be fetched (if there's less images there'll be no error, just less images will be used)
    speed - in miliseconds; e.g. with value of 1000 image will be replaced every 1 second.

    This is a base I think that you could further enhance and it should let you built your weather model system.

    Let me know please if it helped!

    Best regards,
    Adam

  • Adam Czajczyk

    Helo Mark,

    I'm sorry, I was off yesterday.

    I'm glad my code helped you a bit. It can be extended with additional features, such as controlling "external" elements on a page and/or controlling that "image rotator" with some external control elements. However, it would take further custom coding job which would be a bit outside the scope of this support forum.

    If you feel like coding it by yourself, I'll be more than happy to share some tips and/or review you code. You may however want to ask a question on our "Jobs & Pros" job board (please note: no WPMU DEV staff involved!) here:

    https://premium.wpmudev.org/wordpress-development/

    I'm sure some pro developers will be eager to help you with this.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    That's a real shame that you can't assist with coding anymore. We cannot afford a developer and my knowledge is poor on this sort of thing. We'll find a way.

    I understand your point. Please note however that this is a support forum and we're not offering any custom development services. I created a code for you that's not only custom at all but also not even related to any of our plugins. That's already way beyond the scope of this forum.

    That said, since I've already gone that far, let's put it a step further :slight_smile: Below is an updated code that adds an "Animate" trigger so initially the first image is loaded and shown and the images start changing after "Animate" is clicked. Please replace your current code with this one:

    <?php 
    
    function wpmu_return_newest_weather_image_shortcode($atts) {
    
    	$atts = shortcode_atts( array(
    		'dir' => 'temperature', // default folder/chart type
    		'num' => 240, //default number of images to fetch
    		'speed' => 500 //animation speed in miliseconds
    	), $atts, 'weather-image' );
    
    	$path = "wp-content/uploads/weather/" . "{$atts['dir']}"; 
    
    	$latest_ctime = 0;
    	$latest_filename = array();
    	$count = 0;
    	$max = "{$atts['num']}";
    
    	//let's now read a list of {num} of images
    
    	$d = dir($path);
    	while ((false !== ($entry = $d->read())) AND ($count<$max)) {
    		$filepath = "{$path}/{$entry}";
    		if (is_file($filepath)) {
    			$latest_ctime = filectime($filepath);
    			$latest_filename[] = $entry;
    		}
    		$count++;
    	}
    	// let's convert filenames to full image URLs
    	foreach ($latest_filename as $key=>$value) {
    		$latest_filename[$key] = site_url() . '/' . $path . '/' . $latest_filename[$key];
    	}
    	$imageList = implode(',',$latest_filename);
    	$imageSpeed = "{$atts['speed']}";
    	$html = '<p class="weather_animate">Animate</p>';
    	$html .= '<img src="' . $latest_filename[0] . '" data-imagelist="' . $imageList . '" data-speed="' . $imageSpeed . '" class="weather_map">';
    	return $html;
    }
    
    /* shortcode use
    [weather-image dir="temperature" num="240"]
    where
    dir - directory  holding images for selected model
    num - number of recent images to fetch
    speed - how often images should change (in miliseconds)
    
    attributes are optional
    */
    add_shortcode('weather-image','wpmu_return_newest_weather_image_shortcode');
    
    /* let's add some jQuery that will read file list and speed
    from <img> tag and then rotate images */
    
    function wpmu_rotate_weather_maps() {
        ?>
        <script type="text/javascript">
        jQuery(function($) {
    		$('.weather_animate').click(function() {
    				var wSpeed = $('.weather_map').data('speed');
    				var wImageList = $('.weather_map').data('imagelist').split(',');
    				var wImageNum = wImageList.length;
    				var i = 1;
    				setInterval(function() {
    					$('.weather_map').attr("src", wImageList[i]);
    					++i;
    					if (i == wImageNum) i=0;
    				}, wSpeed);
    		});
    	});
        </script>
        <?php
    }
    add_action('wp_footer', 'wpmu_rotate_weather_maps');
    
    ?>

    Additionally, here's some CSS code that turns an "Animate" word into the nice button. You may want to add it to your theme's style.css file or better yet, via Simple Custom CSS plugin:

    .weather_animate {
      background: #3498db;
      background-image: -webkit-linear-gradient(top, #3498db, #2980b9);
      background-image: -moz-linear-gradient(top, #3498db, #2980b9);
      background-image: -ms-linear-gradient(top, #3498db, #2980b9);
      background-image: -o-linear-gradient(top, #3498db, #2980b9);
      background-image: linear-gradient(to bottom, #3498db, #2980b9);
      -webkit-border-radius: 8;
      -moz-border-radius: 8;
      border-radius: 8px;
      font-family: Arial;
      color: #ffffff;
      font-size: 20px;
      padding: 10px 20px 10px 20px;
      text-decoration: none;
    }
    
    .weather_animate:hover {
      background: #3cb0fd;
      background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
      background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
      background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
      background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
      background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
      text-decoration: none;
    }

    I hope this puts you a bit closer to achieving your goal, although that's pretty much as far as I can go with custom coding. In case you'd need any further advise or tips, please ask and I'll be glad to help.

    Best regards,
    Adam

  • Mark Clifford

    Hello again,

    We are under beta with our weather models now having decided upon using a very make-shift solution. However I wanted some advice about styling the buttons.

    You can see it here: http://beta-models.snowwatch.org.uk/models

    Code we're using:

    <!DOCTYPE html>
    <html>
    <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <meta name="robots" content="noindex, nofollow">
      <meta name="googlebot" content="noindex, nofollow">
      <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
        <link rel="stylesheet" type="text/css" href="/css/result-light.css">
         <style type="text/css">
        .slideshow1 {
        position: relative;
        /* necessary to absolutely position the images inside */
        width: 800px;
        /* same as the images inside */
        height: 600px;
    }
    .slideshow1 img {
        position: absolute;
        display: none;
    }
    .slideshow1 img:first-child {
        display: block;
        /* overrides the previous style */
    }
      </style>
    
      <title></title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type='text/javascript'>//<![CDATA[
    jQuery(document).ready(function($) {
        // use $
    
    $(window).load(function(){
    var interval = undefined;
    $(document).ready(function () {
        interval = setInterval(getNext, 2000); // milliseconds
        $('#next').on('click', getNext);
        $('#previous').on('click', getPrev);
        $('#first').on('click', getFirst);
        $('#last').on('click', getLast);
    });
    
    function getNext() {
        var $curr = $('.slideshow1 img:visible'),
            $next = ($curr.next().length) ? $curr.next() : $('.slideshow1 img').first();
    
        transition($curr, $next);
    }
    
    function getPrev() {
        var $curr = $('.slideshow1 img:visible'),
            $next = ($curr.prev().length) ? $curr.prev() : $('.slideshow1 img').last();
        transition($curr, $next);
    }
    
    function getFirst() {
        var $curr = $('.slideshow1 img:visible'),
            $next = $('.slideshow1 img').first();
        transition($curr, $next);
    }
    
    function getLast() {
        var $curr = $('.slideshow1 img:visible'),
            $next = $('.slideshow1 img').last();
        transition($curr, $next);
    }
    
    function transition($curr, $next) {
        clearInterval(interval);
    
        $next.css('z-index', 2).fadeIn('slow', function () {
            $curr.hide().css('z-index', 0);
            $next.css('z-index', 1);
        });
    
    }
    });//]]>
    });
    </script>
    
    </head>
    
    <body>
      <div class="slideshow1">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk1.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk2.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk3.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk4.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk5.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk6.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk7.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk8.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk9.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk10.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk11.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk12.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk13.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk14.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk15.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk16.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk17.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk18.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk19.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk20.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk21.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk22.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk23.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk24.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk25.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk26.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk27.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk28.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk29.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk30.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk31.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk32.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk33.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk34.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk35.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk36.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk37.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk38.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk39.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk40.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk41.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk42.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk43.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk44.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk45.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk46.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk47.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk48.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk49.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk50.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk51.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk52.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk53.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk54.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk55.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk56.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk57.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk58.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk59.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk60.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk61.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk62.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk63.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk64.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk65.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk66.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk67.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk68.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk69.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk70.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk71.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk72.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk73.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk74.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk75.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk76.png"  width="800" height="600"" alt="fourth image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk77.png" width="800" height="600" alt="first image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk78.png"  width="800" height="600" alt="second image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk79.png"  width="800" height="600"" alt="third image">
        <img src="http://snowwatch.org.uk/wxdata/F/GFS/2muk/gfs2muk80.png"  width="800" height="600"" alt="fourth image">
    </div>
    <button id="first">First</button>
    <button id="previous">Previous</button>
    <button id="next">Next</button>
    <button id="last">Last</button>
    </body>
    
    </html>
  • Adam Czajczyk

    Hello Mark,

    I hope you're well today!

    It's great to know that you've gone that far with it, I'm glad I could help :slight_smile:

    I've visited an URL you shared with me but all I'm getting is a "Page not found" 404 error. Could you please make sure that you posted a proper link here? I'd also like to know a bit more about that button styling - what exactly would you like to achieve?

    Please advise!
    Best regards,
    Adam

  • Mark Clifford

    Hi Adam,

    Thanks for getting back to me so quickly!

    The link is correct but I had it as privately published. You can visit it now but please use password 'wpdev' http://beta-models.snowwatch.org.uk/models

    I would like buttons like this: http://take.ms/xEmuU in the format of: First, Previous, Next, Last
    It'll make more sense when you have look at the current viewer we have. I have a feeling it would be easier adding that into the code you suggested which is fine.

  • Adam Czajczyk

    Hello Mark,

    Thanks for you response.

    I've visited your site and if I understood you correctly this would require just a bit of custom CSS code. I think this should do the trick (see screenshot):

    .wpb_wrapper button {
    	font: normal 15px / 25px &quot;Open Sans&quot;, Helvetica, Arial, Verdana, sans-serif;
    	color:#666;
    	width: 25%;
    	padding-top:10px;
    	padding-bottom:10px;
    	margin:10px 0px;
    	border:1px solid #999;
    	background:#fff;
    	border-right:0;
    	float:left;
    	box-sizing: border-box;
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    -webkit-transition: all 300ms ease-in-out;
    -moz-transition: all 300ms ease-in-out;
    -ms-transition: all 300ms ease-in-out;
    -o-transition: all 300ms ease-in-out;
    transition: all 300ms ease-in-out;}
    .wpb_wrapper button:last-of-type {border-right:1px solid #999;}
    .wpb_wrapper button:hover {background:#DCDCDC;}

    Let me know please if it helped!
    Best regards,
    Adam

  • Dimitris

    Hey there Daniel Finch,

    hope you're having a beautiful day and don't mind chiming in! :slight_smile:

    In Adam's (wonderful) piece of code here https://premium.wpmudev.org/forums/topic/building-a-weather-chart-viewer#post-1010334 there aren't any navigation button rather than a single "Animate" one.

    If you use something like Marc's code from here https://premium.wpmudev.org/forums/topic/building-a-weather-chart-viewer#post-1041148 though, you should make a little change in there and wrap the buttons in a div like

    <div class="wpb_wrapper">
      <button id="first">First</button>
      <button id="previous">Previous</button>
      <button id="next">Next</button>
      <button id="last">Last</button>
    </div>

    and also use the CSS provided here https://premium.wpmudev.org/forums/topic/building-a-weather-chart-viewer#post-1041283

    Hope that was some help,
    Dimitris :slight_smile:

  • Dimitris

    Hey there Mark Clifford,

    I trust you're well today and lucky you, we're here on weekends too! :wink:

    Here's an updated code, based on Adam's shortcode, I just inserted the button groups and changed a bit the script to work as should be (please notice that the "speed" argument for the auto-play functionality that Adam had shared is still in place in case you want to use it later on).

    <?php
    
    function wpmu_return_newest_weather_image_shortcode($atts) {
    
    	$atts = shortcode_atts( array(
    		'dir' => 'temperature', // default folder/chart type
    		'num' => 240, //default number of images to fetch
    		'speed' => 500 //animation speed in miliseconds
    	), $atts, 'weather-image' );
    
    	$path = "wp-content/uploads/weather/" . "{$atts['dir']}";
    
    	$latest_ctime = 0;
    	$latest_filename = array();
    	$count = 0;
    	$max = "{$atts['num']}";
    
    	//let's now read a list of {num} of images
    
    	$d = dir($path);
    	while ((false !== ($entry = $d->read())) AND ($count<$max)) {
    		$filepath = "{$path}/{$entry}";
    		if (is_file($filepath)) {
    			$latest_ctime = filectime($filepath);
    			$latest_filename[] = $entry;
    		}
    		$count++;
    	}
    	// let's convert filenames to full image URLs
    	foreach ($latest_filename as $key=>$value) {
    		$latest_filename[$key] = site_url() . '/' . $path . '/' . $latest_filename[$key];
    	}
    	$imageList = implode(',',$latest_filename);
    	$imageSpeed = "{$atts['speed']}";
    	// $html = '<p class="weather_animate">Animate</p>';
      $html = '<div class="wpb_wrapper">
                <button class="first">First</button>
                <button class="previous">Previous</button>
                <button class="next">Next</button>
                <button class="last">Last</button>
              </div>';
    	$html .= '<img src="' . $latest_filename[0] . '" data-imagelist="' . $imageList . '" data-speed="' . $imageSpeed . '" class="weather_map">';
    	return $html;
    }
    
    /* shortcode use
    [weather-image dir="temperature" num="240"]
    where
    dir - directory  holding images for selected model
    num - number of recent images to fetch
    speed - how often images should change (in miliseconds)
    
    attributes are optional
    */
    add_shortcode('weather-image','wpmu_return_newest_weather_image_shortcode');
    
    /* let's add some jQuery that will read file list and speed
    from <img> tag and then rotate images */
    
    function wpmu_rotate_weather_maps() {
      ?>
      <script type="text/javascript">
      jQuery(function($) {
    		var wImageList = $('.weather_map').data('imagelist').split(',');
    		var wImageNum = wImageList.length;
    		var i=0;
    
    		$('.wpb_wrapper > .first').click(function() {
    			$('.weather_map').attr("src", wImageList[0]);
    			i=0;
    			console.log(i);
    		});
    
    		$('.wpb_wrapper > .last').click(function() {
    			$('.weather_map').attr("src", wImageList[wImageNum-1]);
    			i=wImageNum-1;
    			console.log(i);
    		});
    
    		$('.wpb_wrapper > .next').click(function() {
    			++i;
    			if ( i >= wImageNum ) {
    				i=wImageNum-1;
    			}
    			$('.weather_map').attr("src", wImageList[i]);
    			console.log(i);
    		});
    
    		$('.wpb_wrapper > .previous').click(function() {
    			--i;
    			if ( i <= 0 ) {
    				i=0;
    			}
    			$('.weather_map').attr("src", wImageList[i]);
    			console.log(i);
    		});
    
    	});
      </script>
      <?php
    }
    add_action('wp_footer', 'wpmu_rotate_weather_maps');
    
    ?>

    Take care,
    Dimitris :slight_smile:

  • Predrag Dubajic

    Hi Mark,

    If you use classes specific to your chart viewer then you can simply add it to your theme CSS file and it will not affect your other styling, using child theme is highly suggested so that your changes don't get overwritten by theme update.

    You could also create custom CSS file for the code and call it via wp_enqueue_style() function inside your child theme functions.php or mu-plugin, you can read more about wp_enqueue_style here:
    https://developer.wordpress.org/themes/basics/including-css-javascript/

    Best regards,
    Predrag

  • Mark Clifford

    Thanks Predrag Dubajic

    I have discovered that the code is causing an error on my site. The error is as follows:

    `Uncaught TypeError: Cannot read property ‘split’ of undefined
    jquery.themepunch.revolution.min.js?ver=5.2.6:8 http://snowwatch.org.uk/wp-content/uploads/2016/02/scare-slide.jpg Could not be loaded !'

    It breaks the style of the site which never happened before. While I wait for your response I'm going to try placing the code out of the wp-content folder to see if that resolves it. If i don't write back before your reply assume it's not worked.

    Thanks for all your help so far everyone! Love this community!

  • Dimitris

    Hey there Mark Clifford,

    this is happening because the widget's script is being loaded in the footer of every page with this line
    add_action('wp_footer', 'wpmu_rotate_weather_maps');

    Try to replace this line with the following one, which should load the script only in posts that have the [weather-image] shortcode in their content . :wink:

    function custom_shortcode_scripts() {
    	global $post;
    	if( has_shortcode( $post->post_content, 'weather-image') {
    		add_action('wp_footer', 'wpmu_rotate_weather_maps');
    	}
    }
    add_action( 'wp', 'custom_shortcode_scripts');

    Reference: https://codex.wordpress.org/Function_Reference/has_shortcode#Simple_Example_2

    Warm regards,
    Dimitris

  • Mark Clifford

    Thanks for your help. You guys are legends! I have two more things before this project is done which I hope you can help me with...

    1. Duplication
    So, when I say duplication I mean I need the same as AirTemp (seen here http://snowwatch.org.uk/charts) but for the rest of them. Can I just duplicate the 2muk file in mu-plugins and change the link? Because I have tried that and it caused an error.

    2. Responsive
    I need this chart viewer to be fully responsive. Currently it is not as you can see here: http://take.ms/26hx3 How complicated would this be?

    3. We're all done. Hurray for WPMUDEV!

  • Adam Czajczyk

    Hello Mark!

    I'm glad that with Dimitris help you were able to make it all work :slight_smile:

    1. Duplication
    So, when I say duplication I mean I need the same as AirTemp (seen here http://snowwatch.org.uk/charts) but for the rest of them. Can I just duplicate the 2muk file in mu-plugins and change the link? Because I have tried that and it caused an error.

    I haven't tested the code with changes that Dimitirs made, yet, but after a brief review I think it should work as assumed from the beginning meaning that as long as you are not using the shortcode multiple times on the same page, there'd be no need for any additional code or "duplication": simply but the same shortcode with different attributes and it should pickup proper files. That is however, as I mentioned, if you are using "a single shortcode per page/post".

    If you'd like to use multiple shortcode instances withing the same post/page (with different maps) the entire could would need to be modified quite a bit in order to avoide JS conflicts. I would however need to get a full code in its current state (e.g. via pastebin.com) to get a "base" to make changes.

    2. Responsive
    I need this chart viewer to be fully responsive. Currently it is not as you can see here: http://take.ms/26hx3 How complicated would this be?

    That's mostly a matter of a CSS customization. That's another thing that I suppose I could help you with but I'd need to work with your site and seens we do not have any access to it, all I can see is "maintenance mode" page and not the charts in question. If you could share a "maintenance mode" bypass link (if there's any) or a link to the staging site that's an exact copy but available or grant me a support access to the site or, finally, just make site open to public - I'd be happy to take a look.

    Best regards,
    Adam

  • Mark Clifford

    Hello Adam Czajczyk

    I have created you a bypass link for the site which will last for 2 days after which you will need to revisit the link to gain access to it but something tells me you won't need to do that as you guys work super fast. Link: http://snowwatch.org.uk/wpmudev4859

    I have already given you support access via the WPMUDEV Dashboard.

    1. Duplication

    So, the way I'm planning on using it is; for each tab on the chart page will be a different short code for a different chart. ie [weather-image dir="2muk" num="80"] for AirTemp and [weather-image dir="850uk" num="80"] for Temp. This will make sesne once you have seen the chart page.

    I'll leave you to have a look around the site and will await your response.

  • Adam Czajczyk

    Hello Mark,

    Thanks for your response and granting access.

    I checked the site and added a line of CSS to the "Theme Settings -> Advanced -> Custom CSS" box of your site:

    img.weather_map {width:100%;height:auto;}

    This makes the map responsive so the image is scaled to fit its container and since it is already responsive the map should as well work fine. A brief test seems to confirm that but it would be great if you could double-check if those images are now properly scaled on mobile devices.

    As for the "duplication". I think then some change in a code would be necessary however even having a support access to the site I'm not able to access the code of an MU plugin that way.

    Therefore I'd like to ask you to create a .zip file out of your current 2muk.php plugin and e.g. upload it to your site's Media Library. Then, since support access is granted, simply leave me a note about the file name on the "WPMU DEV -> Support" page (there's a text box for such notes). I'll then access the site, download the plugin, review and change code and upload replacement file here for you.

    Let me know here also when that zip for me is ready, please.

    Best regards,
    Adam

  • Mark Clifford

    While I am waiting for Adam Czajczyk to get back to me...

    Referring back to Predrag Dubajic about the CSS file for the chart viewer. I have created a stylesheet in mu-plugins folder and added some code into the funcions.php in child theme as follows:

    <?php
    
    function swgb_script_enqueue() {
    
    wp_enqueue_style( 'chart-viewer-style', get_template_directory_uri() . '/wp-content/mu-plugins/chart-viewer-style.css',false,'1.1','all');
    
    }
    
    add_action( 'wp_enqueue_script', 'swgb_script_enqueue'); 
    
    ?>

    I'm now completely stuck as to what I need to do... can you help at all?

    Adam Czajczyk If you're able to get back to me tonight (I'm in the UK, current time 17:20) that would be awesome.

  • Adam Czajczyk

    Hello Mark!

    Thank you for sharing the script. I downloaded it and started working on some changes. I'm afraid I won't be able to get back to you with this right away but hopefully I should be ready within around a day. I hope that'd be fine for you (there's just an hour time difference between UK and here).

    As for the Predrag's styles code. That's just a way to easily include custom styles that you will/would like to create for your chart viewer. With that code you simply need to create a

    "chart-viewer-style.css"

    file inside the "/wp-content/mu-plugins/" folder and put all your CSS rules related to that "chart-viewer" there. For example, you can move my "responsiveness" CSS rule there from your theme settings.

    Best regards,
    Adam

  • Mark Clifford

    That's fine :slight_smile:

    About predrags styles code--it's not working.

    Are you saying I don't need

    <?php
    
    function swgb_script_enqueue() {
    
    wp_enqueue_style( 'chart-viewer-style', get_template_directory_uri() . '/wp-content/mu-plugins/chart-viewer-style.css',false,'1.1','all');
    
    }
    
    add_action( 'wp_enqueue_script', 'swgb_script_enqueue'); 
    
    ?>

    And I just need to put chart-viewer-style.css in the mu-plugins folder? If so that doesn't work.

  • Adam Czajczyk

    Hello Mark!

    No, you need both actually. That "Predrag's code" is meant to load the "chart-viewer-style.css" file where the CSS would be.

    I did however notice an error in the code just now. See this line:

    wp_enqueue_style( 'chart-viewer-style', get_template_directory_uri() . '/wp-content/mu-plugins/chart-viewer-style.css',false,'1.1','all');

    especially this part:

    get_template_directory_uri() . '/wp-content/mu-plugins/chart-viewer-style.css'

    what it does is it builds a path to the file like this:

    http://yoursite.com/wp-content/themes/yourtheme/wp-content/mu-plugins/chart-viewer-style.css

    which obviously is not existing.

    On the other hand - and I should mention that before - the "mu-plugins" folder should not include any .css files. It's not "not allowed" but it's not considered a "good practice" :slight_smile:

    I think, let's do it this way: if you could wait until I'll get the tweaked script for you, I'll try to include solution for this right in the plugin. Would that suit you?

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    It seems that I could use your help with testing this. I attached a .zip file to this post. That's not a "final" solution but it's the "core" of it. I'd like you to replace your current 2muk.php file with the 2muk20.php file from that attached.zip and then:

    - create multiple charts (e.g. a few different charts on a single page and/or charts in tabs)
    - test it "back and forth" as much as you can to make sure that it's working as it should.

    If that file passes the test I'll wrap it up nicely for you, including the way to load custom script and I think we should be good :slight_smile:

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    You need to replace the 2muk.php file with the one I provided you with, not install it along it. Please just remove the "2muk.php" file from your "/wp-content/mu-plugins" folder (though better keep a copy of it somewhere on your local drive) and instead upload my recent 2muk20.php file.

    There's no need to make any other changes but it's important that only the 2muk20.php file was there :slight_smile:

    Give it another try please and let me know how it works for you.

    Best regards,
    Adam

  • Mark Clifford

    Hello Adam Czajczyk

    Pretty sure that's what I did but it was late and I did it in a rush. I'll try again when I get home from work, which will be about 6pm UK time and report back afterwards.

    Just to be clear though, I'm deleting 2muk.php (but keeping a copy of it locally) and uploading 2muk20.php to mu-plugins and then duplicating it for another chart type i.e. snow depth? Then placing the snow depth short code in a separate tab...

    If this is wrong please respond promptly so I don't waste time doing completely the wrong thing.

    Thanks.

  • Adam Czajczyk

    Hello Mark!

    Just to be clear though, I'm deleting 2muk.php (but keeping a copy of it locally) and uploading 2muk20.php to mu-plugins

    Yes, that's exactly what you wanna do :slight_smile:

    and then duplicating it for another chart type i.e. snow depth? Then placing the snow depth short code in a separate tab...

    Absolutely not :slight_smile: You don't duplicate the file. Only the single "2muk20.php" file should be there, no copies of it whatsoever. All you got to do to add more charts is to add more shortcodes like the one you already have.

    If you want to show that exact same chart that's already on your site then just copy the shortcode. If you wish to show other chart (either on the same post/page or a different post/page or a tab) use the shortcode just specifying a different directory where your weather chart images are stored.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    Just to be clear though, I'm deleting 2muk.php (but keeping a copy of it locally) and uploading 2muk20.php to mu-plugins

    Yes, that's exactly what you wanna do :slight_smile:

    and then duplicating it for another chart type i.e. snow depth? Then placing the snow depth short code in a separate tab...

    Absolutely not :slight_smile: You don't duplicate the file. Only the single "2muk20.php" file should be there, no copies of it whatsoever. All you got to do to add more charts is to add more shortcodes like the one you already have.

    If you want to show that exact same chart that's already on your site then just copy the shortcode. If you wish to show other chart (either on the same post/page or a different post/page or a tab) use the shortcode just specifying a different directory where your weather chart images are stored.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    Hmm, right. That's not how I thought it worked but it's fine as it does the same job.

    That's the better way, believe me :slight_smile: The idea of a shortcode (any shortcode) is basically to let you "use and re-use" it anywhere you wish without any need to duplicate any plugin file. Anyway, if it's working, that's great.

    We usually do not provide such kind of custom development but since we already went that far (as an exception) let me wrap that up for you in a form of a regular plugin with "custom style" feature incorporated and I think you should be ready to go further :slight_smile:

    Please keep an eye on this thread and I'll get back to you with "polished" code.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    I apologize for keeping you waiting. I usually work the most on weekends and in turn I "take my weekends" on Monday and Tuesdays. I should have told you that before, I'm sorry :slight_smile:

    I checked and reviewed the code on my end again and it's still working well. I'm sure that only some minor tweaks will be necessary to make it work on your setup as well but I think at this point it'd be better if I could directly work there. Do you think that you could provide me (temporarily of course) with a full access to your site?

    I could then access both the back-end of the site and FTP and could test everything. I believe I could then be able to make it work quite soon :slight_smile:

    If that's okay with you please send in:

    Subject: "Attn: Adam Czajczyk"

    - Mark to my attention, the subject line should contain only: ATTN: Adam Czajczyk
    - Do not include anything else in the subject line, doing so may delay our response due to how email filtering works.
    - Link back to this thread
    - login URL and admin account login credentials (may be a temporary admin account) data
    - Include FTP log-in details (hostname, username & password)
    - Include any relevant URLs for your site

    Please use our contact form here http://premium.wpmudev.org/contact/

    Select "I have a different question" from the drop-down list. 

    I will not make any changes to your site other than those strictly related to our charts plugin here and necessary to make it work. I'll be also automatically notified of your e-mail.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    It seems I still haven't received your e-mail. I checked "not-assigned-yet" and "spam" inboxes but with no luck. Could you please make sure that you are sending that message exactly following my instructions here:

    https://premium.wpmudev.org/forums/topic/building-a-weather-chart-viewer#post-1157504

    Please also make sure that you are using an e-mail address that's used with your WPMU DEV account here. Alternatively, instead of a contact form you may send the message directly to the "contact@wpmudev.org", however other than this please follow all other steps to the point.

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Mark!

    I was able to access your site and also check the behavior of charts on your pages but unfortunately I'm not able to access the server via FTP. Every connection attempt ends for me with the "Access denied" message so either the FTP credentials are not valid or the access has been withdrawn.

    Could you please double-check these FTP credentials, make sure they work and send them again to me? I already sent you an e-mail message so please include valid credentials in your response to it. I'm posting it here as well just in case your e-mail service was still "temperamental" :slight_smile:

    Best regards,
    Adam