Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2012-03-31 08:38:07

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

tps_spoiler - Spoiler plugin to quickly hide and unhide text

Hey folks,
first of all this is my first post and textpattern plugin, so please tell me if I did anything wrong.

Whats my plugin about?

I wanted to have a nice way to fold (show) and unfold (hide) text in my blog.
Since I didn’t find any spoiler plugin available I decided to create my own one.

Usage is quite simple

Update: Since I remade it, the usage is different. Check the Help for more info.

Just install it and put
<txp:tps_spoiler>Text to be hidden</txp:tps_spoiler>
somewhere in your article.

By default the text will be hidden and a link displayed, to unhide the text.

You can view a demo and download it here

If you have any problems, bugs or suggestions, don’t hesitate to tell me.

Ps: I would really appreciate it if someone could add the “tps”-prefixe for my name and I would feel honored if I could get my plugin posted to the resources.

Last edited by Tomsec (2012-04-01 00:04:48)

Offline

#2 2012-03-31 10:45:05

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,271
Website GitHub

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Tomsec wrote:

this is my first post and textpattern plugin

Hello and welcome. Thanks for the plugin.

I would really appreciate it if someone could add the “tps”-prefixe for my name

Done.

I would feel honored if I could get my plugin posted to the resources.

I’ve sent you a login so you can manage all your plugins yourself. It’s not an optimal workflow at the moment (add each plugin as an article in the ‘plugins’ Section) but things are changing very slowly towards something better.

I’ve also made your forum account a ‘Plugin Author’ so you can create topics in the Author Support forum. I’ll move this post there as well.

Hope that’s all ok. Thanks again, and welcome to the club :-)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#3 2012-03-31 11:21:33

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Welcome to abroad. We don’t generally see much widget type plugins, as Textpattern’s nature and target audience makes them obsolete. But nice to see some new blood.

I took quick look at the code. Some things that I’ve found:

  • The default attribute values should be parsed, or even better, ideally the default values wouldn’t use any tags but PHP (i.e. hu.'/somepath/here'). Currently the values are only parsed because of parser’s secondpass, which is something you may not want to relay to.
  • The JavaScript variables foldimg and unfoldimg are global. You should wrap your code in a function, or prefix the variables to avoid collisions. Declaring the variables using var keyword wouldn’t hurt.
  • The PHP variables passed to JavaScript should be escaped with Textpattern’s escape_js() to prevent breaking the JavaScript when user passes a quote, or linefeed to the attribute.
  • The tag outputs same old JavaScript multiple times. You only need that type of script once. Using same function name and global variables does work because of JavaScript’s nature, but isn’t good practice.
  • The spoiler counter deal, including !isset($tps_spoilerCounter), could be compressed to single line and changed to static instead of global. I.e. static $counter = 0;.
  • Psst, heredoc. Quotes like to be naked and slashless.

Styling-wise:

  • I would recommend following style guide and writing all attributes lowercase instead of camel. Separate multi-word names with underscore or even better, avoid them as much as possible. My advice would be to take a closer look at the core tags and try use similar naming scheme.
  • Help files are mostly rendered using Textile. Instead of what you have now, I would recommend styling the files the same way as other plugins do. Especially please use paragraphs instead of linebreaks, and code tags for code. The raw HTML option of the plugin template is a secondary fallback for b/c. See Plugin Help Guidelines.

Suggestions;

When it comes to the tag, it’s attribute and using it, I would personally prefer if it had just couple straightforward attributes. E.g. hidden, visible… and that’s it. No inline styles or anything that nature. If you want inline styles or formatting, I would suggest taking the standard wraptag, class approach. I.e.

<txp:tps_spoiler hidden="Some content when hidden, or even HTML">
	Some spoiled cheese.
</txp:tps_spoiler>

Or maybe even use of <txp:else />.

<txp:tps_spoiler>
	Some spoiled cheese.
<txp:else />
	Some content when hidden, or even HTML.
</txp:tps_spoiler>

JavaScript wise, I would like it better if it were “modular”. The functionality of the widget-type plugin is identical to few lines of jQuery flavored JavaScript.

<script>
	$('.spoiler').before('<a class="spoiler_toggle" href="#">Show spoilers</a>');
	$('.spoiler_toggle').click(function() {
		$(this).next('.spoiler').slideToggle();
	});
</script>

Same type of JavaScript (using jQuery, or not — getting next sibling is more complicated w/o it tho), could provide better JavaScript functionality and resulting markup for the plugin.

Combined to event hooks and wise loading, you can simply output it just once by simple returning it only on the first tag instance — which is very easy with a help of static variable.

function tps_spoiler($atts, $thing) {
	static $javascript = NULL;

	/* [...] */	

	if($javascript === NULL) {
		$javascript = <<<EOF
			/* Some JavaScript here */
EOF;
		return script_js($javascript);
	}

	/* [...] */
}

Last edited by Gocom (2012-03-31 11:32:40)

Offline

