Jump to content
kongondo

Menu Builder

Recommended Posts

@kongondo,

Thanks for making this.

i finally had time to test this out and it's very great - i'm planning to use it from now on for most projects...

  • Like 2

Share this post


Link to post
Share on other sites

@Macrura,

Glad you liked it. Like I hinted in my first post, your custom menu idea was one of my inspirations, so thank you too :-). It still needs some work and re-factoring but time is my worst enemy (currently? always? :-)). Let us know how you get along.

Share this post


Link to post
Share on other sites

great - i was planning a write up/tutorial on various ways to do menus on PW;

historically i've done it using a lot of different ways (besides the usual generating from the page tree);

for some simple sites now i use a profields table, now that it supports page selects.

but i do think the menu builder is the best for larger sites; let me know if you need any help on it, i can donate time over the next 2 months.

  • Like 2

Share this post


Link to post
Share on other sites

let me know if you need any help on it, i can donate time over the next 2 months.

Thanks, might just do, considering my growing issues list. I also have @jlahijani list of ideas to consider.

Share this post


Link to post
Share on other sites

Update: Version 0.1.1

And, we are back! Thanks for waiting!  :) 

  1. Fixed bug relating to getLanguageValue() (issues #22 and #25). Thanks @all who reported, tested,and fixed the issue.
  2. Fixed bug where 'has_children' would not be applied to a menu item whose children were included 'natively'.
  3. Switched to $this->wire('pages') from wire('pages') (and similar).
  4. As per request at issue #18, added option 'default_class' to enable application of a default CSS class to every menu item at API level. Thanks @jlahijani. You can use this API-level option to add custom CSS class(es), e.g. Bootstrap or Foundation ones.
  • Like 5

Share this post


Link to post
Share on other sites

Update: Version 0.1.2

  • Fixed bug whereby 'new tab' setting for new custom menu items would not work reliably
  • In addition to the existing AsmSelect and Page Autocomplete options of adding pages to menus, you can now also use a PageListSelectMultiple. This is similar to the original version of MenuBuilder (not in styling but function :P  :) ). Personally, I am not a fan* of the option....the tree jumps all over the place and can be unwieldy. Anyway, the feature is there for those who prefer it :-). Logged in as a Supersuser you will see the whole tree, of course. Not other users though. So, no 'danger'(?) of them adding admin pages to the menu!

*I might rethink this and remove PageListSelectMultiple as an option..

  • Like 3

Share this post


Link to post
Share on other sites

Hi! Thanks for the great module!

After deciding that its functionality was a bit too much for what I wanted to do right now, I tried to uninstall the module but it throws this error: 

Can't delete template 'menus' because it is used by 1 pages.
The Markup Module unisntalls just fine.

 I am using PW 2.6.1

Thanks for further assistance,

Thanks for catching this. The error there meant you had some menu pages in the trash. On uninstall, the module was trying to delete their template, hence the error. Fixed in the latest version, 0.1.3.

  • Like 1

Share this post


Link to post
Share on other sites

Update: Version 0.1.3.

  • Fixed bug where on uninstalling the module, menu pages in the trash would not get deleted, hence throwing an error when the uninstall routine tried to delete their template
  • Like 1

Share this post


Link to post
Share on other sites
  • In addition to the existing AsmSelect and Page Autocomplete options of adding pages to menus, you can now also use a PageListSelectMultiple. This is similar to the original version of MenuBuilder (not in styling but function :P  :) ). Personally, I am not a fan* of the option....the tree jumps all over the place and can be unwieldy. Anyway, the feature is there for those who prefer it :-). Logged in as a Supersuser you will see the whole tree, of course. Not other users though. So, no 'danger'(?) of them adding admin pages to the menu!

*I might rethink this and remove PageListSelectMultiple as an option..

Thanks for adding PageListSelectMultiple.  I personally think it should stay since it puts you in the page tree context (meaning you see the page/child structure), thereby making it easier to understand the exact page you are choosing.

Share this post


Link to post
Share on other sites

Here are my thoughts:

Hi Jonathan,

Thanks for taking time to pen your thoughts about how this module could be improved.

