Jump to content
Chris

idea draft: template driven page list icons

Recommended Posts

Please read the following before looking on the big picture :))

Here's an idea i got, while experimenting with PW:

A lot of cool icon fonts are avaible, on the other hand the page system of pw can be used verry flexible. why not bring these together to improve customized backend usabillity,

version a (more complicated to build, i guess): when creating a template you choose the icon of your choice for this kind of content.

in the page tree, based on the template that you've choosen for every page, the pages uses an little icon.

version b (i guess, maybe simpler): based on the choosen template, the page <a> get's a css class with the name of the template.

so you need to attache an custom css in the backend that styles your page list with icons using the :before/:after css-technics, :)

i've seen that each page list item already get's a unique class, but it doesn't look like every page list item gets an class/id based on the used template.

i think version b of my idea is nicer, and would bring up more flexibilty so style the page tree, additionaly to the icon solution.

however, i did a dirty mockup of version a for better illustration.

what do you guys think about the draft?

writing something like this myself with php would be a realy big and scary task at the moment, since i'm a young padawan, but maybe some of the jeddai masters like it? :)

post-620-0-57191300-1343484902_thumb.png

<- i did an mistake..on the mockup i mean with "<-*click* a click on the picture symbol, not the pencil >.<

EDIT:

another "sourcecode mockup" to illustrate what would be cool the get with version b of the draft, so page list items get automatic an template name based icon

post-620-0-22425100-1343487654_thumb.jpg

, styleable with

div.basic-page:before {
content: "a";
}

div.sitemap-template:before {
content: "k";
}

link with more infos about the css part etc,

  • Like 3

Share this post


Link to post
Share on other sites

i've seen that there is something for "template name" in the api

a general question: does the backed work similar like the fronted concerning the pw api, or is the backend complete native php?

when the api is usable for the backend to, it shout be possible to do something with the "template name" function.

Share this post


Link to post
Share on other sites

There's been various mentions or requests already for something like page tree icons.

Just to mention, there's also option to define the label rendered in the page tree using custom fields. You'll find this under tab advanced. Using this if you add an image field it will output the image name as label. Using this I did some hacking. After that I also created a module to add Image thumbnails to pages in the tree, http://modules.processwire.com/modules/page-list-image-label/, little different from the template icon, but it's in the similar direction.

The process module responsible for creating the page tree list is https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Process/ProcessPageList/ProcessPageList.module

Not sure what could or should be the way to implement such a feature, but thinking outputting the template name as class added to the pages could make it simple using css as you mention.

The backend and everything in PW is using same API as you use (or can use) in templates, though using $this->pages or wire("pages") syntax instead of $pages, which makes it easy to get things done without the need to learn new things just because you're working on the backend. (although I seem to be repeating myself over and over, it can't be mentioned enough :D )

  • Like 1

Share this post


Link to post
Share on other sites

Looks like a nice idea for a module. I agree that in some sites it can make the tree more readable to some clients.

Not the same thing, but there is a module from Soma that you might like http://modules.proce...st-image-label/

The backend doesn't work exactly the same way as the frontend, particularly the processes, but can still use the API functions.This is possible for sure.

edit: Soma, sorry for the double answer :D

I still don't understand why sometimes the system doesn't alert that there is a new answer...

  • Like 2

Share this post


Link to post
Share on other sites

[...]

Just to mention, there's also option to define the label rendered in the page tree using custom fields. You'll find this under tab advanced. Using this if you add an image field it will output the image name as label.

[...]

thank you a lot. that will be very usefull to know in the future.

i don't understand all of the page-list code that you linked on github, but it's good see that i'm able to understand some parts of it:) verry cool to have the chance to use the gaining api knowledge for backend modifications to.

Share this post


Link to post
Share on other sites

Not the first time I took a look again at how this could be done the most simple way, since page list tree is done using ajax php/js it's not really possible to hook or change it so it adds a class with the template name to the list item.

If Ryan is willing to change two lines of code so a extra css class would be added, it would be easy from there to implement icons for different types of templates.

Adding 1 more option here https://github.com/r...ist.module#L398

"template" => $page->template->name,

Adding the class to the item here: https://github.com/r...ageList.js#L418

// change it to
var $li = $("<div></div>").data('pageId', child.id).addClass('PageListItem ' + child.template);

Voila, all items have the template name as class. Now one could create a module that adds a css file and some configuration on per template.

  • Like 2

Share this post


Link to post
Share on other sites

Good suggestions. This makes sense to me. I've added the code to add a class of PageListItem_[template name] to each item. Going to test a bit more locally and commit early this week.

Thanks,

Ryan

  • Like 3

Share this post


Link to post
Share on other sites

I was happy to see this has already been mentioned and is under way! Icons for templates would definitely make it faster for a content manager to browse the sitemap.

However, I'll just briefly mention one small reservation/concern I have about this...