#4 2012-03-31 17:32:55

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Thx a lot for the help and feedback.

I try to go throw the feed back and fix it.

The things is: PHP was my first programming language and I left it years ago to use Java and code “offline” instead. So my HTML and Javascript skills tend to violate coding rules.

With the Camel-Case naming thats due to Java and the multi-part words are due to being german and being tough to give meaningful names which don’t need any explanation.

But as I said I try to fix as much as possible and improve my style.

With the helpfile I have to admit I didn’t want to waste too much time creating it, but I had it done in textile at first and it didn’t render in HTML, so I switched to plain HTML instead. (I saw you doing it in some of your plugins too). Do have have to do something special go get it running?

In general it was some kind of quick shot, to get what I needed. (I’m using textpattern for less than a week) If I have the time to read all the dev articles I will do so, but as always time is limited.

I don’t think I’ll become a regular textpattern-programmer, but what ever I need and can’t find I’ll code and I I’ll try to do it right and make it useful for others too.

One last thing. What did you mean by this:

Welcome to abroad. We don’t generally see much widget type plugins, as Textpattern’s nature and target audience makes them obsolete.

I got that the nice thing about textile is, that you don’t have to use xml-Tags all the time, but is there another way to put such a plugin into textile style? Like you only have to write .{ Hidden Text }. or something similar?

Now I’ll start fixing stuff and then I’ll upload it to the resource page. :)

Ps: I realy like textile and textpattern, you did a great job guy. Thumbs up

Offline

#5 2012-03-31 18:22:27

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Tomsec wrote:

so I switched to plain HTML instead. (I saw you doing it in some of your plugins too).

I use zero HTML or custom-styles in my help files. They are all done in just plain Textile. I parse the Textile on server with some guy’s compiler to avoid b/c issues in-case the target server uses older Textile version (or newer).

With the helpfile I have to admit I didn’t want to waste too much time creating it, but I had it done in textile at first and it didn’t render in HTML, […] Do have have to do something special go get it running?

To set the target server to parse the markup, you would set allow_html_help meta to 0 and use help_raw instead of the help. The meta help can only contain preprocessed content, while help_raw can contain Textile markup.

It doesn’t really matter which one of the approaches you take, as long as the help file’s markup structure is clean and complies with variety of admin-side themes.

One last thing. What did you mean by this:

Unlike many other systems, Textpattern doesn’t limit what your templates do and it neither outputs any markup with out telling it to. With the freedom, widget type plugins (like tsp_spoiler) aren’t necessarily needed. The plugin’s real functionality can be covered with three lines of JavaScript.

I got that the nice thing about textile is, that you don’t have to use xml-Tags all the time, but is there another way to put such a plugin into textile style? Like you only have to write .{ Hidden Text }. or something similar?

Textile supports HTML attributes including classes, so I would say yes, with relative easiness. A unique selector for the spoilers is only thing you need to do the JavaScript magic. For example using the JavaScript snippet I mentioned above (in the previous post), you could simply say;

p(spoiler). Some spoilers here.

Textile also has it’s own plugin format experiment, but the branch that is implementing it is rather experimental and old. But some day Textile could have a plugin support of its own.

Last edited by Gocom (2012-03-31 18:25:35)

Offline

#6 2012-03-31 23:39:46

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

So big thx again to Gocom,

I took at much of your advice I could, had a big look into jquery and remade the plugin.
I think it was worth the work and I learn some cool new stuff, so thx again.

For the plugin you now you can take p(tps_spoiler). to create spoilers and all the rest is cleand up to.

With the help file I took one of yours as an blue print. I hope that’s ok, otherwise I’ll rewrite it again.

Maybe you would like to have another look tomsec.de/10/textpattern-spoiler-plugin. I would really appreciate it.

I start to like textile and textpattern even more. :D

Offline

#7 2012-04-01 05:49:57

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Tomsec wrote:

With the help file I took one of yours as an blue print. I hope that’s ok, otherwise I’ll rewrite it again.

That’s fine. The help file looks good and so does the code look better. If anything I would use heredoc for the JavaScript code (so that you don’t need to escape the quotes in the code). Also you can save some announces by using array_map to the lAtts instead of escaping all the variables individually.

Especially if you are not distributing the icons with the plugin, the icon specific attribute could be merged to the label attributes. If the user wants to use HTML, he can with those.

Executing the points I mentioned and also after cleaning up dead weight from JavaScript, the plugin would look as little as;

function tps_spoiler($atts) {

	extract(doArray(lAtts(array(
		'visible' => 'Click here to hide the content',
		'hidden' => 'Click here to show more content',
		'default' => 'hidden',
	), $atts), 'escape_js'));

	$js = <<<EOF
		$('.tps_spoiler').wrap('<div class="tps_spoiler_wrap" />');
		$('.tps_spoiler').before('<a class="tps_spoiler_toggle" href="#">{$visible}</a>');

		$('.tsp_spoiler_wrap').click(function(e) {
			e.preventDefault();

			var area = $(this).children('.tps_spoiler');
			var toggle = $(this).children('.tps_spoiler_toggle');

			if(area.is(':hidden')){
				area.slideDown();
				toggle.html('{$visible}');
			}

			else {
				area.hide();
				toggle.html('{$hidden}');
			}
		});
EOF;

	if($default == 'hidden') {
		$js .= '$(".tps_spoiler_wrap").click();';
	}

	return script_js(
		'$(document).ready(function() {'.$js.'})'
	);
}