Perhaps remove the ability to create multiple menus.  It's a nice feature but it feels like overkill since sites typically don't have more than just a few menus.  (or disable this option by default and perhaps have it enabled in the module's settings for advanced used).  Perhaps add a standard "Add New" button instead that follows the typical Page creation process.

Although the module is primarily for building menus, out in the wild, its probably being used to build other navigational lists as well. True, many sites have 2 - 3 menus at most, but I want the module to remain as flexible as possible. The create new field is collapsed by default so I don't think it looks like its inthe way?

For the same reasons above, remove batch actions to delete, unpublish, etc.  (or disable this option by default and perhaps have it enabled in the module's settings for advanced used).

That field is hidden by default and secondly, one can control what actions appear via permissions. In addition, my point above about how people are using this module is still applicable here.

When going in to edit a menu, make the first tab be "Structure" which is selected by default.  This is typically the first action most people would want to take so it would feel more natural for it to be the first tab item. There should be 3 fieldsets/sections in this "Structure" tab:

Add Page

Add Custom Link

Menu Items

I have not been able to find out how the 2nd tab can be selected by default.

Fieldsets do take some vertical space. I tried this in the first version of the module and I didn't like the results.

Perhaps simplify how you can add pages to your menu:

Remove the existing 3 methods: Pages (both ASM and PageAutoComplete), Custom, Selector

In regards to adding pages using Selectors, perhaps have this disabled by default, but an option that can be enabled in the modules settings.  It's an advanced feature but I'd imagine wouldn't be as commonly used and therefore feels a bit overwhelming.

If possible, replace with a ProcessPageList (this is what goes inside the "Add Page" fieldset).  It feels like a more natural fieldtype since it uses the tree.

I think providing choice is a good thing; let the user decide what best fits in their workflow. In the first version of the module, it only used a 'page list' (actually, an InputfieldPageListSelectMultiple) and the results were not very pretty. I (and others) found it a bit tedious, especially with long trees. To offer more choice though, I have gone ahead and added an option to select pages using PageListSelectMultiple (MB version 0.1.2).

Since version 0.0.4, there is already a permission 'menu-builder-selector' that hides the selectors field, hence prevents non-superusers from adding pages to the menu using selectors :-)

since this would replace the ASM way of adding menu items, that means you can't change a CSS Class/ID until AFTER it's been added to the menu.  I think that's OK since right now you change CSS Classes/IDs both before and after adding the menu item, which I find a little confusing.

This is also about flexibility. You add a menu item including CSS Classes/IDs and you forget about it :-)....Until when you have a need to edit them, then you head to their settings. I think this a good feature :-)

If possible, upon clicking a page to add to your menu on the ProcessPageList, it should show an "add" action/button (native ProcessPageList action stuff), that when clicked, adds the page to the actual menu (some ajax/dom manipulation required here I think) instead of putting it in a "limbo" state like it is right now until a page is saved.

As far as being able to add custom links, that should go under the "Add Custom Link" fieldset.  Perhaps also remove batch ability to add Custom Links and utilize general Inputfieldtext instead of a table structure.  Remove ability to set CSS Class and ID at this stage.

Using the PageListSelect to add items to the menu in that way will require some (JS) work which TBH, I can't spare some time to learn how to do, test and implement.

I am afraid I don't see any real benefit to removing the ability to add CSS Classes and ID to custom links at the point of creation :-). As stated previously, it allows you to do things once, and only edit them later if needed.

Now for the "Menu Items" section:

Right now, you're utilizing custom styling and javascript for the adding page items and creating the toggle boxes, however it should be possible to use make each added menu item act as an InputfieldFieldset.  When each item/fieldset is clicked, it should reveal the 5 editable fields (Title, URL, CSS ID, Class Class, New Window) and ability to delete.  Apply the nestedSortable JS to that list to make it have drag/drop capability with indenting.  A final result similar to this screenshot which I hacked together.

You 'hacked-together' version looks interesting. I would find it confusing if there were many items though. It wouldn't have that 'menu-items-look' to it, IMHO. Having said that, I prefer the current Menu Builder look  :P  ;) 

"Main" tab should be renamed to "Settings".  Put as second tab.

"Items Overview" tab: this could be removed (or disabled by default) since it's essentially just displaying the same menu in a table.  Feels repetitive.

"Delete" tab should remain as is.

I like the idea about renaming the 'Main' tab to 'Settings' and moving it to second, possibly 3rd tab. I am not sure how much impact renaming would have on any tabs out there that have already been translated (non-English sites). I'll have a think.

I have found the 'Items Overview' tab quite invaluable. Even on a menu with, say, just 3 items, if I only wanted to find out their CSS IDs and/or Classes, it saves me from clicking to expand and collapse each menu item's settings just to have a quick glance about their CSS attributes (+ new tab setting for custom links).

Again, thanks for taking your time to review the module. Although I take a different view to many of your suggestions, I appreciate that you took time to think about and write down your thoughts. ^-^ 

How's the screencasts coming along?

Cheers,

kongondo

Share this post


Link to post
Share on other sites

Dear forists,

this post is just to help others to find the solution to the issue, which has been mentioned and solved here and in the following post by hansv, and which is currently difficult to spot via Google.

Snippets of the error message are

    No menu items found!     

  MarkupMenuBuilder.module(88)

To repeat the explanation given, kongondos Menu Builder, which is really a great piece of software, creates named menu datasets, aka pages, and can in monolingual sites render the respective menus by using the menu dataset / page name.

