Leaderboard
Popular Content
Showing content with the highest reputation on 01/28/2017 in all areas
-
NOTE: This thread originally started in the Pub section of the forum. Since we moved it into the Plugin/Modules section I edited this post to meet the guidelines but also left the original content so that the replies can make sense. ProcessGraphQL ProcessGraphQL seamlessly integrates to your ProcessWire web app and allows you to serve the GraphQL api of your existing content. You don't need to apply changes to your content or it's structure. Just choose what you want to serve via GraphQL and your API is ready. Warning: The module supports PHP version >= 5.5 and ProcessWire version >= 3. Links: Zip Download Github Repo ScreenCast PW modules Page Please refer to the Readme to learn more about how to use the module. Original post starts here... Hi Everyone! I became very interested in this GraphQL thing lately and decided to learn a bit about it. And what is the better way of learning a new thing than making a ProcessWire module out of it! For those who are wondering what GraphQL is, in short, it is an alternative to REST. I couldn't find the thread but I remember that Ryan was not very happy with the REST and did not see much value in it. He offered his own AJAX API instead, but it doesn't seem to be supported much by him, and was never published to official modules directory. While ProcessWire's API is already amazing and allows you to quickly serve your content in any format with less than ten lines of code, I think it might be convenient to install a module and have JSON access to all of your content instantly. Especially this could be useful for developers that use ProcessWire as a framework instead of CMS. GraphQL is much more flexible than REST. In fact you can build queries in GraphQL with the same patterns you do with ProcessWire API. Ok, Ok. Enough talk. Here is what the module does after just installing it into skyscrapers profile. It supports filtering via ProcessWire selectors and complex fields like FieldtypeImage or FieldtypePage. See more demo here The module is ready to be used, but there are lots of things could be added to it. Like supporting any type of fields via third party modules, authentication, permissions on field level, optimization and so on. I would love to continue to develop it further if I would only know that there is an interest in it. It would be great to hear some feedback from you. I did not open a thread in modules section of the forum because I wanted to be sure there is interest in it first. You can install and learn about it more from it's repository. It should work with PHP >=5.5 and ProcessWire 3.x.x. The support for 2.x.x version is not planned yet. Please open an issue if you find bugs or you want some features added in issue tracker. Or you can share your experience with the module here in this thread.10 points
-
Consistent with the plans of introducing new site profiles this year, we’ve started work on the new site profile, and have the first version ready this week. This profile contains a blog component and uses the new Uikit 3 front-end framework: https://processwire.com/blog/posts/introducing-a-new-processwire-site-profile/8 points
-
A couple of comprehensive looking video tutorials in Polish by the folks at: https://xtras.pl/5 points
-
Translation files are located in the /site/assets/ directory, as files under the language page itself. If the ID of your target language page is 1010, the translation files should be under /site/assets/files/1010/ as separate .json files. As long as you copy / sync your assets directory to the production server, these should work as expected4 points
-
Sure! Only important thing is to do it! -- before you continue If $id is 0 and the first thing you do is: if(0 == $id) continue; nothing ever will happen.4 points
-
Yes, by using textdomains: https://processwire.com/api/multi-language-support/code-i18n/#technical-details3 points
-
By the way, in terms of security, this module follows the permission settings in ProcessWire. All it does is collects the templates that are viewable by the client via $user->hasPermission('page-view', $template); and for every request it makes sure to returns only those pages that have one of those templates. So, as long as user does not have permission to view the page, she won't be able to fetch it. I tried to make module reflect your existing settings as much as possible. It basically delegates everything possible to ProcessWire itself. That is so true. I personally thought GraphQL was new SQL.3 points
-
First of all, I think this looks great. I'm not entirely sure if I'll ever need something like this personally, but a module like this would no doubt be useful for some cases To my best understanding the main point Ryan was making about REST was that since it's easy to add new views (or whatever you choose to call them) for a ProcessWire site, a separate module doesn't make as much sense as it does for a system that doesn't provide similar flexibility. I've got some, albeit very limited, experience with the REST API in WP, and in their case it definitely makes a lot of sense. There's also the question of security: there may be cases where something is technically speaking public, but not accessible via your existing web site, and a "generic" REST API could result in some surprises there.. and, of course, if it's not read-only, that's a whole another thing to worry about. All that being said, I'm looking forward to seeing where this module goes. An easy-to-use plug-n-play GraphQL API sounds like a great thing to have in one's toolbox3 points
-
What you're describing is an issue about convenience and workflow in the admin. You have some pages that you want to view as a group with some kind of separation from the other pages. There are better ways to deal with this besides changing the page structure in the tree. The solution that I like best is Lister Pro - you pre-configure a Lister Pro instance for each group of related pages and then you or your editor can work with these pages without the distraction of other pages. And the interface is much more powerful than the page tree, especially when you start working with Actions and inline editing. For a no-cost solution you could: 1. Work with the core Find lister - it's pretty quick to filter by template or whatever to see your related pages. 2. Put together a simple Process module to live in the menu under "Pages". For example: class ProcessMyPages extends Process { public static function getModuleInfo() { return array( 'title' => 'My Pages', 'summary' => 'An example of a Process module that lists pages.', 'version' => 1, 'permission' => 'page-edit', 'page' => array( 'name' => 'my-pages', 'parent' => 'page', 'title' => 'My Pages' ), ); } public function execute(){ $table = $this->modules->get('MarkupAdminDataTable'); $table->setEncodeEntities(false); // headers $table->headerRow( array('Title', 'Modified', 'Created', 'Created by') ); // find the pages you want to list $my_pages = $this->pages->find("template=news_item"); foreach($my_pages as $page){ // create whatever columns you want $data = array( "<a href='{$this->config->urls->admin}page/edit/?id={$page->id}&modal=1' class='pw-modal'>{$page->title}</a>", date("j F Y", $page->modified), date("j F Y", $page->created), $page->createdUser->name, ); $table->row($data); } return $table->render(); } }3 points
-
I used the module BCE. It's a "work-around", but it's do-able (if you don't want too much languages). You import 1st language. Switch your admin to the other language and re-import with second language.3 points
-
@ethfun, You are missing some code. See a fuller example here (the original CMS Critic case study). What you need: Create your Hook. Have that run as early as possible, preferably in a file that is prepended to templates, for instance _init.php Enable URL segments in home.php. Note that this depends on how you want the URL to be rewritten. If you want to rewrite directly off root, then 'home' is where to go. For instance, if you want /blog/post/ to be rewritten to /post/, you will need to enable URL segments for the template file home.php since that is where ProcessWire will be looking. If you want /blog/posts/post-a/ to be rewritten to /blog/post-a/ you will have to enable URL segments on the template used by blog. The reason you are hitting 404s is that you haven't instructed ProcessWire to accept a URL Segment for that template, in your case, 'home'. Tell ProcessWire what to do when it hits that URL Segment enabled in #2 Mapping the above to code: In these examples, we want to rewrite /posts/post-a/ to /post-a/ 1# Hook: We have this code in _init.php. Any prepended file will do. //wire()->addHookBefore('Page::path', function($event) { @note: this or below, both work. $pages->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'post') {// template used by 'post-a' // ensure that pages with template 'post' live off the root rather than '/posts/' $event->replace = true; $event->return = "/$page->name/"; } }); 2#. Allow URL segments in the template: Do this in the URLs tab when editing the template. In our case, that is the template 'home'. 3#. Handling URL Segments: in home.php Note that here I haven't taken into account situations where we have more than 1 URL Segment. See CMS Critic case study link above for the full example, specifically under the sub-section /site/templates/home.php. // check if we have a URL Segment if(strlen($input->urlSegment1)) { // render the blog post named in urlSegment1 $name = $sanitizer->pageName($input->urlSegment1); $post = $pages->get("/posts/")->child("name=$name"); if($post->id) echo $post->render();// render the post using its template file else throw new Wire404Exception(); } Just in case you are not sure how to have ProcessWire automatically prepend a file like _init.php, you add this to your /site/config.php/ $config->prependTemplateFile = '_init.php'; It should work as expected, without 404s. ps: I haven't completely digested earlier posts but I am guessing this is what you were after.2 points
-
There are 6 10 38 episodes now, so I'll just link to the channel: https://www.youtube.com/channel/UCAC6bGszwXecqp1Nq2qn1Sg2 points
-
Good point. How about a simple button "Backup Now" to do it ? This is a thing in which I have to brainstorm; But definitely yes. I am looking for a good solution to name the packages files. Thanks here. It was stipulated on my first post, this will be the best part of the module This one is the hardest part to implement in my point of view so it will come in a second time but ASAP! What I mean by ASAP - I will finish to implement Amazon upload and the s/FTP as this last feature is required to jump to the installer one.2 points
-
2 points
-
I don't know much about GraphQL but I want to learn more, and your module looks like it will make it easy to get started with in PW. So definitely interested.2 points
-
Isn't it just a stylistic preference whether you increment the counter at the beginning or the end of your operations?2 points
-
Last update: June 2024 Current stable version: 1.5.4 Dev version: github dev-branch You can find the module on Github and in the modules directory : https://modules.processwire.com/modules/duplicator/ https://github.com/flydev-fr/Duplicator/archive/master.zip Screenshots / Features Dir and files exclusion CRON job Advanced settings Local and Cloud storage duplicator.mp41 point
-
ProcessWire Prism JS Syntax Highlighter A module to parse given HTML and syntax-highlight code elements using Prism JS Features Support for 120 languages Very lightweight, core weights 2KB minified gzipped. Customizable. Specify your own CSS, or use one of 8 default themes Hookable. Use hooks to specify your own custom CSS, and JS Plugin support. You can use all available plugins that come with Prism JS. Installation Add module to /site/modules/ and then install. Or go to Modules > Install > Add New and use any of the options provided to to install. Create a text/textarea field or use an existing one then pick Prism Code Highlighter from Details > Text Formatters. Protip: This module parses HTML markup, so it should come after HTML parsers such as Markdown textformatters. Add code elements within the field content with language-xxxx classes. Or pick a default language from configuration page if you are unable to specify the classes. Go to configuration page and select any plugins you want. To use some plugins, extra classes are required. See plugin documentation. Install these recommended modules for the best experience: Parsedown Extra module to render Markdown Extra into HTML. You can also set custom attributes for each element unlike vanilla Markdown. Customization Go to module configuration to specify: Auto inclusion of highlighters for parsed languages Default language for inline code elements or ones without language-xxxx classes. Ability to use minified/non-minified component and parser files Plugin options Theme options Custom JS and CSS for configuration / theming Ability to use hooks to specify custom CSS and JS Hooks Hook into TextformatterPrism::getCustomCss and TextformatterPrism::getCustomJs in your ready.php file and return an (array of) URLs as follows: // specify custom CSS wire()->addHookAfter('TextformatterPrism::getCustomCss', function (HookEvent $event) { $event->return = 'path/to/custom.css'; }); // Specify custom JS wire()->addHookAfter('TextformatterPrism::getCustomJs', function (HookEvent $event) { $event->return = ['path/to/custom.js', 'another/custom.js']; }); Screenshots Links https://github.com/abdusco/pw-prism-code-highlighter http://prismjs.com/ http://modules.processwire.com/modules/textformatter-prism/1 point
-
Hi, I'm toying with the idea of having a central place in PW's translation system for phrases and strings that are frequently used throughout several template files. The way I understand PWs translation system after reading the docs (http://processwire.com/api/multi-language-support/code-i18n/) is that everytime a __('translate-me') is used in a different .php file, the system will pull that 'translate-me' in a context of the .php file where it is used - so basically all translatable strings of _one_ file at a time are manageable via the (very cool) translation tool in PW's admin interface. So if for example I were to use __('Daytime phone number') in, lets say, the home.php as well as in the login.php and maybe a profile.php, I'd need to translate this three times, right? - A solution given in the docs is using the gettext context, and have this pointing to the first template file where the string was used first, so I only need to translate that template's strings and the other two will "see" their translation threre. So in my fabricated example: //home.php: __('Daytime phone number'); //login.php: __('Daytime phone number','/site/templates/home.php'); //profile.php: __('Daytime phone number','/site/templates/home.php'); So I only need to look for the translations of /site/templates/home.php in the translation tool and the other occurances of that string will be taken care for. This now brings me to the idea of creating a php file in, say, "/site/language/strings.php". So what I can now do (but what feels kind of hacky to me…?), I use all the frequently used strings of my several template files in this "strings.php" file, wrapped in their language functions like __('translate me'). in _init.php or maybe in config.php I store this file's path for the context: $i18lctx = '/site/templates/language/strings.php'; And now I can use the transalatable strings in several template/php files like this // in home.php, in archive.php etc __('Hello pilgrim',$i18lctx); In PWs admin interface I'll have all the strings in one place: the strings.php (?textdomain=site--templates--language--strings-php). Is this the right way to go about it or am I overlooking a basic fact (maybe like, dude, this is what the language packs are for)? Cheers, Tom1 point
-
That's a namespace problem - for some reason your template is not being compiled with the ProcessWire namespace. You can add the namespace... $comments = ProcessWire\FieldtypeComments::find("comments", $selector); ...but you shouldn't call the find() method statically anyway. The comment block for the deprecated findComments() explains how the find() method should be called: @deprecated Use $field->type->find($field, $selectorString) instead.1 point
-
I am not a big ML user, but I ended up with a Table field on the home page for sitewide translations. I use a 'name' field for the first column and a textAreaMultilanguage for the second column. This makes it really easy to add new strings and edit via the admin. I wrap the Table field in a fieldsetTab called "Sitewide Translations" to keep it separate from the main content.1 point
-
Yes, I am aware of field permissions, thank you for reminding. I have not added support for them yet. Though it is definitely in my todo list for this module.1 point
-
"How about a simple button "Backup Now" to do it ?" - Sure "I am looking for a good solution to name the packages files." - Normally I name them like this: 2017-01-28_13-55-17-anything-i-find-descriptive.zip Since you dubbed the module "Duplicator" you also implied that it will also be able to help in installing so I just wanted to make sure I got that right. Thanks again for the awesome work!1 point
-
Thanks for sharing the preview! A few questions: Will it be possible to do a manual backup without changing the module's Event trigger? It is not practical to change it back-and-forth just to do it manually once in a while. Or am I missing something? Is a timestamp like this possible: 2017-01-28_13-55-17 (year-month-day-hour-minute-second)? This can be alphabetically sorted so we also get the order arranged chronologically at the same time. Are you planning to implement any sort of "installer functionality" to simplify deployment/restore from the packages a little bit?1 point
-
I always though graphql would only be for qraph databases, but really this looks damn rad.1 point
-
All possible.....for the maps you can select what items you show on your map based on any field (for your specific turtle page): $items = $pages->find("marker_colour=red"); My code here: // LEAFLET MAP WITH BICYCLE ICONS $items = $pages->find("marker_icon=bicycle"); $map = wire('modules')->get('MarkupLeafletMap'); $options = array( 'markerFormatter' => function($page, $marker_options) { if ($page->marker_icon->title) { $marker_options['icon'] = $page->marker_icon->title; } if ($page->marker_colour->title) { $marker_options['markerColor'] = $page->marker_colour->title; } // And the icon colour. This is another text field. Colour values like White, Black or an RGB value are ok here. if ($page->marker_icon_colour->title) { $marker_options['iconColor'] = $page->marker_icon_colour->title; } return $marker_options; }, 'popupFormatter' => function($page) { $out[] = "<strong>$page->summary</strong>"; $out[] = "<a href=\"$page->url\" ><img src=\"{$page->summary_image->url}\" class=\"image fit\" /></a>"; $out[] = "<img src=\"{$page->summary_image->url}\" width=\"200\" height=\"200\" />"; // ** NB: Use escaped double quotes if HTML attributes needed ** return implode('<br/>', $out); } ); and for items from different categories (species for your big map): $items = $pages->find("marker_colour=red|green|blue"); Remember you can use: 'red', 'darkred', 'orange', 'green', 'darkgreen', 'blue', 'purple', 'darkpuple' & 'cadetblue' and any icons from your version of Awesome icons: http://fontawesome.io/icons/ Beneath each map you can summarise revevant posts for each region or each species with the page find function based on an "options field type": $features = $pages->find('species=loggerhead');1 point
-
You're right, but as I said. I did not tested it, and wrote this piece of code in a rush. Thanks for the addition. I think it is, most of the time I use it at the end of operations.1 point
-
hi adrian, nice that you take up my idea. i may have the code somewhere but i don't think it would be helpful. i did a manual search&replace in the wire folder that writes all calls to a file. i think you'll have a much better approach in some minutes looking forward to your solution. what i mentioned when playing with it was, that it gets quite messy very quickly. there are lots of hookable methods and on every pagesave or edit there are lots of recorded hooks. it would be necessary to build some UI around that. or additional informations, like a dump of the event object or the like. I'm not sure what the best solution would be for this. do you understand what i'm talking about?1 point
-
@Matt_P If you use the `getRecentMedia()` endpoint you should be able to access the location inside the foreach loop. Have a look at the instagram api, expand the response and there you'll see an example response containing all data which will be returned including a location entry. "location": { "latitude": 37.778720183610183, "longitude": -122.3962783813477, "id": "520640", "street_address": "", "name": "Le Truc" } Code example (not tested): <?php $feed = $modules->get('InstagramFeed')->getRecentMedia(); ?> <div class="instagram"> <?php foreach ($feed as $media): ?> // check if location is not `null` <?php if ($location = $media['location']): ?> Location: <?= $location['name'] ?> <?php endif; ?> <?php endforeach; ?> </div>1 point
-
@Harmen you must ensure that you count up the $id before continue. $id = -1; // set it -1, as we first count it up +1, (it will be 0 on its first check then!) foreach($sections as $item) { $id++; // count up +1 if($id == 0) continue; // skip the first child if($id == 1) { echo "<li class='yourclassforfirstitem'><a href='#section-$id'>$item->title</a></li>"; } else { echo "<li><a href='#section-$id'>$item->title</a></li>"; } }1 point
-
Nice. Those UIkit PHP functions will be a real bonus for anyone using the profile as the starting point for a website. I like the dummy text - what generator did you use?1 point
-
1 point
-
@Nukro - what you are after is certainly possible, but I am not sure the best way to make it handle everyone's need and not break current functionality for existing users because at the moment the module doesn't consider anything other than the page ID being somewhere in the URL. This allow ultimate flexibility in the URL, but obviously prevents detection of URL segments. I guess it could be a module config option to consider everything after the ID as segments that should be parsed. Anyway, for now I have attached a version that should do what you want. Please test thoroughly and let me know how it goes. If it's working fine at your end, I'll probably make the urlSegment detection optional and release it. ProcessRedirectIds.module1 point
-
Hi, I think this is not that difficult, you work already with an id which you can use now: You could add a if statement for the very first id in your foreach loop: $id = 0; // set it to zero foreach ($sections as $item) { if ($id == 0) continue else { echo "<li><a href='#section-$id'>$item->title</a></li>"; } $id ++; } NOTE: Haven't tested this As you want to skip the first element, which id is equal to 0, the first rendered <li> will have id 1, so if you add another if statement in your foreach loop for id ==1 you can filter that item out and the rest gets the normal tags. See code below: $id = 0; // set it to zero foreach ($sections as $item) { if ($id == 0) continue else { if ($id == 1){ echo "<li class='yourclassforfirstitem'><a href='#section-$id'>$item->title</a></li>"; } echo "<li><a href='#section-$id'>$item->title</a></li>"; } $id ++; } Haven't tested it so far, but I expect this works (maybe with some adjustments)1 point
-
Typically the way to do this is define $i=0; before the foreach loop and then at the end (just inside) do: $i++ This lets you check which iteration of the loop you are at, so if $i==0 then "continue;" Hope that helps - it's not a full code example, but hopefully it will help you to understand what is required.1 point
-
Just like $pages->get, $users->get returns a NullPage object if no match was found. Thus, you can check for that. I feel that doing it this way is better for readability (implicitly illustrating the difference between a new User object with no id and the result of a get call with no match), but that may just be a personal preference. $item = $users->get("email=example@processwire.com"); if($item instanceof NullPage) { // Not found } else { // Do something }1 point
-
1 point
-
Here is a tipp for you if you want to check for validation errors in inputfields before processing php code inside a Hook function. My goal was to run the code inside the Hook function only if there are no errors after processing the form in the backend. $pages->addHookBefore('saveReady', function($event) { $page = $event->arguments[0]; //count errors during input process $errors = $page->errors('all'); $errors = count($errors); if ($errors == 0) { ......//run your code } }); In this case I run a Hook before "saveReady" inside my ready.php. But I only want to run my php.code inside this Hook function if there are no errors in the form submission. So I need to check for errors in the form submission first. These 3 simple lines of code are necessary: $page = $event->arguments[0]; //count errors during input process $errors = $page->errors('all'); $errors = count($errors); The first step is to define the page variable $page; Second step is to get the error array Last step is to count the entries in the array to get the number of the errors Thats all! Afterwards you can use the number of errors in an if-statement to run the code only if there are no errors. Hope this will be helpful for someone.1 point
-
Hai @manlio, As far as I know this is not available at the moment. Currently the development for multi-language export and maybe import is ongoing for BatchChildEditor. I don't know if there is another way to import your multi-language csv into Processwire yet.1 point
-
1 point
-
@adrian, a while ago @bernhard came up with a cool idea for a "hook recorder": I'm wondering if you and he think this is something that might be integrated into Tracy Debugger. Now that there is the feature in Tracy (thanks @owzim) for parsing the hookable methods from the wire/site directories, I was thinking that there could be a feature that temporarily appends hooks for all hookable methods to /site/init.php or /site/ready.php. These "auto-hooks" would just do something simple like log/dump the method name as the hook fires. Of course this would be terrible for site performance - it's something you would only enable briefly during development to work out which hookable methods are firing as PW completes some task. What do you think?1 point
-
I just updated the Captain Hook cheatseheet to latest version 3.x now there's a master and dev version. Thanks to @owzim for providing a cli script to parse the repos automaticly and generate a array to use. It helps a lot to update. https://somatonic.github.io/Captain-Hook/index.html1 point
-
Hi ryan, is this topic outdated? Because all pages have an unpublished-Status (in 2016). Or do I miss the point here? Maybe this should be added in this thread.1 point
-
Quickly toggle your checkboxes with extra action buttons via AJAX. The module adds functionality to InputfieldCheckbox so you can toggle the checkbox fields in the extra action buttons intruduced in ProcessWire 2.6.5 via AJAX. Github Page Download Link Requirements This module works only for ProcessWire versions later than 2.6.5. How to Install 1. Copy the files to /site/modules/ProcessQuickToggle/ 2. In your admin, go to Modules > Refresh for new modules. 3. Click the "Install" button next to "Process Quick Toggle". Usage Go to any checkbox field you want to enable quick toggle feature for. Setup > Fields > my_checkbox_field. There in the Input tab you should see an Enable Quick Toggle field. After you check it you will see some fields that you can fill based on your needs. Then save the field. Now there should be an extra button for every page that has this field in the Pages tree. Features Supports template contexts. Supports core FontAwesome icons. Any kind of feedback is appreciated.1 point
-
Nope, but it's kinda easy. // module context $table = $this->modules->get("MarkupAdminDataTable"); $table->headerRow( ["Title", "ID", "Created"] ); foreach($this->pages->find("some=pages") as $page){ $data = array( // Values with a sting key are converter to a link: title => link $page->title => $this->config->urls->admin."page/edit/?id=".$page->id, $page->id, $page->created ); $table->row($data); } // $table->footerRow( $someArray ); echo $table->render();1 point