Leaderboard
Popular Content
Showing content with the highest reputation on 02/21/2016 in all areas
-
Just found http://intercoolerjs.org/ It does declarative ajax. Frontend wizardry without writing javascript. I'm impressed.7 points
-
@steveooo This question was already answered in your previous thread by quoting the README of ProcessWire 3, which is written by Ryan. It seems to me you're not really trusting the answers even of our best community members. You won't always get answers directly from Ryan, as he's quite aware and sensible about how much time he's able to invest into reading/writing here and most of it goes into VIP support of his pro modules and the really important topics like bugs or other critical topics.5 points
-
I can think of two possibilites to approach this: Reverse your logic and add the products in a page field to the option page (not really intuitive) Add a counter field to the option pages' template(s) and update the value through a hook on Pages::save for your product template (with a similar looping logic as in your code above). Then you can easily filter with $optionpages->children("usecount>0").4 points
-
hi, outsourcing the usage-info into a queryable field like bitpoet describes seems a very good idea. I think you can limit your fields query like this $fields = $template->fieldgroup->find('name^=_meta'); and save the substr check later on, maybe this also improves performance a bit by reducing the loop iterations. not 100% sure about that, maybe it needs to be $metaFields = $fields->find('name^=_meta'); and the looping over $metaFields, not $fields edit: ah, scrap that, I just see that you're using inputField($p) <-- (where does $p come from?) nonetheless, if you only want the fields whose name starts with '_meta', the above could still work, and the make a check if the current field is not in ignoreFields and then use inputField($p)…? cheers, Tom3 points
-
Still some work needed, but I just pushed the whole new version to GH and renamed it as MarkupCookieConsent. https://github.com/CanRau/MarkupCookieConsent/ (beta) It's now doing everything on it's own, means there are no externals involved. EDIT 1: Added screenshot to repo EDIT 2: Okay, I would say anything works (at least in Chrome on Mac) except the translatable config fields. Both themes are ready having each 2 available positions (top/bottom). Extended screenshots to show all 4 versions Added readme Added to module directory http://modules.processwire.com/modules/markup-cookie-consent/ EDIT 3: Lanaguage fields will work using this patch from Ryan, or you can just wait for the next PW devns release (probably on friday) Changelog 0.0.9 - Changed style injection, now prepends to first <link> in head makes it easier to add custom css tweaks without the need for !important because of the cascading order 0.1.1 - Fixed issue with cookie not being set, two strings wouldn't recognize translation, default cookie expire now 1 year, updated readme 0.1.2 - Added minified CSS & JS 0.1.3 - don't remember what changed in this version 0.1.4 - cookie bar now fully translatable, added devns branch which is meant to be used with PW 3.x devns as it adds namespaces 0.1.5 - fixed issue on single language installations Still have to test some things. For example, you can now select a page from your tree as policy page using InputfieldPageListSelect instead of entering the url, so now the link should work with multiple languages, too. Though I haven't exactly tested it yet! The language fields draw my attention. They look nice but only default language is saving at the moment. So this is how I build the config fields using MarkupCookieConsent.config.php file I kept only settings for one field.. public function getDefaults() { return array( 'messageText' => __("This website uses cookies to ensure you get the best experience on our website"), ); } public function __construct() { $this->add(array( array( 'type' => 'text', 'name' => 'messageText', 'label' => __('The message shown by the plugin'), 'useLanguages' => true, 'columnWidth' => 70 ) ) ); }); I'm not sure if/how I need to define default values for languages, too? I checked some other modules from Ryan but there he still uses the config field building ways getConfigInputfields() for example, so those are not really applicable, are they? So visually everything looks good, even when inspecting the fields the field names seem to be alright.. Or is this approach not yet multi lang capable? Everything else should work already. Ah except for the Default settings button at the bottom. It's more like to-do list for myself ;-) Ah and regarding "dependencies". When "Enable Ajax" checked, the form will be submitting using ajax (magic! haha), anyway..just to let you know it's using plain vanilla js so no jquery or anything else needed. Although it should work well, it's only tested in newest Chrome on Mac and the script is not handling errors. It's actually removing the cookie information right after the click and then making the request. So worst case would be, considering any error, the message popping up again even so the user thinks he already agreed... I figured it's probably not the kind of module which many will use, cause when you're a little into PW you now how to easily include such an information yourself. But for me it's especially practicing PHP.. So I would really love to get some hint on the language fields Side note: For everyone interested in disabling cookies at all to avoid every possible need for this plugin checkout out this blog post from Ryan http://processwire.com/blog/posts/multi-instance-pw3/#more-session-control2 points
-
Hi there, I'm currently starting out with some already quite big projects in cooperation with a partner agency in Munich. There are different scopes of work from rather simple-in-structure content websites to a quite complex SaaS webapp in the pipeline. Therefore I'm looking for possible partnerships with at least one freelancer to assist in these projects, possibly as long-term collaboration. Some proximity to our office in munich would be preferable, but is not required, as is knowledge of the german language. Please drop me a line on the forum if you're interested, so we can get into the details. Greetings, Benjamin2 points
-
The latest version adds a new experimental "Variables" panel (thanks to a request by @matjazp). This will show you the names and values of all non-ProcessWire variables available to the template of the current page - these are the variables you have defined in your template files and any "includes". It is disabled by default so you need to turn it on in the config settings. It is only available for PW 3.x and currently only works on compiled templates (although I am looking to get it working on PW 2 / non-compiled templates). It also only works after a template file has changed for the first time after this module is installed/updated. Please let me know if you have any problems with this feature - if you decide to enable it. This latest version also includes an enhanced PW panel - several additions/tweaks, but the most notable is the "Field Values" section which lists all Page fields and their values for the current page:2 points
-
Your right BernhardB! Got a little stuck with the code, so making screenshot and readme felt a little wrong..but it would make the post a little more attractive I guess. Now we're having a little selfmade chocolate snack and afterwards I'm preparing something ;-) Thank you Pete, but it's actually the opposite (or your "rather than.." part ), means I want the module config fields to be translatable on the config screen. EDIT: couldn't let you guys wait any longer so I quickly added a screenshot to the repo. More is coming soon.2 points
-
Related to this? https://github.com/ryancramerdesign/ProcessWire/issues/16242 points
-
When you have an update between ProcessWire versions, be it 2.x or 3.x there are not usually changes like database changes that affect normal pages. What I will say after running into an error that had no message whatsoever last night with PW3.x is that if you're worried about it, don't use it yet. In my case I switched the /wire folder and index.PHP file back to 2.7.x and carried on with other ways of doing what I was trying to do. I simply didn't have the time on the project I'm working on to troubleshoot. As a general rule, if you're relying on things working perfectly and have limited time then only use final versions of any software. If you have a bit of time to work some issues out and want to use the latest then feel free to use 2.7 dev or 3.x dev (though 2.7 dev is going to be more reliable at the moment because less has changed overall in the core code than 3.x). EDIT: I will try and work out that blank error bug I had last night, but once client work is finished. I enjoy resolving issues, just can't spare the time sometimes when deadlines are looming.2 points
-
Displays countries and continents and their iso codes. The "value" for each country is the two-letter country code. As an added bonus, the country names are displayed in the language of the user (sorted by name ASC) if the appropriate translation was added. read more ...1 point
-
In the last few weeks I've notices some request (e.g. here and here) to be able to get pages based on if they are selected in page fields of other pages. I think adding a method for this would be a nice addition to ProcessWire, as it's often the case that the pages itself are options we just want to get, if they are used somewhere. Currently the task "Get all tags used by some blogposts" has to be done manually like this: $tags = $pages->find("template=tags"); foreach($tags as $tag){ // Filter unavailable if(! $pages->count("template=posts, tags=$tag") ) continue; // Do stuff with it } Now it would be nice to have something like this, where we don't need to have a selector for tags (this is done by the pagefield already). // Find all pages, which are selected in the "tags" field of the selected posts $available_tags = $pages->findSelectedPages("template=posts", "tags"); I'm not that big a MySQL guy, but I can imagine this not only improving readability, but also reducing database calls.1 point
-
This week it's a relatively focused blog post, largely in part to much focus going into the ProDrafts documentation today. Specifically, ProDrafts is now in pre-release! Here is today's post: https://processwire.com/blog/posts/prodrafts-now-available-in-pre-release/1 point
-
1 point
-
http://ukmoths.org.uk Hi, I launched this back in late 2015 but just decided to post it here. It's a complete rebuild in ProcessWire of a site that's been running and growing for at least 15 years in one form or another. The site aims to illustrate all of Britain's moths (not quite there yet!), and despite the obscure subject matter, gets quite a lot of traffic. Hence I've used ProCache to keep things snappy and I'm pleased with the performance. There are over 7000 photos on the site. I should say that the design is not mine, but a purchased template. It took a while to find a template that I thought could portray these under-appreciated creatures in a good light. The most challenging aspects were importing all the data and images from the old system, and getting aspects of the search to work in the way I wanted. The best part is that it's so much easier to add new content! Thanks for ProcessWire, and thanks Ryan and everyone else in the forums! Cheers, Ian.1 point
-
Yeah, it needs to be refreshed (the button, i.e.)... You can use JS for that. Which reminds me, This module comes with an empty InputfieldRuntimeMarkup.js...in which I foolishly state: ...as if those wouldn't be overwritten on the next upgrade, grrr! Anyway, I will either let the module check for and if found include an 'InputfieldRuntimeMarkupCustom.js', which won't get overwritten on upgrades, or simply, I will ship the module without a 'InputfieldRuntimeMarkup.js' (and without a 'InputfieldRuntimeMarkup.css' as well). In that case, PW will autoload those files if found and they'll never get overwritten. So, to your solution. Add the following to your 'InputfieldRuntimeMarkup.js': @note: I added an id="archives" to your button $(document).ready(function(){ $('button#archives').on('click', function(){ //refresh button (remove 'ui-state-active') (only needed for default theme) $(this).button().button('refresh'); }); }) The code could probably be optimized to only run if default admin theme is in use. Maybe could even be used inline but this is cleaner. Maybe there's better solutions as well. The blue (on Chrome) outline around the button can be removed using CSS.1 point
-
Thanks for the hints (especially FETCH_NUM), I got it working without the extra queries. I will do extensive testing tomorrow and report back1 point
-
1 point
-
Hey guys - I actually removed that popup link I was using - not because it didn't work great with RuntimeMarkup, but for other reasons - anyway, I don't have the code I used for it anymore. But, this works for me: $url = 'http://www.example.com'; $out = '<button data-href="'.$url.'" type="button" name="button" class="pw-modal pw-modal-large ui-button ui-widget ui-corner-all ui-state-default">'; $out .= '<span class="ui-button-text">Image Archive</span></button>'; return "<div class='pfabLink'>".$out."</div>";1 point
-
Erm... But your screenshot shows what I meant? The "rather than" bit I mentioned is translating the module instructions not the output message. Either way, it's all good, and would actually be something that could be added to other modules as well - nice work.1 point
-
There's really not much "fixed" db structure to change anyway. There are about 9 tables, which are installed by default and are not dynamically setup. They handle the data of templates/fields/pages (name, status, hierarchy; not field data) and modules and there's a cache table. These are very unlikely to change in a way to not be backwards compatible. Any other tables are created by fields you're creating in the backend or by some modules. So any changes in the database, which would not be backwards compatible are from fieldtypes or other features, which are explicitly stated as 3.0 only. If you're using those there might be no way back. For example the new repeater field is one of those changes, which didn't need database changes, but still the UI for hiding repeaters is only available in 3.0. So you shouldn't rely on that feature, even though there where no changes to the db, but rather on how the available fields are used. But I'm totally with diogo. I don't see much reason to use 3.0 if you're such concerned. There's essentially no benefit if you're not using new features beyond maybe helping Ryan with reporting issues.1 point
-
I guess your problem with the sentence in the readme is the word should. Ryan was already explicit in saying that he believes that the devns branch is safe for new projects, even the download button in the site states that: "The newest 3.x dev version, great for testing, new projects or development." Honestly, if these aren't enough for you, maybe you should play safe and stick to the stable branch.1 point
-
The page has image field's thumbnail images which use modal and have those "pw-modal" classes and work just fine, so any necessary js and css are in place already. I'd seen that Adrian comment so I know it can be done. I'm new to jqueryUI so I don't understand the handling of the click event and at what point it does something (return false?) to stop the browser from processing the link as a link and going off to another page. There must be some condition which isn't being met. Could it be a matter of what the A tag is wrapped in? Answer: Don't use an A tag! Seems simple enough. Just do it all with the button, putting the url in a "data-href" attribute on the button. It's working now. Drifting off topic but any tips on how best to generate the boilerplate page markup for this iframe so that admin theme styling for an AdminDataTable works. I'm about halfway there.1 point
-
It is literally just for having a draft of an existing page's content in the admin - not a whole new layout/structure etc. If you are looking to build a new version of your site, best to copy your existing site locally or to a dev folder and work on it there before replacing the live site.1 point
-
I think your language question is around sites displayed in multiple languages (multi language fields etc) rather than translating the module itself into other languages? If so then that is a little tricky I guess - you'd need to iterate the languages and store a message for each language - this code may help: https://processwire.com/talk/topic/4383-how-to-set-language-active-via-api/?p=42956 Please feel free to submit it to the modules directory as it is though - it'll give it better visibility and possibly more feedback1 point
-
Hi can, Thank you for the module. It would be great to have a description of what the module does or a screenshot1 point
-
I submitted the profile of our agency (incognito.ms, 14 employees, 10 of them proudly working with PW) some weeks ago. I wonder if agencies are allowed/wanted to be part of the directory?1 point
-
You can't use a wildcard in Access-Control-Allow-Origin if you want to do XHR. A simple workaround would be to return the value of the Origin request header instead of the wildcard.1 point
-
You need to allow credentials for cross domain requests for ajax calls in the mobile framework you use. For regular xhr objects this just means setting xhr.withCredentials = true; but depending on the library, this may have to be done in a less direct way (like in beforeSend in jquery where you have access to the xhr object).1 point
-
Is it namespaced PW? (3.05) If so, try ProcessWire\wireRenderFile...1 point
-
They don't have to be configured as hidden/unpublished. It all depends on your use case. You may want to show them (i.e.. Year, Model, etc) as menu sub-dividers for instance. Other than hiding them, If you don't want them to show up in menus, you could also remove them from the returned PageArray prior to outputting your menu.1 point
-
Maybe the ideas presented here The Wire Render Pattern by @cclsource ould help you decide?1 point
-
By default, the "Forgot Password" module is not turned on in v2.1. My thought was that lack of such a function is technically more secure (on any site or CMS). Why? Because having such a function active means your password is only as secure as your email (*though see note at end of this message). So I thought we'd start things out as secure as possible and let people adjust it according to their own need. But I'm rethinking that decision, and may change it to be 'on' by default. If you don't already have that "Forgot Password" module installed, it is relatively easy to reset your password with the API. Lets say that you lost the password for your account named 'admin' and you wanted to reset it. Paste this code into any one of your templates (like /site/templates/home.php in the default profile, for example): <?php $admin = $users->get('admin'); $admin->setOutputFormatting(false); $admin->pass = 'yo12345'; // put in your new password $admin->save(); …or if it's easier for you to copy/paste everything on one line, here's the same thing as above on one line: <?php $users->get("admin")->setOutputFormatting(false)->set('pass', 'yo12345')->save(); Replace "yo12345" with the new password you want and save the template. Then view a page using that template (like the homepage, in our example). The password for that account has now been reset, and now you are ready to login. Don't forgot to now remove that snippet of code from the template! Otherwise your password will get reset every time the page is viewed. Once logged in, here's how to install the Forgot Password capability: 1. Click to the "Modules" tab. 2. Scroll down to the "Process" modules. 3. Click "Install" for the "Forgot Password" module. That's all there is to it. You will now see a "Forgot Password" link on your login page. *ProcessWire's "Forgot Password" function is actually a little more secure than what you see in most other CMSs. Not only do you have to have the confidential link in the email, but the link expires in a matter of minutes, and PW will only accept password changes from the browser session that initiated the request. So an attacker would have to initiate the password change request and have access to your email at the same time, making it a lot harder for a man-in-the-middle snooping on your email.1 point
-
Before posting, it's worth noting there is an existing section on Security relating to ProcessWire in the Docs section of this website: http://processwire.com/docs/security/ It contains several sub-pages that are worth a read as they offer code examples where appropriate and pointers for general security beyond ProcessWire.1 point
-
Sounds interesting. Here's one way you can do it: $table = $fields->get('your_page_field')->getTable(); $query = $database->query("SELECT data FROM $table GROUP BY data"); $ids = $query->fetchAll(PDO::FETCH_COLUMN); $items = $pages->getById($ids); // $items is a PageArray echo $items->implode("\n", "<a href='{url}'>{title}</a>"); If we were to add this to the API, I think I'd want to make it accessible from a regular find() selector, rather than as a separate findSelectedPages method. That way it could be used with things like InputfieldSelector. Perhaps something like this: $pages->find("your_page_field=:selected"); ...where ":selected" is a keyword is would recognize to execute this behavior.1 point
-
Hi everybody, First of all: Thanks to everybody for keeping the community alive. Every time I search for something in the forum I find the solution. Great work! I wanted to share a small module with you / my first one. I use it in order to switch the user language on page load. Processwire GeoInfo GeoInfo is a small module that Implements Geoplugin PHP web service. Please donate to "geoplugin.com" in order to keep the service alive. The Module ads two methods to retrieve data from the web service. $page->GeoInfoIP('IP ADDRESS'); you can enter the ip address manually. If left blank the server remote address will be used. The retrieved data is then stored to the active session, in order to limit the requests. The web service gives back following data. 'geoplugin_request' 'geoplugin_status' 'geoplugin_credit' 'geoplugin_city' 'geoplugin_region' 'geoplugin_areaCode' 'geoplugin_dmaCode' 'geoplugin_countryCode' 'geoplugin_countryName' 'geoplugin_continentCode' 'geoplugin_latitude' 'geoplugin_longitude' 'geoplugin_regionCode' 'geoplugin_regionName' 'geoplugin_currencyCode' 'geoplugin_currencySymbol' 'geoplugin_currencySymbol_UTF8' 'geoplugin_currencyConverter' for e.g. $page->GeoInfoIP('IP ADDRESS')->geoplugin_countryCode; will give back the country iso code. $page->GeoInfoLatLong('LAT', 'LONG'); Enter Latitude and Longitude in order to get following information: 'geoplugin_place' 'geoplugin_countryCode' 'geoplugin_region' 'geoplugin_regionAbbreviated' 'geoplugin_latitude' 'geoplugin_longitude' 'geoplugin_distanceMiles' 'geoplugin_distanceKilometers' for e.g. $page->GeoInfoLatLong('40.712784', '-74.005941'); will give back the city name "New York City". Todo store places in json file / check if place exists implement nearby "service" https://bitbucket.org/pmichaelis/processwire-geoinfo1 point
-
@mrkhan: There have been changes in ProcessPageEdit recently. The tabs need to be deleted manually. The code below works in 2.5.25 (dev). (don't know if thats the case for 2.5 and if so could you report this back) function removeSettings(HookEvent $event){ // check what role the user has, if not has editor role do nothing if(!wire("user")->hasRole("webmaster")) return; // $event->return being the inputfield wrapper $wrapper = $event->return; // set the inputfield wrapper to hidden $wrapper->collapsed = Inputfield::collapsedHidden; // Get the active Object (ProcessPageEdit) $process = $event->object; // Remove the Settings tab with the ID $process->removeTab('ProcessPageEditSettings'); // we're done }1 point
-
1 point
-
You could either just wrap the whole in a form, don't see any problems to do so even if the form fields are just in one tab. Have a separate process executeUpload() where you build the from.. and have a button with the href ="upload/". Or simply add a wrapper yourself (You can't just use InputfieldWrapper as a main wrapper with a ID, or I don't know how because it's not for such purposes) and use a main IntpufieldWrapper to render the wrappers... In a process module execute $wrapperMain = new InputfieldWrapper(); //...add all tab wrapper to the main. return "<div id='MyTabs'>" . $wrapperMain->render() . "</div>"; Then the js would be as simple as $(function(){ $t = $("#MyTabs"); $t.find("script").remove(); // to avoid double script execution $t.WireTabs({ items: $("#MyTabs > .Inputfields > .InputfieldWrapper"), id: 'ProcessExampleTabs' }); });1 point
-
If you use it on backend, I think so. The jSon is generated by ProcessWire self.1 point
-
Wished, that the JqueryWireTabs also listened to hashes in URLs, so that you could link to a certain tab. --- internal + external links to work with JqueryWireTabs tabs links like: http://pw.local/processwire/page/edit/?id=1#children or [click children](#children) in field descriptions can open tab directly now. p.s. view tab doesn't work. /** * Wire Tabs, jQuery plugin * * Developed by Ryan Cramer for ProcessWire * */ (function($) { $.fn.WireTabs = function(customOptions) { var options = { rememberTabs: config.JqueryWireTabs.rememberTabs, // -1 = no, 0 = only after submit, 1 = always cookieName: 'WireTabs', items: null, skipRememberTabIDs: [], id: '' }; var totalTabs = 0; $.extend(options, customOptions); return this.each(function(index) { var $tabList = $("<ul></ul>").addClass("WireTabs nav"); var $target = $(this); var lastTabID = ''; // ID attribute of last tab that was clicked function init() { if(!options.items) return; if(options.id.length) $tabList.attr('id', options.id); if(options.items.size() < 2) return; options.items.each(addTab); $target.prepend($tabList); var $form = $target; var $rememberTab = null; var cookieTab = getTabCookie(); var hash = capitalize(document.location.hash.replace("#","")); $(".description a[href^=#]").click(function(e){ e.preventDefault(); var thisHash = $(this).attr('href').replace("#",""); var thisHash = "#ProcessPageEdit" + capitalize(thisHash); $tabList.find("a[href$=" + thisHash + "]").click(); }); if(options.rememberTabs == 0) { $form.submit(function() { setTabCookie(lastTabID); return true; }); } if(cookieTab.length > 0 && options.rememberTabs > -1) $rememberTab = $tabList.find("a#_" + cookieTab); if($rememberTab && $rememberTab.size() > 0) { $rememberTab.click(); if(options.rememberTabs == 0) setTabCookie(''); // don't clear cookie when rememberTabs=1, so it continues } else if(hash.length) { $tabList.find("a[href$=" + hash + "]").click(); } else { $tabList.children("li:first").children("a").click(); } } function capitalize(s){ return s.charAt(0).toUpperCase() + s.slice(1); } function addTab() { totalTabs++; var $t = $(this); if(!$t.attr('id')) $t.attr('id', "WireTab" + totalTabs); var title = $t.attr('title') || $t.attr('id'); $t.removeAttr('title'); var href = $t.attr('id'); var $a = $("<a></a>") .attr('href', '#' + href) .attr('id', '_' + href) // ID equal to tab content ID, but preceded with underscore .html(title) .click(tabClick); $tabList.append($("<li></li>").append($a)); $target.prepend($t.hide()); } function tabClick() { var $oldTab = $($tabList.find("a.on").removeClass("on").attr('href')).hide(); var $newTab = $($(this).addClass('on').attr('href')).show(); var newTabID = $newTab.attr('id'); var oldTabID = $oldTab.attr('id'); // add a target classname equal to the ID of the selected tab // so there is opportunity for 3rd party CSS adjustments outside this plugin if(oldTabID) $target.removeClass($oldTab.attr('id')); $target.addClass(newTabID); if(options.rememberTabs > -1) { if(jQuery.inArray(newTabID, options.skipRememberTabIDs) != -1) newTabID = ''; if(options.rememberTabs == 1) setTabCookie(newTabID); lastTabID = newTabID; } return false; } function setTabCookie(value) { document.cookie = options.cookieName + '=' + escape(value); } function getTabCookie() { var regex = new RegExp('(?:^|\\s?' + options.cookieName + '=(.*?)(?:;|$)','i'); var match = document.cookie.match(regex); match = match ? match[1] : ''; return match; } init(); }) } })(jQuery);1 point
-
arjen is right. You would load a module with $modules->get("name") in templates when needed and have it ready. You could also have another Wire module that provides template variables and use the Process module only for backend interface. Then load the Wire module if you need it in there aswell. Either way, I think it's best to make process module not autoload and load module when needed in front-end, but it's up to you.1 point
-
Tabs is more easy then you espect: in YourModuleName.js: if($("#YourModuleName-tabs").size()) { $("#YourModuleName-tabs").WireTabs({ items: $("#div-or-form-with-this-id, #an-other-id"), id: 'tabs', rememberTabs: 1 }); } In your module: $this->modules->get('JqueryWireTabs'); $output = "<div id='{$this->className}-tabs'>"; $output .= " <div id='div-or-form-with-this-id'>bladibla</div>"; $output .= " <div id='an-other-id'>content blabla</div>"; $output .= "</div>";1 point