In multilingual sites,though, it currently cannot. One has to resort to other ways of addressing the prepared menu dataset, by its ID.

To get the latter, open the menu editing page and look into the address bar.

Now render your menu with a string analog to 

$menumodule->render(1023);

(added) Kongondo noted "that you can also pass a menu $page or an array of menu items in addition to the ID."

I don't know how exactly to get a menu page object into a variable, so I resort to the ID method.

Of course, you can include the options as explained in the readme.

This is all redundant information but may be it helps somebody to get it faster.

Share this post


Link to post
Share on other sites

kongondo, do you have a donation pathway, i d like to buy you 2 coffees or something.

  • Like 3

Share this post


Link to post
Share on other sites

kongondo, do you have a donation pathway, i d like to buy you 2 coffees or something.

I'm glad you find the module useful :-)

Share this post


Link to post
Share on other sites

Hi, I am new using PW and I am building my first website.

I am trying to use the menu builder to create the a dropdown menu using bootstrap and not getting menu to work. I don't know if it is a programing problem or a css problem.

Where can I find some example with Menu Builder and bootstrap to build a dropdown?

How can I insert new attributes into the menu tag or into the children's tags, like 'role=""' or other attribute?

Thank you.

Share this post


Link to post
Share on other sites

Hi @bluellyr,

Welcome to PW and the forums. Currently it's not possible but its something I think I can easily add to the module (no ETA though!). Meanwhile, you can try what @Webrocker did here or check if MarkupSimpleNavigation (a non-GUI menu builder) will enable what you are after.

Share this post


Link to post
Share on other sites

Hi, can I get the menu array items from the menu builder? or it is to difficult?

If possible I could construct the menu manualy.

Thank you.

Share this post


Link to post
Share on other sites

Everything you need is in that example :-)...Constructing the menu manually is also a good option where there are only few items and the menu will not be changing

Share this post


Link to post
Share on other sites

Hi, I manage to build the menu in a bootstrap navigation bar,

thank for your help.

Now I have other problem, when creating menu items in the Menu builder admin,

the pages I had created and want to add to the menu I can not find them on the pages dropdown.

The pages are publish and are like others, it is possible a config problem? 

Can you give me some hints about this?

Thank you.

Share this post


Link to post
Share on other sites

Have a look at the second paragraph in this section in the README. I have just updated it now. By default, only 50 pages are returned if using AsmSelect or PageAutocomplete. Either use a custom selector or the 'PageListSelectMulitple' method to add pages to your menu. Let me know if this resolves your issue.

Share this post


Link to post
Share on other sites

Update: Version 0.1.4

As per @cJonathan Lahijani suggestion, in ProcessMenuBuilder, I have moved the first tab 'Main' to become the third tab and renamed it to 'Settings'. I think it looks much nicer now, thanks @Jonathan. This is in dev branch only for now.

post-894-0-66061600-1454190835_thumb.png

  • Like 2

Share this post


Link to post
Share on other sites

Hey kongondo, 

this plugin is amazing! Is it possible to output something like this:

<a href="#" onclick="return false">Menu Link</a>

I want to add the "onclick" event.

I hope you can help me,

thanks Jannis.

Share this post


Link to post
Share on other sites

If you use JavaScript anyways, why not add the event also by JavaScript?

Share this post


Link to post
Share on other sites

...Is it possible to output something like this:

<a href="#" onclick="return false">Menu Link</a>

I want to add the "onclick" event.

Hi @jannisl,

Welcome to the forums. Glad you find the module useful.

Currently, that can't be done. There has been a similar request recently and am currently thinking how best to implement this. My current thinking is to allow such functionality both in the backend (Menu Builder GUI) and within template files using the API. In the backend, all extra attributes for each menu item could be entered in one text box (each item having its own text box for this similar to CSS classes) in comma-separated key=value pairs, e.g.

role=button, onclick=return false, 

In the frontend (template file) such extra attributes would be added universally  by passing them as options, e.g.

$options = array (
          'wrapper_list_type' => 'ul',// ul, ol, nav, div, etc.
	  'wrapper_list_type_attributes' => 'role=menu',// comma-separated key=value pairs
	  'list_type' => 'li',
	  'list_type_attributes' => 'role=button, onclick=return false',// comma-separated key=value pairs
	  'submenu_attributes' => 'role=banner',// applied to submenu wrapper element; comma-separated key=value pairs
);

As per my example, the extra attributes would be applied to all elements specified in *_type + submenu (usually inner <ul>). By default these will only be applied if specified by developer/designer.

The differences between specifying attributes in the backend vs frontend (API)

  • Finer-grained control in the backend; apply extra attributes selectively (only on required menu items)
  • Universal attributes application only possible in the frontend
  • Application of attributes to menu and submenu wrappers only possible in the frontend

What do you guys think? Would this work for you?

Edited by kongondo

Share this post


