Jump to content

MarkupShortcodes


Nico Knoll
 Share

Recommended Posts

It would go to far to ask PW to somehow analyze all module code. For PW to be able to check something i guess it's always up to the module author to provide info about the min. required PHP version, if applicable. Perhaps require it in the getModuleInfo part. PW then could always do version_compare against the PHP version available on the system. And maybe show a Pro-Tip urging people to finally update to 5.3+ :)

  • Like 1
Link to comment
Share on other sites

Hey Nico, really useful module! Very powerful.

I've tried out locally (with PHP 5.3), like it very much, but when uploading to the online host it also crashes the Adminpage. :(

When looking to the code, there is only one closure within the preg_replace_callback what relies on PHP 5.3. Is there any chance to change that to a (surely less elegant) code but that also run with PHP 5.2 ?  (Bitte, bitte!)

Unfortunately I'm not comfortable with preg_replace & co.

Link to comment
Share on other sites

I think it's not the preg_replace_callback that is causing the 'problem', but the use of a anonymous function in there. Maybe it could be done using create_function instead but i'm not sure this is desirable.

  • Like 1
Link to comment
Share on other sites

I think it's not the preg_replace_callback that is causing the 'problem', but the use of a anonymous function in there. Maybe it could be done using create_function instead but i'm not sure this is desirable.

 Yes, its the so called closure within the preg_replace_callback. :)

 Maybe there also could be used a named function as callback, somehow? But I don't really understand what's going on at that point.

Edit / Add:

Links about PHP closures with versions prior to 5.3:

http://stackoverflow.com/questions/2209327/is-it-possible-to-simulate-closures-in-php-5-2-x-not-using-globals

http://www.phpclasses.org/package/5484-PHP-Create-closure-functions-for-any-PHP-5-version.html

Edited by horst
Link to comment
Share on other sites

I know horst, that's basically what i said. Anonymous functions are often referred to as closures (which is not entirely correct i suppose). Have a look at php docs for preg_replace_callback at the callback parameter and the example. Then at the similar code in Nico's module. You could probably use create_function instead of the closure but maube someone with better PHP knowledge can give better advice.

  • Like 1
Link to comment
Share on other sites

I know horst, that's basically what i said. Anonymous functions are often referred to as closures (which is not entirely correct i suppose). Have a look at php docs for preg_replace_callback at the callback parameter and the example. Then at the similar code in Nico's module. You could probably use create_function instead of the closure but maube someone with better PHP knowledge can give better advice.

Ah, ok. Thanks for the link. I've read the example on php docs and yes they use create_function instead of a 'closure' for the same purpose.

Probably we can do this like the Wordpress shortcodes original. Large parts of the source seem to be the same, but Wordpress only requires PHP 5.2

http://core.svn.wordpress.org/trunk/wp-includes/shortcodes.php

Thanks too! WP uses a named function within their preg_replace_callback.

So this shouldn't be too complicated to achieve. (Will try when there is more time) ^_^

Link to comment
Share on other sites

(Ryan, I wonder if code should be added to the Modules page that prevents this behavior. I would think that the check should also come from within PW, rather than relying on any particular module.)

I don't think we can do that because a parse error generated as a result of wrong PHP version will occur before ProcessWire can even perform a getModuleInfo() call on it. Module info would have to be stored in a separate file in order for PW to identify and prevent that sort of thing. Even that, or PW would have to file_get_contents() the PHP file and manually parse it looking for that info (which doesn't seem worth it). Though adding support for optional external module info files is something I would like to add at some point.

Link to comment
Share on other sites

Okay, I added this: 

<?php

public function ___install() {
	
	if(ProcessWire::versionMajor == 2 && ProcessWire::versionMinor < 2) {
		throw new WireException("This module requires ProcessWire 2.2 or newer."); 
	}
	
	if(version_compare(PHP_VERSION, '5.3.0', '<')) {
		throw new WireException("This module requires PHP 5.3 or newer."); 
	}
	
}

?>

Should work I guess.

  • Like 1
Link to comment
Share on other sites

Just wanted to add also that this check doesn't work you added for PHP 5.3 as a module will get parsed before installing!

I recommend to add notes to all your modules that require PHP 5.3 in big red letters in the thread and in readme's.

Its very annoying, and even people said so, bu you didn't do anything to fix it!

/rant over

  • Like 1
Link to comment
Share on other sites

Just wanted to add also that this check doesn't work you added for PHP 5.3 as a module will get parsed before installing!