JavaScript-wise, I removed the left-over Image() instances, defined the variables (var), removed prefixing from the variables as they are in their own scope (inside a function), used jQuery’s is() and “:hidden”:http://api.jquery.com/hidden-selector/ selector, replaced return false with preventDefault(), and finally wrapped the code into a ready so that it can technically be placed close to anywhere on the page.

Offline

#8 2012-04-01 10:56:56

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Thx a lot again.
I put all your advice into the plugin.

Just one more question:
I made

<txp:tps_spoiler>
<img class="tps_spoiler_img" src="/images/icons/unfold.png"> click here to hide the content
<else/>
<img class="tps_spoiler_img" src="/images/icons/fold.png">click here to show more content
</txp:tps_spoiler>

work for the declaration. In adition to the “show” and “hide” attributes.
But I couldn’t find a smarter way to treat the <else\> tag, that to explode the 2nd argument using it as a delimiter.

Is there a textpattern way to do it? I found EvalElse, but thats not really what I needed in that case.

I did not include the Icons because I was not 100% sure if I’m allowed to so by copyright law, but the current situation is more flexible, so its better that way anywas.

Offline

#9 2012-04-01 12:08:24

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

EvalElse is what you need. EvalElse returns content before <txp:else /> when second attribute is TRUE and the fallback when it’s FALSE. For example I used EvalElse extensively in my mck_login fork/patch. So, picking the labels is very simple, e.g.

$visible = parse(EvalElse($thing, true));
$hidden = parse(EvalElse($thing, false));

Remember to run the results with parse(), but only after EvalElse.

Offline

#10 2012-04-01 12:27:42

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Omg, you are so right. I kinda overlooked that way of using it.

I’ll fix and upload it this evening. :)

Offline

#11 2012-04-02 22:51:12

Tomsec
Plugin Author
Registered: 2012-03-31
Posts: 7
Website

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Updated to V 1.0 and hopefully final.

By the way is there a plugin, that can parse ALL kind of links and sets the rel-Attribute to “nofollow”? (Since I wanna mess around with google and try how it behaves on that move).

I know for your rah-urltolink plugin there is an option, but only for the links it creates itself.
My current approach is to take the PHP DOMDocument, pars the posts HTML and check all links in it. This has the bad side effect, that you have to do some nasty stuff to deal with UTF-8 (at least following the comments at php.net) and some other nasty stuff to get rid of the auto added html- and body-tag.

The result is currently working, but not really efficient and to nasty to be ever released. Thats why I asked for a plugin. I could not get a hold of zem_prblock, since the source code seems to be gone. :(

Offline

#12 2012-04-02 23:27:38

uli
Moderator
From: Cologne
Registered: 2006-08-15
Posts: 4,304

Re: tps_spoiler - Spoiler plugin to quickly hide and unhide text

Tomsec wrote:

I could not get a hold of zem_prblock, since the source code seems to be gone. :(

My HD is a treasury :)

function zem_prblock_replace($attr, $type='nofollow') {
    global $siteurl, $zem_prblock_atts;

    $atts = @splat($attr);

    $link = @$atts['href'];
    if ($link) {
        $url = parse_url($link);
        $mydomain = preg_replace('/^www\./', '', $siteurl);
        $linkdomain = preg_replace('/^www\./', '', @$url['host']);

        if ($linkdomain and @$url['scheme'] == 'http' and $linkdomain != $mydomain) {
            if ($type == 'nofollow') {
                $atts['rel'] = 'nofollow';
            }
            else {
                $atts['href'] = 'javascript:;';
                $atts['onClick'] = "window.location.href='$link'; return false;";
            }

        if (is_array($zem_prblock_atts))
            $atts = array_merge($atts, $zem_prblock_atts);
        }
    }

    $out = '';
    foreach ($atts as $k=>$v) {
        $out .= ' ' . $k . '="'.$v.'"';
    }

    return '<a'.$out.'>';
}

function zem_prblock($atts, $thing) {
    global $zem_prblock_atts;

    $type = isset($atts['type']) ? $atts['type'] : 'nofollow';
    $zem_prblock_atts = $atts;
    unset($zem_prblock_atts['type']);

    $out = parse($thing);

    return preg_replace('@<a\s+([^>]+)>@ei', "zem_prblock_replace(\"\\1\", \"$type\")", $out);
}

In bad weather I never leave home without wet_plugout, smd_where_used and adi_form_links

Offline

Board footer

Powered by FluxBB