Leaderboard
Popular Content
Showing content with the highest reputation on 02/22/2017 in all areas
-
You can add a hook like this in your /site/init.php file: $this->wire()->addHookProperty('Page::courseData', null, function($event) { $sql = "SELECT * FROM ......"; $results = $this->wire('database')->query($sql); $event->return = $results->fetchAll(); }); And then in your template file you can call: $page->courseData You can also make of $event->object->name inside the hook to get the name of the page that the courseData property is called from so you can use that in your sql query. Of course you can get any other field from the page, like $event->object->myfieldname and use that in your query as well. Does that help?5 points
-
4 points
-
The problem occurs because the "user" template is a system template. See this comment in PageRender.php: Specifically setting prepend/append files in the Files tab of Edit Template doesn't work either - you might need to use an include for _init.php in user.php.3 points
-
Try $users instead - that should work with non-superusers. $event->users->find('roles=client');3 points
-
Rather than trying to hack the url for file_get_contents, you should use ->filename instead and then you can just do: file_get_contents($page->icon->filename);3 points
-
if you to make things easier, you can create an API sitting infront of the DB so from PW you simply call that API and based on the Data needed the API will fetch it from the relevant Database. However this might mean all call-centers having their own API so each can easily communicate because I doubt it would be easy to connect to their DB remotely directly.3 points
-
@adrian Thank you for the input. I have been able to get the query like mentioned in the post above yours. This is quite some time back now. In the meantime I've come to love Tracy Debugger. It is very easy to setup and makes debugging fun. Wouldn't want to miss it now3 points
-
I know this is ancient, but I wanted to note that if this worked in the past, it no longer works. I think I recently even saw reference to placing $config->debug = true in ready.php. None of these options work properly. If you want conditional debug mode, you need to use the debugif option: https://github.com/processwire/processwire/blob/35df716082b779de0e53a3fcf7996403c49c9f8a/wire/config.php#L56-L71 Keep in mind that setting it to true in a module or ready.php etc might make it look like it's working because the "Debug Mode Tools" link and icon will appear in the admin, but it will not output any errors/notices/warnings to the browser. Also, in the debug panel you'll notice that the "Database Queries", "Timers", and "Autoload" sections are not populated because they require debug mode to be on Also, of course, with Tracy enabled you don't really need debug mode on (or if you do have it on), it will take care of capturing any errors, and hiding them from users, anyway. The only thing you will be missing with it off, are those "Database Queries", "Timers", and "Autoload" sections.* Anyway, hope that helps to avoid any confusion for those who come here in the future. * This really wasn't meant to be a Tracy advert, but thought it was relevant because it solves the reason why you would want debug mode on only for superusers or the like.3 points
-
Sorry you had a bad experience with languages. A couple of things here: 1) What version of 2.7 are you running - make sure it is 2.7.3 2) 2.7 is pretty old now - you should be running 2.8 or 3.x - both have many fixes since 2.7 3 ) This should be an easy fix - just add a new field to the "pages" database table called "name1022" with these settings: varchar(128) ascii_general_ci null = yes Hope that helps!2 points
-
Hi VirtuallyCreative, instead of $homepage = $pages->get('/'); foreach($homepage->and($homepage->children) as $child) { you might try this $homepage = $pages->get("/"); $children = $homepage->children; $children->prepend($homepage); foreach($children as $child) { (Found in this thread.)2 points
-
You will likely want to add some sort of conditional inside that AddHookProperty to check the template of the page so you only run the query on appropriate pages. eg.: if($event->object->template == "template_that_needs_course_data") {2 points
-
"how to store it inside processwire" - I am not sure what you mean here - do you mean save the content to PW pages? You can query content from an external database and simply iterate over it and output in your template file. Here is the docs on $database: https://processwire.com/api/ref/database/ Here is a rough idea of what you can do. Obviously I am querying the PW "pages" table, but you can do this on any table in the database whether PW or not. You can see in the output that you can easily iterate through each row in the returned array and grab whatever array keys (db fields) you want.2 points
-
You can also have a look in my module http://modules.processwire.com/modules/fieldtype-select-ext-option/ This is a Select Fieldtype (single or multiple) which provides all the data of the selected table rows of any PW or Non-PW database table.2 points
-
You can easily make use of PW's $database to call an external database to populate content on a page - nothing fancy and no hooks required. It might help if you can provide more details of the data in these tables and how you want it displayed.2 points
-
This module provides a solution for keeping various site settings in one place (titles, slogans, api keys, emails, addresses, etc.). Features - Admin can create unlimited number of settings - Settings can be grouped - Admin can set setting label, notes, property name, field width and type - Settings can be of type text, checkbox, radios, select, email, url, integer How to use In module configuration create as many settings as needed. Customize their label, type, width and provide a name you want to use in a template files (property name). After that admin can set those settings on "General Settings" page in "Setup" section. Every time you wish to output eg. site name you can use $settings->site_name or wire('settings')->site_name or $settings->option2 to get value of 'Check it' as seen on the first screenshot. (Checked checkbox returns 1). You can change global name ($settings) to something else in module configuration. To get basic markup with all settings and their values use $settings->render(), usefull to check returning values (esp. select/radios - their values are sanitized as page names). Current limitation: -no way to change order of settings, -new settings can only be added at the bottom. Multilanguage To make fields multilanguage aware create a field with a same property name with '_languageName' appended. Example: Your site has two languages: default and french, create site_title and site_title_french fields. Put in a template $settings->site_title. If a user has set french language, this module output site_title_french, otherwise site_title. Please notice that render() function is not language aware. https://github.com/pmarki/ProcessGeneralSettings1 point
-
Well, you don't have to. I assumed this was for some feature on the Home page where the latest comments (sitewide) are displayed. I have something like this on one of my sites, although doing a custom render that links each comment to the page it appears on.1 point
-
Try this: $field = $fields->get('comments'); // assumes your comments field is named 'comments' $latest_comments = $field->type->find($field, "limit=5, sort=-created"); echo $latest_comments->render();1 point
-
@adrian thanks! That did the trick. I'll have to think of serving up a default avatar if no Gravatar exists and work that into the next version. Appreciate the help!1 point
-
The approach is fine, just a couple of minor problems, one being the if($img) conditional. The others are the "return" at the end of the first couple of checks that are exiting right there. Try this: <?php /** * Module for generating Gravatar URLs for ProcessWire users. * * Use it like this: * * Get URL only with all defaults: * $user->gravatar() * * Get image tag with different size: * $user->gravatar(array('img' => true, 's' => 200)); * */ class Gravatar extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Gravatar', 'version' => 1, 'summary' => 'Gravatar hook for users', 'singular' => true, 'autoload' => true, 'icon' => 'smile-o', ); } public function init() { $this->addHook('User::gravatar', $this, 'methodGravatar'); } public function methodGravatar($event) { $u = $event->object; if ( ! $u instanceof User) return; if ( ! $u->email) return; $params = ($event->arguments(0) ? $event->arguments(0) : array()); // Default options $defaults = array( 's' => 100, 'd' => 'retro', 'r' => 'g', 'img' => false, 'attrs' => array(), ); $opts = array_merge($defaults, $params); extract($opts); $url = '//www.gravatar.com/avatar/'; $url .= md5(strtolower(trim($u->email))); $url .= "?s=$s&d=$d&r=$r"; $url = '<img src="' . $url . '"'; foreach ($attrs as $key => $val ) { $url .= ' ' . $key . '="' . $val . '"'; } $url .= ' />'; $event->return = $url; } }1 point
-
Ok, I understand how that works and will try to implement this for the pages. Thanks you so much for your help.1 point
-
Actually I take that back - the function (and therefore the db query) won't be called unless you call $page->courseData so no need for this.1 point
-
Not really, what the addHookProperty does is to run that code and inject your data from the database into Page::courseData in TLDR it dynamically creates the courseData property in the Page class.1 point
-
Hrmm... I only have one text formatter on the body field. Textformatter OEmbed Can you try embedding https://soundcloud.com/thirdday/i-need-a-miracle-1 and see if you get an error? If I try the following on line 130 it gives the error because $test is NULL $test = $this->essence->extract("https://soundcloud.com/thirdday/i-need-a-miracle-1"); bd($test); However, if I try the following it works $test = $this->essence->extract("https://soundcloud.com/centricitymusic/jordan-feliz-the-river"); bd($test); This makes me think that it is something wrong with the essence php library and not the textformatter-oembed module. I started an issue at https://github.com/essence/essence/issues/127 It looks like textformatter-oembed is running 3.2.0. The latest essence library is at 3.3.0 maybe that will fix it?1 point
-
Yes I tested and it's about the same ratio except all a little lower. Like 20ms - 26ms Rendertime, TTFB 130ms - 170ms1 point
-
1) Yes my example block all files, I made this just for testing. You have to modify it for your needs. 2) Yes. It looks like it is accessed directly. A http header will be sent by WireHttp::sendFile() and output the content of the given file if the page is unpublished. If you don't set $config->pagefileSecure = true; all files will stay accessible even if the page is unpublished. If you hook in Page::isPublic() and return false the name of the files directory changes and your .htaccess will prevent accessing files under the secured path. If you make changings in your page and save it the files directory will be renamed again. Thats why this solution is a bit hacky. I wouldn't go forward in this direction. You should look for another solution.1 point
-
Adrian is right if calling external database you can use WireDatabasePDO, it's a wrapper around PDO and additional method,1 point
-
I feel like the "quiet" save option should also work for published. It works for created, but not modified or published. This SQL will do the trick though: $sql = "UPDATE `pages` SET `published` = '2015-01-01 12:30:00' WHERE `id` = '2101';"; $database->query($sql);1 point
-
1 point
-
Maybe the multilanguage name is not made available as a subfield. You could do this: $p = $pages->get("name{$user->language->id}=$urlSegment1"); // you should probably include a parent or template in this selector too $selector = "template=mysubcategory,pageref_category=$p"; As for the other problem, it looks like your screenshot shows the name of those pagefields is different for each language. So you need to search the right one for the language: pageref_categoria or pageref_categoria_en or pageref_categoria_fr.1 point
-
There's also this, which I found far more convenient to hide some files, because it doesn't pipe all other file requests through php as well: http://modules.processwire.com/modules/fieldtype-secure-file/1 point
-
i do agree - i think modules should probably prefix any global variables with something that won't risk being overwritten...1 point
-
yes, you can change that but most people probably won't realize why their listers all broke, so the default within the module code should be changed. not sure if it needs own namespace, because you just want to be able to get and set your global settings in a quick and easy way; plus i have module that then uses this module's settings basically wraps the settings for things like meta tags.. prior to this i always set my settings as part of $config which may be safer, because then you are 1 down from the top level... so another option would be to have this module use like $config->settings instead of being top level; since i have abstracted my calls to the vars through my intermediary module, the global name can change at any time without affecting my template output b/c my module looks for whatever the global name is and then refers to that in all of the output methods...1 point
-
To find a page using a multilanguage name you have to append the ID of the language to 'name' in your selector. Each multilanguage page name is stored separately like this. So suppose you had a page named 'three' in the default language, and added a French name for the page 'trois'. In a simplified example, if you wanted to get the page by name in the default language you would do... $p = $pages->get("name=three"); But if you wanted to get the page by name in French you would do... $p = $pages->get("name1234=trois"); ...where 1234 is the ID of the French language. So if you are working from the user's language you could do... $p = $pages->get("name{$user->language->id}=trois");1 point
-
Just a reminder that these are not design literal mockups, they are base styling and default looks. Think of them as functional wireframes.1 point
-
No sorry, I had to do a dirty workaround that meant looping thru records. Nothing elegant and it's a concern for me moving forward if I have very large datasets. I got into a real mess with urlSegments and then having to build the Url for both the languageSwitcher and also the Breadcrumbs in a _main.php. Honestly, Processwire is a really smart piece of code ( i'm very new to it ), but in all my experience coding, when things go this wrong, it's normally because I am not doing something correctly, or I have badly thought it through. I will return to it in a little while as I need to make head way on other parts of the site. If I find something that works better, then for sure, I'll let post it here. Good luck!1 point
-
Actually, it's pretty nice running your API call through the Tracy Console - save it as a snippet so you always have it on hand. This way you can easily see the results of the selector as well as the SQL query used to generate them. PS I think this is the thread that was mentioned regarding teppo's version: https://processwire.com/talk/topic/9408-is-there-a-way-to-convert-a-selector-in-sql-using-pw-engine/ although I think it's actually longer.1 point
-
Keep in mind that there a are other better ways to achieve this. You should read this tutorial made by @kongondo : Anyway, to continue with the repeater and to add tags to your aforisms you could create a new template "aforisms_tags" and a page in the PageTree called "Aforisms Tags", assign the template "aforisms_tags" to this new page; And add some children to this page: tag1, tag2, tag3... Then you create a new field of type PageReference , set the option Input Field Type to "AsmSelect" and set the option Parent to the new created page "Aforisms Tags". Then you add the field to your "aforisms_repeater". Illustration : There is the code : $aphorisms_list = ''; $tags = ''; foreach($page->aforisms_repeater as $aforism) { $aphorisms_list .= "<li>"; $aphorisms_list .= $aforism->aforisms_title; foreach ($aforism->aforisms_tags as $tag) { $tags .= "<span class='tag' style='margin: 3px; color: red;'>"; $tags .= $tag->title; $tags .= '</span>'; } $aphorisms_list .= "{$tags}</li>"; } $content .= "<ol>{$aphorisms_list}</ol>";1 point
-
1 point
-
Marc, it sounds like you've got a bottleneck somewhere. You mentioned a remote DB connection, and maybe there's something to to that. You also mentioned Windows (I'm in unix), and it's certainly possible there's something platform specific going on. Here are some things you can do to narrow in on where it might be. Edit your /index.php file and before the line that says this: $config = ProcessWire::buildConfig($rootPath); Add this: Debug::timer('pwboot'); Now edit your /site/templates/_init.php file (or whatever gets called first) and add this at the top, after the "namespace ProcessWire;" (old school and rough, but gets straight to the point): die('Boot time: ' . (Debug::timer('pwboot')*1000) . ' ms'); Now you can get a sense of how long it takes ProcessWire to boot, before it hands off the request to you. This should give you an indicator as to whether you need to look at the modules you've got installed, or whether you need to look at the API calls in your templates. Hit reload several times in your site (front-end) to get a sense of the average boot time. On my oldish Macbook Pro and PHP 7, running the site-default profile with no 3rd party modules installed, these are my average boot times: ProcessWire 3.0.52: 53 ms (opcache off) ProcessWire 2.7.3: 104 ms (opcache off) ProcessWire 3.0.52: 35 ms (opcache on) ProcessWire 2.7.3: 35 ms (opcache on) As you can see, without PHP caching the code, ProcessWire 3.x boots nearly twice as fast as ProcessWire 2.7 (at least in my environment). Interestingly, if PHP's cache is enabled, then the boot time is identical. But when Soma said above “ProcessWire is getting slower and slower each iteration”, this is a blanket statement that is the opposite of reality. ProcessWire is getting faster and more optimized with each version. What's real is that clearly something about the conditions present in his environment and your environment is reducing performance, and that needs to be narrowed in upon. So the next steps will be to determine if it's something about the server, something from a module, or something going on in the template file(s), like some specific API call that might be common among your installations. Now go to your Chrome dev tools, Network tab. Hit reload several times like you did before (same URL). Note the first request in your Network tab. Take this time and subtract the time you recorded above. This represents (roughly) the time required to load PHP before it gets to ProcessWire. With opcache off, my PHP takes about 100ms before it loads ProcessWire's /index.php file. If I enable opcache, then I'm seeing almost no overhead from PHP at all. Meaning, Chrome dev tools is showing 40ms or less. I'm guessing that your remote DB connection is going to mean your boot times are significantly higher than if it was local. So maybe you shouldn't be looking for the same boot times that I'm seeing here. But hopefully you can get a better idea of whether the times you are seeing are related to the boot process, or what happens after the boot process. If you are seeing it in the boot process, then uninstall all 3rd party modules and test again. Or go one-by-one until you can narrow in on which one it is. If still seeing a slow boot then we might need to start looking at potential Windows platform issues. If your boot times seem reasonable, then the next step is to start debugging in the template files. Let me know what you find and I can suggest the next steps.1 point
-
Alternatively you could provide methods in your module, which return the needed markup when called from manually created template files.1 point
-
I created a request issue of this: https://github.com/processwire/processwire-requests/issues/781 point
-
I concur that some kind of slow down is to be expected when complexity rises. Before touching template cache, markup cache or thinking about APC or Varnish though, the first step should IMHO always be to cache the raw PHP by using opcache or wincache (the latter should only be enabled after installing PW). Having said that, I can see a few specific things that might impact performance in 3.x: Namespaces. Yes, they don't impact hard, but any call to a global function in namespace context makes PHP look for an identically named function in the current namespace. It might be worth it to go through the code and qualify all global calls, like e.g. \explode() instead of explode(). I'll see if I can whip up a tool to do that. File system access / file compiler. Not much to do about directly it if you need it, besides faster disks. Memory footprint. More functionality, more properties, more memory, but should only be a real issue on slow or overloaded servers. Old PHP versions. Some PHP features needed a few release steps to reach optimal performance. It's always worth it to compare performance under e.g. 5.5 and 7.1. MySQL. Often, production systems using a distribution's default installation have performance schema enabled unnecessarily or are logging every tiny query to disk. Though this shouldn't impact in whole percentages unless the system's at its limits anyway.1 point
-
There is a dedicated "VIP support" subforum for questions relating to Form Builder. See this thread for limiting entries based on email address:1 point
-
I agree with Adrian, there's no point on doing this with PHP when you can do it easily with CSS. Besides, if someone loads the site on a small window, and then resizes the window, you'll have less content on a larger screen. Is your reason purely layout related, or are you trying to spare mobile users from loading content? That can also be fixed with JS, and some browsers won't even load images that are not displayed. In your code you're trying to load a PHP file with javascript. for what I see, either you have those files on the root of the site without PW code, or it won't work at all. Anyway, I strongly discourage you to load content through AJAX if only for templating purposes. Here's how you can do it with CSS: @media only screen and (max-device-width: 720px) { .articles-parent article:nth-child(n+6) { display: none; } } This would hide the last 6 posts when the screen is narrower than 720px.1 point
-
It's as complex as building such things on your own elsewhere. We have an easy pagination generating module, which just happens to lack an option to render just next/prev links instead of a full pagination. I'm sure Ryan could add those quite easily. Also may I suggest a more readable version of yours. Things are always easier to digest when they're not muddled with html tags. <?php $next = $prev = ''; $total_pages = ceil($pagedata->getTotal() / $limit); if($input->pageNum > $total_pages) // Optional; For page 11 of 10 throw new Wire404Exception(); if($total_pages > 1){ $base_url = rtrim($page->url . $input->urlSegmentsStr, '/') . '/'; if($input->pageNum == 2) $prev = $base_url; elseif($input->pageNum > 2) $prev = $base_url . $config->pageNumUrlPrefix . ($input->pageNum - 1); if($input->pageNum < $total_pages) $next = $base_url . $config->pageNumUrlPrefix . ($input->pageNum + 1); } ?> <?php if($next || $prev) : ?> <div class="pagination"> <?php if($prev): ?> <div class="prev-page"> <a rel="prev" href="<?= $prev ?>">Prev page</a> </div> <?php endif; if($next): ?> <div class="next-page"> <a rel="next" href="<?= $next ?>">Next page</a> </div> <?php endif; ?> </div> <?php endif; ?>1 point
-
Hi @zervis, you could try $pages->findMany("template=user"); or $pages->findMany("role=user"). I tested this with normal PW users and $pages->find(), but it should work with findMany, too. Another way could be: $pages->find("template=user", ["lazy" => true]) see here for options, but I didn't tested that.1 point
-
Have you tried to refresh module cache? I just had a problem where the whole admin menu wouldn't change language, after flushing the cache it works1 point
-
The whole process is not that difficult. Create a long random string and store in in the db. When a link is hit, check the db for that token and if found (and still valid?) login the user and delete the token from the db. The only real pain point could be the "create a random string" part depending on how secure the whole thing should be.1 point
-
I have the same issue with 2.5.10 dev even when I remove the old session files. I've just moved the site from my local environment to the live server and am getting the same error Unrecognized HTTP host: 'domain.me' - Please update your $config->httpHosts setting in... domain.me is just for illustration but you get the idea. This is my config $config->httpHosts = array('domain.me','www.domain.me' );1 point
-
I found the answer myself. In the Foundation Site Profile, $useMain is initially set to true in _init.php and checked in _main.php: /templates/_init.php (line 40) /* * Whether to include the _main.php markup file? For example, your template * file would set it to false when generating a page for sitemap.xml * or ajax output, in order to prevent display of the main <html> document. * */ $useMain = true; /templates/_main.php (line 14) // if any templates set $useMain to false, abort displaying this file // an example of when you'd want to do this would be XML sitemap or AJAX page. if(!$useMain) return;1 point