Link to post
Share on other sites

Hi,

i'm starting my first real project with PW (coming from Contao and a little bit of WordPress). I wanna use UIKit as CSS framework and right now i'm trying to setup the navigation. I wanna use the Menu Builder and everything is fine, except one "problem": 

For a dropdown in the navigation bar the submenu ul has to wrapped in an extra div. Something like this:

<nav class="uk-navbar">
	<ul class="uk-navbar-nav">
	    <li class="uk-active"><a href="">Active</a></li>
	    <li><a href="">Item</a></li>
	    <li class="uk-parent" data-uk-dropdown="" aria-haspopup="true" aria-expanded="false">
	        <a href="">Parent</a>

	        <div class="uk-dropdown uk-dropdown-navbar uk-dropdown-bottom">
	            <ul class="uk-nav uk-nav-navbar">
	                <li><a href="#">Item</a></li>
	                <li><a href="#">Another item</a></li>
	                <li class="uk-nav-header">Header</li>
	                <li><a href="#">Item</a></li>
	                <li><a href="#">Another item</a></li>
	                <li class="uk-nav-divider"></li>
	                <li><a href="#">Separated item</a></li>
	            </ul>
	        </div>

	    </li>
	</ul>
</nav>

Is this possible with the module or do i have to write another solution? And how could i add the attributes (data-uk-dropdown)? 

Mario