That's correct. When PW 2.4 is here, it won't matter, because PW will require PHP 5.3+ as well. But this could be a recurring issue with PHP 5.4, 5.5, etc. I recommend that any modules available on the modules directory be required to have the same PHP version requirements as the version of PW they are written for. An autoload module that requires PHP 5.3 when they only have PHP 5.2 could take down someone's site.

  • Like 2
Link to comment
Share on other sites

When PW 2.4 is here, it won't matter, because PW will require PHP 5.3+ as well.

Thanks, Nico!

Ryan: Won't requiring PHP 5.3+ knock a whole lot of shared server accounts out of the water, in terms of PW?

Even my site, which is a new VPS from LiquidWeb.com, has PHP v. 5.2.17. I've never upgraded PHP, and have no idea of the impact on code running under 5.2+, but it seems like a hurdle in many cases.

Just curious. Maybe upgrading PHP is easier than I think.

But I have a number of clients who use shared hosting, and upgrading is not an option for them. They would have to migrate to another box, which can be a real pain.

Peter

Link to comment
Share on other sites

How come a new vps has a software that ended in 2010 installed? Is that normal? Did a small search and ubuntu 10.04 was already coming with php5.3 packaged...

Anyway, apparently you can upgrade php with a dist-upgrade

Link to comment
Share on other sites

  • 1 month later...
if (wire('input')->post->submit)) { ... }

;)

Inside functions, the API variables are out of scope. That's a PHP thing. So for every API variable, use the global function wire('api_var_here').

  • Like 2
Link to comment
Share on other sites

Hey Nico,

Great module, will come in very handy with my latest project. I have a question if it is possible to do the following with the shortcodes:

An Input like

Lorem ipsum dolor sit amet, consectetur adipiscing elit. [footnote]I’m quoting here![/footnote]
Morbi volutpat, enim in scelerisque tristique, tortor lectus tincidunt nisi, sit amet pellentesque sem nibh non enim. [footnote]Some other quote![/footnote] Etiam pharetra a metus ac aliquet. Sed posuere nibh eget lobortis pretium.[footnote]Here again![/footnote] Nunc commodo ut ante id placerat.
 

to render an output outside the shortcodes lke this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. (1) Morbi volutpat, enim in scelerisque tristique, tortor lectus tincidunt nisi, sit amet pellentesque sem nibh non enim.(2) Etiam pharetra a metus ac aliquet. Sed posuere nibh eget lobortis pretium.(3) Nunc commodo ut ante id placerat.

(1) I’m quoting here!
(2) Some other quote!
(3) Here again!
Link to comment
Share on other sites

You could do something like:

Maybe:

<?php

$shortcode->add('quote', function($atts) {
    $quotes = array();
    
    function replaceQuotes($matches) {
        global $quotes;
        $quotes[] = $matches[1];
        return '['.(count($quotes-1)).']';
    }

    $content = preg_replace_callback('%\[quote\](.*)\[\/quote\]%Uis', $atts['content'], 'replaceQuotes');

    $quotesString = implode('<br />', $quotes);
    
    return $content.$quotesString;

});

?>

  • Like 1
Link to comment
Share on other sites

Thank you very much for the heads up! Few hiccups, was not able to get it working, so I did a wrapper around the whole text with

[/quotearea] or I could just drop the $shortcode->add and have the code inline.
$shortcode->add('quotearea', function($atts) {
    $quotes = array();
    global $quotes;
    function replaceQuotes($matches) {
        global $quotes;
        $quotes[] = $matches[1];
        return '['.count($quotes).']';
    }
    $content = preg_replace_callback('%\[footnote\](.*)\[\/footnote\]%Uis', 'replaceQuotes', $atts['content']);
    $quotesString = implode('<br />', $quotes);
    return $content.$quotesString;
});
 

Wärmste Grüße von Shanghai nach Berlin, J.

Link to comment
Share on other sites

  • 1 month later...
Any questions left?

yes, this module doesn't seem to work with mutliple shortcodes of the same type, on 1 page;

is there some special logic needed to be coded into the shortcode to handle multiple shortcodes on 1 page;

for example if you try to do [sitemap] [sitemap] you'll crash the page

Error:     Cannot redeclare sitemapListPage() (previously declared in
/home/user/public_html/site/templates/shortcodes.inc:34) (line 34 of
/home/user/public_html/site/templates/shortcodes.inc)
 

I'm attempting to make a tabs shortcode, but not sure about how this will work, since there would be the same shortcode tag many times on 1 page. right now my tests show that it only processes the last one on the page for some reason;

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...