I really like what this theme does - as far as using icons to indicate the state of an item, rather than the type of an item.

For one, the state of an item is sort of unclear at the moment - I know the color-coding of items is supposed to indicate this, but most people I've showed PW to so far don't see to pick that up without some explanation.

Another factor, is the fact that you're most likely going to have a high number of templates, and a low number of states - I personally find that icons are most useful when there's a low number of different icons. When you have a high number of different graphical symbols, reading pictograms starts to take more effort, and it gets to a point where there are so many types of icons, you simply start to ignore them.

Just something to consider: perhaps it would be wiser to use an icon to indicate the state of the items. And rather than using icons to indicate the type of item, perhaps it would make more sense to use color-coded badges to actually display the template-name - something along the lines of the labels you see on e-mail items in gmail. The color-coding and varying width of the badges helps you recognize same-type items intuitively - as opposed to a large number of same-size (and probably same color-scheme) icons, which quickly turns into "icon soup".

Just something to consider.

  • Like 1

Share this post


Link to post
Share on other sites

Good thoughts. I think the same. Though our clients don't have any problems understanding without anything (default theme).

BTW my theme goes the same direction http://modules.proce...odules/teflon/.

I think making it possible is nice, although I maybe won't really use it. Depends on the project.

Share this post


Link to post
Share on other sites

I committed the update today that adds a template class to all the PageList items. The class it adds is PageListTemplate_[template name], i.e. PageListTemplate_basic-page. So it should make it possible for modules or admin themes to go further with icons, colors or what not. I don't think we'll be implementing any of this output in the core/default admin theme, but wanted to make it easy for others to add the capability if desired.

Share this post


Link to post
Share on other sites

I spent a couple of hours tonight skimming through APIs, reading documentation, trying to understand how to extend the Template admin form...

It appears that only the execute_() methods are hookable? Only the execute-methods have the triple underscores - so it's not possible to extend the Template form tabs, or add new tabs? For that to be possible, the build_Form() methods would need to have the triple underscores added, is that correct?

Extending the admin forms is not permitted?

Share this post


Link to post
Share on other sites

You can add tabs via the field "FieldsetTabOpen" to templates. If you are talking about the template edit screen you're right.

Share this post


Link to post
Share on other sites

Extending the admin forms is not permitted?

It's just that the add form method isn't yet hook-able. It's not about not being permitted and it comes down to each process that creates form for various tasks in the admin. I think Ryan will be glad to make it hookable.

I also was starting a module to add icons to templates but stopped working on it. Just made css tests to see what can be done. Since my teflon theme already has icons in the page tree I tried to find a convenient solution. I was thinking about either extending the template edit form or just keep it on the module setting screen to be able to set a icon for each template on one screen. Either way it would work but still some things to figure out.

I made the buildEditForm hookable and was able to add tab easily.

Edit: this is example module to add tab and a checkbox to template edit screen. Once the buildEditForm() is hookable. Just add ___ to the method.


<?php


/**
* ProcessWire Page List Icons
*
* ProcessWire 2.x
* Copyright (C) 2010 by Ryan Cramer
* Licensed under GNU/GPL v2, see LICENSE.TXT
*
* http://www.processwire.com
* http://www.ryancramer.com
*
*/

class PageListIcons extends WireData implements Module {

   /**
    * getModuleInfo is a module required by all modules to tell ProcessWire about them
    *
    * @return array
    *
    */
   public static function getModuleInfo() {

       return array(
           'title' => 'Page List Icons',
           'version' => 100,
           'summary' => 'Add an icon per template in the admin page list',
           'href' => '',
           'singular' => true,
           'autoload' => true
           );
   }

   public function init() {
       //$this->config->scripts->add($this->config->urls->PageListIcons . "PageListIcons.js");
       //$this->config->styles->add($this->config->urls->PageListIcons . "fontello/css/fontello.css");
       $this->addHookAfter("ProcessTemplate::buildEditForm",$this,'addForm');
       $this->addHookBefore("ProcessTemplate::executeSave",$this,'saveForm');
   }

   public function addForm($event) {
       $form = $event->return;
       $template = $this->templates->get($event->arguments('template'));
       $t = new InputfieldWrapper();
       $t->attr('title', $this->_x('Icons', 'tab'));
       $t->head = $this->_('Add icons to pages');
       $t->attr('class', 'WireTab');
       $t->add($this->buildEditFormIcons($template));
       $form->add($t);
   }

   public function buildEditFormIcons($template) {
       $field = $this->modules->get('InputfieldCheckbox');
       $field->label = $this->_('Test');
       $field->attr('id+name', "mycheckbox");
       $field->attr('value', "test");
       if($template->mycheckbox) $field->attr("checked","checked");
       return $field;
   }