Edited by kongondo
Moved your topic to Menu Builder's support forum

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 FireWire
      Hello community!

      I want to share a new module I've been working on that I think could be a big boost for multi-language ProcessWire sites.

      Some background, I was looking for a way for our company website to be efficiently translated as working with human translators was pretty laborious and a lack of updating content created a divergence between languages. I, and several other devs here, have talked about translation integrations and have recognized the power that DeepL has. DeepL is an AI deep learning powered service that delivers translation quality beyond any automated service available. After access to the API was opened up to the US, I built Fluency, a DeepL translation integration for ProcessWire.
      Fluency brings automated translation to every multi-language field in the admin, and also provides a translation tool allowing the user to translate their text to any language without it being inside a template's field. With Fluency you can:
      Translate any plain textarea or text input Translate any CKEditor content (yes, with markup) Translate page names for fully localized URLs on every page Translate your in-template translation function wrapped strings Translate modules DeepL offers translations to the following languages: English (US), English (UK), German, French, Spanish, Portuguese (EU), Portuguese (Brazil, Italian, Dutch, Polish, Russian, Japanese, Chinese (Simplified)
      Installation and usage is completely plug and play. Whether you're building a new multi-language site, need to update a site to multi-language, or simply want to stop manually translating a site and make any language a one-click deal, it could not be easier to do it. Fluency works by having you match the languages configured in ProcessWIre to DeepL's. You can have your site translating to any or all of the languages DeepL translates to in minutes (quite literally).
      Let's break out the screenshots...
      When the default language tab is shown, a message is displayed to let users know that translation is available. Clicking on each tab shows a link that says "Translate from English". Clicking it shows an animated overlay with the word "Translating..." cycling through each language and a light gradient shift. Have a CKEditor field? All good. Fluency will translated it and use DeepL's ability to translate text within HTML tags. CKEditor fields can be translated as easily and accurately as text/textarea fields.

      Repeaters and AJAX created fields also have translation enabled thanks to a JavaScript MutationObserver that searches for multi-language fields and adds translation as they're inserted into the DOM. If there's a multi-language field on the page, it will have translation added.

      Same goes for image description fields. Multi-language SEO friendly images are good to go.

      Creating a new page from one of your templates? Translate your title, and also translate your page name for native language URLs. (Not available for Russian, Chinese, or Japanese languages due to URL limitations). These can be changed in the "Settings" tab for any page as well so whether you're translating new pages or existing pages, you control the URLs everywhere.

      Language configuration pages are no different. Translate the names of your languages and search for both Site Translation Files (including all of your modules)

      Translate all of the static text in your templates as well. Notice that the placeholders are retained. DeepL is pretty good at recognizing and keeping non-translatable strings like that. If it is changed, it's easy to fix manually.

      Fluency adds a "Translate" item to the CMS header. When clicked this opens up a modal with a full translation tool that lets the user translate any language to any language. No need to leave the admin if you need to translate content from a secondary language back to the default ProcessWire language. There is also a button to get the current API usage statistics. DeepL account owners can set billing limitations via character count to control costs. This may help larger sites or sites being retrofitted keep an eye on their usage. This tool is available for all users with the page-edit permission.

      It couldn't be easier to add Fluency to your new or existing website. Simply add your API key and you're shown what languages are currently available for translation from/to as provided by DeepL. This list and all configuration options are taken live from the API so when DeepL releases new languages you can add them to your site without any work. No module updates, just an easy configuration. Just match the language you configured in ProcessWire to the DeepL language you want it to be associated with and you're done. Fluency also allows you to create a list of words/phrases that will not be translated which can prevent items such as brands and company names from being translated when they shouldn't

       
      Limitations:
      No "translate page" - Translating multiple fields can be done by clicking multiple translation links on multiple fields at once but engineering a "one click page translate" is not feasible from a user experience standpoint. The time it takes to translate one field can be a second or two, but cumulatively that may take much longer (CKEditor fields are slower than plain text fields). There may be a workaround in the future but it isn't currently on the roadmap. No "translate site" - Same thing goes for translating an entire website at once. It would be great, but it would be a very intense process and take a very (very) long time. There may be a workaround in the future but it isn't on the roadmap. No current support for Inline CKEditor fields - Handling for CKEditor on-demand hasn't been implemented yet, this is planned for a future release though and can be done. I just forgot about it because I've never really used that feature personally.. Alpha release - This module is in alpha. Releases should be stable and usable, but there may be edge case issues. Test the module thoroughly and please report any bugs via a Gitlab issue on the repository or respond here. Please note that the browser plugin for Grammarly conflicts with Fluency (as it does with many web applications). To address this issue it is recommended that you disable Grammarly when using Fluency, or open the admin to edit pages in a private window where Grammarly may not be loaded. This is an issue that may not have a resolution as creating a workaround may not be possible. If you have insight as to how this may be solved please visit the Gitlab page and file a bugfix ticket.
      Requirements:
      ProcessWire  3.0+ UIKit Admin Theme That's Fluency in a nutshell. A core effort in this module is to create it so that there is nothing DeepL related hard-coded in that would require updating it when DeepL offers new languages. I would like this to be a future-friendly module that doesn't require developer work to keep it up-to-date.
      It's Free
      This is my first real module and I want to give it back to the community as thanks. This is the best CMS I've worked with (thank you Ryan & contributors) and a great community (thank you dear reader). The only cost to use this is a subscription fee for the DeepL Pro API. Find out more and sign up here.
      Download & Feedback
      Download the latest version here
      https://gitlab.com/SkyLundy/fluency-processwire/-/archive/master/fluency-processwire-master.zip
      Gitlab repository:
      https://gitlab.com/SkyLundy/fluency-processwire
      File issues and feature requests here (your feedback and testing is greatly appreciated):
      https://gitlab.com/SkyLundy/fluency-processwire/-/issues
       
      Thank you! ¡Gracias! Ich danke Ihnen! Merci! Obrigado! Grazie! Dank u wel! Dziękuję! Спасибо! ありがとうございます! 谢谢你!

    • By horst
      ---------------------------------------------------------------------------------------------------------------------------------
        when working with PW version 2.6+, please use Pim2, not Pim!
        read more here  on how to change from the older to the newer version in existing sites
      ---------------------------------------------------------------------------------------------------------------------------------
      PageImage Manipulator, API for version 1 & 2

      The Page Image Manipulator is a module that let you in a first place do ImageManipulations with your PageImages. - And in a second place there is the possibility to let it work on any imagefile that exists in your servers filesystem, regardless if it is a 'known PW-image'.

      The Page Image Manipulator is a Toolbox for Users and Moduledevelopers. It is written to be as close to the Core ImageSizer as possible. Besides the GD-filterfunctions it contains resize, crop, canvas, rotate, flip, sharpen, unsharpMask and 3 watermark methods.



      How does it work?

      You can enter the ImageManipulator by calling the method pim2Load(). After that you can chain together how many actions in what ever order you like. If your manipulation is finished, you call pimSave() to write the memory Image into a diskfile. pimSave() returns the PageImage-Object of the new written file so we are able to further use any known PW-image property or method. This way it integrates best into the ProcessWire flow.

      The three examples above put out the same visual result: a grayscale image with a width of 240px. Only the filenames will slightly differ.

      You have to define a name-prefix that you pass with the pimLoad() method. If the file with that prefix already exists, all operations are skipped and only the desired PageImage-Object gets returned by pimSave(). If you want to force recreation of the file, you can pass as second param a boolean true: pim2Load('myPrefix', true).

      You may also want to get rid of all variations at once? Than you can call $pageimage->pim2Load('myPrefix')->removePimVariations()!

      A complete list of all methods and actions are at the end of this post.
       
      You may also visit the post with tips & examples for users and module developers.


      How to Install
      Download the module Place the module files in /site/modules/PageImageManipulator/ In your admin, click Modules > Check for new modules Click "install" for PageImageManipulator Done! There are no configuration settings needed, just install and use it. Download    (version 0.2.0)
      get it from the Modules Directory History of origins

      http://processwire.com/talk/topic/3278-core-imagemanipulation/


      ----------------------------------------------------------------------------------------------------------


      Page Image Manipulator - Methods

      * pimLoad  or  pim2Load, depends on the version you use!

      pimLoad($prefix, $param2=optional, $param3=optional)
      param 1: $prefix - (string) = mandatory! param 2: mixed, $forceRecreation or $options param 3: mixed, $forceRecreation or $options return: pim - (class handle) $options - (array) default is empty, see the next method for a list of valid options! $forceRecreation - (bool) default is false It check if the desired image variation exists, if not or if forceRecreation is set to true, it prepares all settings to get ready for image manipulation
      -------------------------------------------------------------------

      * setOptions

      setOptions(array $options)
      param: $options - (array) default is empty return: pim - (class handle) Takes an array with any number valid options / properties and set them by replacing the class-defaults and / or the global config defaults optionally set in the site/config.php under imageSizerOptions or imageManipulatorOptions.

      valid options are:
      quality = 1 - 100 (integer) upscaling = true | false (boolean) cropping = true | false (boolean) autoRotation =true | false (boolean) sharpening = 'none' | 'soft' | 'medium' | 'strong' (string) bgcolor = (array) css rgb or css rgba, first three values are integer 0-255 and optional 4 value is float 0-1, - default is array(255,255,255,0) thumbnailColorizeCustom = (array) rgb with values for colorize, integer -255 - 255 (this can be used to set a custom color when working together with Thumbnails-Module)
        outputFormat = 'gif' | 'jpg' | 'png' (Attention: outputFormat cannot be specified as global option in $config->imageManipulatorOptions!) set {singleOption} ($value)
      For every valid option there is also a single method that you can call, like setQuality(90), setUpscaling(false), etc.
      -------------------------------------------------------------------

      * pimSave

      pimSave()
      return: PageImage-Object If a new image is hold in memory, it saves the current content into a diskfile, according to the settings of filename, imagetype, targetFilename and outputFormat. Returns a PageImage-Object!
      -------------------------------------------------------------------

      * release

      release()
      return: void (nothing) if you, for what ever reason, first load image into memory but than do not save it, you should call release() to do the dishes! 😉 If you use pimSave() to leave the ImageManipulator, release() is called automatically.
      -------------------------------------------------------------------

      * getOptions

      getOptions()
      return: associative array with all final option values example:
      ["autoRotation"] bool(true) ["upscaling"] bool(false) ["cropping"] bool(true) ["quality"] int(90) ["sharpening"] string(6) "medium" ["targetFilename"] string(96) "/htdocs/site/assets/files/1124/pim_prefix_filename.jpg" ["outputFormat"] string(3) "jpg" get {singleOption} ()
      For every valid option there is also a single method that you can call, like getQuality(), getUpscaling(), etc. See method setOptions for a list of valid options!
      -------------------------------------------------------------------

      * getImageInfo

      getImageInfo()
      return: associative array with useful informations of source imagefile example:
      ["type"] string(3) "jpg" ["imageType"] int(2) ["mimetype"] string(10) "image/jpeg" ["width"] int(500) ["height"] int(331) ["landscape"] bool(true) ["ratio"] float(1.5105740181269) ["bits"] int(8) ["channels"] int(3) ["colspace"] string(9) "DeviceRGB" -------------------------------------------------------------------

      * getPimVariations

      getPimVariations()
      return: array of Pageimages Collect all pimVariations of this Pageimage as a Pageimages array of Pageimage objects. All variations created by the core ImageSizer are not included in the collection.
      -------------------------------------------------------------------

      * removePimVariations

      removePimVariations()
      return: pim - (class handle) Removes all image variations that was created using the PIM, all variations that are created by the core ImageSizer are left untouched!
      -------------------------------------------------------------------
      * width

      width($dst_width, $sharpen_mode=null)
      param: $dst_width - (integer) param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you prioritize the width, like with pageimage. Additionally, after resizing, an automatic sharpening can be done with one of the three modes.
      -------------------------------------------------------------------

      * height

      height($dst_height, $sharpen_mode=null)
      param: $dst_height - (integer) param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you prioritize the height, like with pageimage. Additionally, after resizing, an automatic sharpening can be done with one of the three modes.
      -------------------------------------------------------------------

      * resize

      resize($dst_width=0, $dst_height=0, $sharpen_mode=null)
      param: $dst_width - (integer) default is 0 param: $dst_height - (integer) default is 0 param: $auto_sharpen - (boolean) default is true was deleted with version 0.0.8, - sorry for breaking compatibility param: $sharpen_mode - (string) possible: 'none' | 'soft' | 'medium' | 'strong', default is 'soft' return: pim - (class handle) Is a call to resize where you have to set width and / or height, like with pageimage size(). Additionally, after resizing, an automatic sharpening can be done with one of the three modes.
      -------------------------------------------------------------------

      * stepResize

      stepResize($dst_width=0, $dst_height=0)
      param: $dst_width - (integer) default is 0 param: $dst_height - (integer) default is 0 return: pim - (class handle) this performs a resizing but with multiple little steps, each step followed by a soft sharpening. That way you can get better result of sharpened images.
      -------------------------------------------------------------------

      * sharpen

      sharpen($mode='soft')
      param: $mode - (string) possible values 'none' | 'soft'| 'medium'| 'strong' return: pim - (class handle) Applys sharpening to the current memory image. You can call it with one of the three predefined pattern, or you can pass an array with your own pattern.
      -------------------------------------------------------------------

      * unsharpMask

      unsharpMask($amount, $radius, $threshold)
      param: $amount - (integer) 0 - 500, default is 100 param: $radius - (float) 0.1 - 50, default is 0.5 param: $threshold - (integer) 0 - 255, default is 3 return: pim - (class handle) Applys sharpening to the current memory image like the equal named filter in photoshop.
      Credit for the used unsharp mask algorithm goes to Torstein Hønsi who has created the function back in 2003.
      -------------------------------------------------------------------

      * smooth

      smooth($level=127)
      param: $level - (integer) 1 - 255, default is 127 return: pim - (class handle) Smooth is the opposite of sharpen. You can define how strong it should be applied, 1 is low and 255 is strong.
      -------------------------------------------------------------------

      * blur

      blur()
      return: pim - (class handle) Blur is like smooth, but cannot called with a value. It seems to be similar like a result of smooth with a value greater than 200.
      -------------------------------------------------------------------

      * crop

      crop($pos_x, $pos_y, $width, $height)
      param: $pos_x - (integer) start position left param: $pos_y - (integer) start position top param: $width - (integer) horizontal length of desired image part param: $height - (integer) vertical length of desired image part return: pim - (class handle) This method cut out a part of the memory image.
      -------------------------------------------------------------------

      * canvas

      canvas($width, $height, $bgcolor, $position, $padding)
      param: $width = mixed, associative array with options or integer, - mandatory! param: $height = integer, - mandatory if $width is integer! param: $bgcolor = array with rgb or rgba, - default is array(255, 255, 255, 0) param: $position = one out of north, northwest, center, etc, - default is center param: $padding = integer as percent of canvas length, - default is 0 return: pim - (class handle) This method creates a canvas according to the given width and height and position the memory image onto it.
      You can pass an associative options array as the first and only param. With it you have to set width and height and optionally any other valid param. Or you have to set at least width and height as integers.
      Hint: If you want use transparency with rgba and your sourceImage isn't of type PNG, you have to define 'png' as outputFormat with your initially options array or, for example, like this: $image->pimLoad('prefix')->setOutputFormat('png')->canvas(300, 300, array(210,233,238,0.5), 'c', 5)->pimSave()
      -------------------------------------------------------------------

      * flip

      flip($vertical=false)
      param: $vertical - (boolean) default is false return: pim - (class handle) This flips the image horizontal by default. (mirroring)
      If the boolean param is set to true, it flips the image vertical instead.
      -------------------------------------------------------------------

      * rotate

      rotate($degree, $backgroundColor=127)
      param: $degree - (integer) valid is -360 0 360 param: $backgroundColor - (integer) valid is 0 - 255, default is 127 return: pim - (class handle) This rotates the image. Positive values for degree rotates clockwise, negative values counter clockwise. If you use other values than 90, 180, 270, the additional space gets filled with the defined background color.
      -------------------------------------------------------------------

      * brightness

      brightness($level)
      param: $level - (integer) -255 0 255 return: pim - (class handle) You can adjust brightness by defining a value between -255 and +255. Zero lets it unchanged, negative values results in darker images and positive values in lighter images.
      -------------------------------------------------------------------

      * contrast

      contrast($level)
      param: $level - (integer) -255 0 255 return: pim - (class handle) You can adjust contrast by defining a value between -255 and +255. Zero lets it unchanged, negative values results in lesser contrast and positive values in higher contrast.
      -------------------------------------------------------------------

      * grayscale

      grayscale()
      return: pim - (class handle) Turns an image into grayscale. Remove all colors.
      -------------------------------------------------------------------

      * sepia

      sepia()
      return: pim - (class handle) Turns the memory image into a colorized grayscale image with a predefined rgb-color that is known as "sepia".
      -------------------------------------------------------------------

      * colorize

      colorize($anyColor)
      param: $anyColor - (array) like css rgb or css rgba - but with values for rgb -255 - +255,  - value for alpha is float 0 - 1, 0 = transparent  1 = opaque return: pim - (class handle) Here you can adjust each of the RGB colors and optionally the alpha channel. Zero lets the channel unchanged whereas negative values results in lesser / darker parts of that channel and higher values in stronger saturisation of that channel.
      -------------------------------------------------------------------

      * negate

      negate()
      return: pim - (class handle) Turns an image into a "negative".
      -------------------------------------------------------------------

      * pixelate

      pixelate($blockSize=3)
      param: $blockSize - (integer) 1 - ??, default is 3 return: pim - (class handle) This apply the well known PixelLook to the memory image. It is stronger with higher values for blockSize.
      -------------------------------------------------------------------

      * emboss

      emboss()
      return: pim - (class handle) This apply the emboss effect to the memory image.
      -------------------------------------------------------------------

      * edgedetect

      edgedetect()
      return: pim - (class handle) This apply the edge-detect effect to the memory image.
      -------------------------------------------------------------------

      * getMemoryImage

      getMemoryImage()
      return: memoryimage - (GD-Resource) If you want apply something that isn't available with that class, you simply can check out the current memory image and apply your image - voodoo - stuff
      -------------------------------------------------------------------

      * setMemoryImage

      setMemoryImage($memoryImage)
      param: $memoryImage - (GD-Resource) return: pim - (class handle) If you are ready with your own image stuff, you can check in the memory image for further use with the class.
      -------------------------------------------------------------------

      * watermarkLogo

      watermarkLogo($pngAlphaImage, $position='center', $padding=2)
      param: $pngAlphaImage - mixed [systemfilepath or PageImageObject] to/from a PNG with transparency param: $position - (string) is one out of: N, E, S, W, C, NE, SE, SW, NW,
      - or: north, east, south, west, center, northeast, southeast, southwest, northwest
      default is 'center' param: $padding - (integer) 0 - 25, default is 5, padding to the borders in percent of the images length! return: pim - (class handle) You can pass a transparent image with its filename or as a PageImage to the method. If the watermark is bigger than the destination-image, it gets shrinked to fit into the targetimage. If it is a small watermark image you can define the position of it:
      NW - N - NE | | | W - C - E | | | SW - S - SE  
      The easiest and best way I have discovered to apply a big transparency watermark to an image is as follows:
      create a square transparent png image of e.g. 2000 x 2000 px, place your mark into the center with enough (percent) of space to the borders. You can see an example here! The $pngAlphaImage get centered and shrinked to fit into the memory image. No hassle with what width and / or height should I use?, how many space for the borders?, etc.
      -------------------------------------------------------------------

      * watermarkLogoTiled

      watermarkLogoTiled($pngAlphaImage)
      param: $pngAlphaImage - mixed [systemfilepath or PageImageObject] to/from a PNG with transparency return: pim - (class handle) Here you have to pass a tile png with transparency (e.g. something between 150-300 px?) to your bigger images. It got repeated all over the memory image starting at the top left corner.
      -------------------------------------------------------------------

      * watermarkText

      watermarkText($text, $size=10, $position='center', $padding=2, $opacity=50, $trueTypeFont=null)
      param: $text - (string) the text that you want to display on the image param: $size - (integer) 1 - 100, unit = points, good value seems to be around 10 to 15 param: $position - (string) is one out of: N, E, S, W, C, NE, SE, SW, NW,
      - or: north, east, south, west, center, northeast, southeast, southwest, northwest
      default is 'center' param: $padding - (integer) 0 - 25, default is 2, padding to the borders in percent of the images length! param: $opacity- (integer) 1 - 100, default is 50 param: $trueTypeFont - (string) systemfilepath to a TrueTypeFont, default is freesansbold.ttf (is GPL & comes with the module) return: pim - (class handle) Here you can display (dynamic) text with transparency over the memory image. You have to define your text, and optionally size, position, padding, opacity for it. And if you don't like the default font, freesansbold, you have to point to a TrueTypeFont-File of your choice.
      Please have a look to example output: http://processwire.com/talk/topic/4264-release-page-image-manipulator/page-2#entry41989
      -------------------------------------------------------------------





      PageImage Manipulator - Example Output


    • By d'Hinnisdaël
      Format Datetime fields as Carbon instances.
      You can find the latest release and the complete readme on Github.
      Installation
      composer require daun/datetime-carbon-format Usage
      All Datetime fields will now be formatted as Carbon instances instead of strings. Some examples:
      // $page->date is a Datetime field // Output format: j/n/Y echo $page->date; // 20/10/2020 echo $page->date->add('7 days'); // 27/10/2020 echo $page->date->format('l, F j'); // Monday, October 20 echo $page->date->year; // 2020 echo $page->date->diffForHumans(); // 28 minutes ago Frontend only
      The ProcessWire admin seems to expect datetime fields to be strings. This module will only return Carbon instances on frontend page views.
      Date output format
      When casting a Carbon instance to a string (usually when outputting the field in a template), the field's date output format will be respected.
      Links
      GitHub • Readme • Carbon docs
       
       
      PS. I remember reading about a Carbon module in a recent newsletter, but couldn't find it anywhere. Was that you, @bernhard?
×
×
  • Create New...