   public function saveForm($event) {
       $value = isset($this->input->post->mycheckbox) ? $this->input->post->mycheckbox : null;
       $templ = $this->templates->get($this->input->post->id);
       if($templ->mycheckbox != $value) $this->message($this->_("Template saved: Test"));
       $templ->mycheckbox = $this->input->post->mycheckbox;
   }

}

Share this post


Link to post
Share on other sites

@soma Thanks, this is very educational! ... Teflon is my theme of choice, by the way - mainly because of the icons and navigation, lightning fast to work with... but as with PW standard theme, I find that once you have a lot of Pages on your sitemap, it starts to get harder to keep track of what's what. I'm going to attempt to add a label/color setting to Templates. I'll post my results here.

Share this post


Link to post
Share on other sites
I think Ryan will be glad to make it hookable.

Definitely -- anytime you need something to be hookable just edit it, precede the function with the 3 underscores (to make sure it does what you want) and then let me know and I'll update the source to have it hookable. This is possible in most cases. Occasionally, there will be function that is used so much that making it hookable would be an overhead concern, but there's very few of those.

  • Like 1

Share this post


Link to post
Share on other sites

What's the difference between $label = $this->modules->get('InputfieldText') and $label = new InputfieldText() ?

Share this post


Link to post
Share on other sites
What's the difference between $label = $this->modules->get('InputfieldText') and $label = new InputfieldText() ?

This is a good question. Both would give you a new instance of InputfieldText. However, for any module, it is preferable to use $modules->get('moduleClass'); because it ensures the module is ready for use. Modules require an init() method, distinct from the __construct(); method. When you instantiate a module on your own using new you bypass the built-in logic that determines when/if a module needs to be initialized based on it's autoload/singular settings.

It's also preferable to use $modules->get('...') because new InputfieldText() wouldn't work if the InputfieldText.module file hadn't already been included. Whereas $modules->get() knows when/if to include files.

Share this post


Link to post
Share on other sites

I thought it might be something like that. Any particular reason the autoloader couldn't be responsible for this?

Anyhow, to return to the original subject - I've mostly built out a module (yay, my first!) that lets you add a colorful badge and/or an icon to a template, which will display on the page list.

Here's a screenshot:

screenshot.png

The repository lives here:

https://github.com/mindplay-dk/TemplateBadges

Two known issues:

  1. I realized too late that ProcessWire uses an older version of jQuery - to test this module, you will need to replace the bundled jQuery with a newer version. I posted the issue here.
  2. ProcessTemplate::buildEditForm is not hookable - I haven't posted an issue for this, since Ryan said he will adds hooks as needed.

With those two fixes in place, you should be able to test it out.

Since this is my first, I would appreciate a code review and feedback from any experienced module developers!

  • Like 4

Share this post


Link to post
Share on other sites

Thanks for sharing! Looks cool so far. Great learning for sure.

What have you used that it requires a newer version of jQuery core?

Might be only me, but I'd have gone for a icon font, but having .png icons makes it easier to implement of course.

When I've seen that color picker, I immediately thought about my ColorPicker Fieldtype that would be nice to have here maybe.

I'm not too happy with the badge label. Look much like a button, and personally it add's too much color and noise for my taste.

I also wanted to mention that this "Badge label" can also be already done by using custom label setting in templates. Just add as a field string "title template.label". And it will show the label of the template.

Only took a quick glimpse at the module, and couldn't understand how it's all done, also it looks very different from how I would've implemented it. But keep up the good work and congratulation on your first module!

Share this post


Link to post
Share on other sites

I use jQuery.on() everywhere - it's basically the standard for event-management in jQuery now.

An icon font, hmm... I prefer to have a folder where I can drop in another icon when needed.

I knew about the custom label setting, but I wanted something colorful you can distinguish from the rest of the content - I won't personally be using the label-feature on every template, just on certain templates to call attention to certain things. The style was lifted from Twitter Bootstrap's badge style - I'm not a designer, but it looks fine to me.

I saw your color-picker and decided not to use it, as it creates more complications from having to either compute (or enter) a foreground color. I also decided I wanted a small preset list of colors because I'm not trying to turn the page list into a color symphony - a low number of colors that are easy to distinguish from each other.

All conscious decisions.

I was less conscious of API choices and PW conventions - I tried to grok what I could from existing plug-ins, but as said, a code-review would be appreciated, if anyone has the time/experience...

(on that note, the documentation page really could use a chapter explaining hooks in depth...)

  • Like 1

Share this post


Link to post
Share on other sites

Yeah, I can see why you chose to make it that way.

From the code base, it all looks good, nothing wrong there.

I'm not too sure about those hooks you have in your hook method's.

Especially "$icon->addHookAfter('render', null, function(HookEvent $event) use($icons, $icons_url, $icons_license) {..."

And "$t->addHookAfter('render', $this, 'hookAfterRender');" which I don't think is really needed.

Now when I try to install I can't and get error in admin once I check for new modules.

Parse error: syntax error, unexpected T_FUNCTION in /Applications/XAMPP/xamppfiles/htdocs/pw-dev/site/modules/TemplateBadges/TemplateBadge.module on line 93

Share this post


Link to post
Share on other sites
I thought it might be something like that. Any particular reason the autoloader couldn't be responsible for this?

The most basic reason is that modules are delivered to the API in a configured state where they have had configuration data populated to them by the Modules class. The module itself can use its constructor to populate defaults. Once init() is called (again by the modules class) configuration data has been populated to the module. Once ready() is called, the API is fully ready (if it's an autoload module). Basically, a lot happens between when the module is constructed and when it's delivered to you. If you just do "new ModuleClass()" then you are skipping over a sequence of events that is important for some modules and not for others. So it's a best practice to use $modules->get('ModuleClass') rather than new ModuleClass, so that you don't have to worry about what initialization does or doesn't need to occur in a module based on it's configurability, singular and autoload status.

Anyhow, to return to the original subject - I've mostly built out a module (yay, my first!) that lets you add a colorful badge and/or an icon to a template, which will display on the page list.

This looks great! I can't wait to try this one out tomorrow (only on mobile this evening). Nice work.

Share this post


Link to post
Share on other sites

@Soma you need PHP 5.3 for this module.

@ryan thanks for the clarification - this probably should be part of a documentation page about module development?

Regarding the two hooks mentioned by @Soma, yeah - I wasn't too sure about these, but what's the alternative?

I went with $icon->addHookAfter('render', ...) in order to inject my own markup (the icon list) into the form... is there a cleaner way to do that?

The hookAfterRender() method is there for two reasons:

1. So I could inject the initialization script-tag - is there a cleaner way to do that?

2. So I could add to $config->scripts ... init() seems like the right place to do that, but for some reason my script-tag would show up "too soon", e.g. before jQuery, so it didn't work... is there a better way to work around that?

For the same reason, I'm not adding the CSS in init() - it shows up too soon, and my rules get overridden...

I guess the underlying question here is, can you control the order of script and css embeds?

Share this post


Link to post
Share on other sites

@Soma: except if you do it via 'title template.label', it will comma separated and there is nothing you can do about it, right?

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By quickjeff
      Hi Guys, 
      I have been debugging a site for the last 2 hours and cannot solve the issue. 
      I have a site running on 3.0.148. 
      I installed the Kongondo Blog module and was updating the templates to include the website style. 
      Once everything was set and done, I checked the page tree to see an error appear. 
      Template must be assigned a name before 'filename' can be accessed
      The same error appears in templates. 
      Debugging Steps
      I checked the templates in the server to ensure I didnt accidentally delete the namespace.  Deleted cache in browser and server under assets Still no go. 
      Any help is appreciated. 
      Thanks! 
    • By Falk
      Hi!
      I have lots of blogposts in my pagetree and I want the pagelabel to include the value of the post’s datefield (only the year).
      Adding date | title in the template settings results in something like…
      1536012000 | my blogpost title
      Is it possible to convert the timestamp to a readable date?
       
    • By Robin S
      PageListTrash
      Allows non-superusers to trash pages directly from Page List (if they have page-delete permission for that page).
      Not much to say really - the module adds a "Trash" option to the extra actions for pages in Page List. It looks and works just like the Trash action available to superusers.

      https://github.com/Toutouwai/PageListTrash/
       
      Up to you whether you think non-superusers should be trusted with simpler trashing. For most cases I like the default behaviour where editors have to jump through some more hoops - I want them to think carefully about what they are doing. But if an editor needs to trash several pages then this module might reduce frustration.
      @tpr, by now you can probably predict what I'm going to say...
      ...something to merge into AdminOnSteroids?
    • By jploch
      Hey!
      I just finished working on a website for a client.
      To restrict the use of PW for the client (so he can't brake the website), I created a new User and asigned some permissions.
      The problem is, that the link to the page tree is missing, when I login with the new user (see screenshot).
      Only the "Add New" shortcut works.
      When Iam logged in as admin, everything works fine.
      I never had this problem before. Iam using PW 3.0.25
      Any Ideas?
      THX!
       

    • By Jason Huck
      When logged into the admin as the superuser, the 404 page appears in the page tree per usual. When logged in as a "site administrator" (a custom role), the 404 page is missing. The 404 page uses the basic-page template and hasn't been edited or altered in any way. Under "who can access this page", it shows the expected permissions (site administrators can definitely edit basic pages), and in fact, if a site administrator navigates directly to the edit screen for the page, it works fine. So it's not a permissions issue per se, it just doesn't show up in the page tree for users in that role. It is a multilingual site, and English is not the default language, in case that's relevant. Any thoughts?
       
×
×
  • Create New...