Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/05/2018 in all areas

  1. I stumbled across this on Github ... just breathtaking .... piece of history right there. A good place to brush up on your Assembly Language https://github.com/chrislgarry/Apollo-11 By the way, Margaret Hamilton who worked on the module is considered a programming genius. https://www.wired.com/2015/10/margaret-hamilton-nasa-apollo/
    7 points
  2. ProcessWire will make you want to be, and then in a fairly short space of time become a developer. I've been using ProcessWire for a year now, and whilst I still haven't published any modules like the very talented people on this forum, I've more than tripled my clients, can take an idea to a working prototype stage in less than a week and honestly enjoy every minute I spend interacting with PW. My previous background was purely as a web designer, bespoke designs but using various modules and essentially piecing sites together as many do. I also started with a personal project to get my head around PW, it was essentially a membership based database where users could add 'titles' to their collection and share them with others, produce stats etc. I never finished it because I moved onto client work but it functions perfectly and was a great, pressure-free basis for learning PW. I did a bit of maintenance this evening on an old clients WordPress site, and it's just a bloated, illogical mess and just being logged in feels like a security risk. The other option you may want to consider is Laravel, which I started learning after picking up ProcessWire, but with having the CMS out of the box (plus a ton of other time saving benefits) means there's no real reason to use Laravel over PW.
    4 points
  3. Hello Roych, First of all, I recommend a few things: Installing @adrian's TracyDebugger module. Makes development a lot easier, you can instantly spot issues like undefined variables and null objects, it also has support for one click online html validating and about a hundred more features to ease the "pain" I mean to help get more fun out of coding. Also, turning on $config->debug = true; in config.php is very helpful during development. Next, after a successful system or module upgrade you might want to delete files/directories beginning with a dot, in your case: /.wire-3.0.36 /.htaccess-3.0.36 /.index-3.0.36.php /site/modules/.MarkupSimpleNavigation I installed @tpr's AdminOnSteroids as it has very useful features to support development: in the Page Tree it can show the ID and templates of a page, it has a one click jump link to open template/field editor pages right from a page editor page (just hover over the lables and links appear in tooltips) so it made it easy to find my way around your template/field setup. Actually, it always makes it easy to find my way around MY OWN setups too! I also uninstalled the FrontendEditing module. Frontend editing is an advanced technique, it has its limitations and quirks, and most importantly since it injects code into your frontend it is best not to use it when learning PW. It just makes issues a little bit harder to track down. Back to your code. Things I could spot: PHP Notice: Undefined variable: title in .../site/templates/_prepend.php:6 which is: <?php echo $title; ?> and should be <?php echo $page->title; ?> First I cleaned up your code to get rid of issues of invalid html. TracyDebugger has a tool to one-click validate your html which helps a lot to pinpoint issues. Your HTML was broken, I found an unnecessary "</div>" and a "<" which were simply syntax errors. With broken HTML it might be impossible to generate a working JS portfolio. You get a collection of "portfolio-detail" templates, but in the page tree the following pages are created based on this template: children of Portfolio Kategorije children of Kategorije Which is not right when your selector is this: $portfolio_details = $pages->find('template=portfolio-detail, sort=-created'); because it collects unrelated pages. You need to add "parent=portfolio, " to get the specific pages: $portfolio_details = $pages->find('template=portfolio-detail, parent=portfolio, sort=-created'); Since your original template setup was problematic, I made changes: Changed template of page Kategorije from "portfolio-detail" to "categories" Changed template of pages Vizitke, Logo and Publications from "portfolio-detail" to "category" (I renamed Kategorije to category.) Note that it is best to stick to English when writing code and setting up names in the admin. You never know when you need to pass your code to someone not speaking your native language Similarly, when testing multilingual fields, if you put Slovenian in the English fields then you make it harder to follow your own setup, so I used English names for each "en input". The more things you do not put in the right pace the harder you find to make sense of your own site, even when "just testing things out". I did not touch the Family settings of categories/category templates but you should set them up like this: https://processwire.com/talk/topic/15842-200200200-field-texturltextarea-into-1-template/?do=findComment&comment=141413 I renamed the field category to categories, as it is a Page Reference field with ASM selects, so using plural is more appropriate. I removed the setting of "Select the template of the pages that are selectable. May be used instead of, or in addition to, the parent above.", because setting the parent to the Categories page is enough. Back to code changes: this loop is not needed: <?php //foreach ($cat_items as $item) : ?> $single->images->description->first was changed to $single->images->first->description normally I use <?= ?> when echoing single values but in that case it is not possible to temporary comment them out, so that is why I switched to <?php echo ?> It helps testing. Using title as a css class or id will not work as is can contain spaces and other special characters, you need to use the name property (Settings tab > Name in the admin): <a href="index.htm#" data-filter=".<?php echo $item->name ?>"> and in the portfolio loop, you need to output the related category name(s): <?php foreach ($portfolio_details as $single) : ?> <div class="portfolio-item <?php echo $single->categories->first->name ?> "> After making all these changes it works for me, I'm going to send my version to you in a PM soon. Note that you still have unrelated owl Carousel erros in your JS. Here is the content part of the code for anybody else who might find it useful as an example: All in all, I recommend using Tracy and AdminOnSteroids (AOS), always look for PHP errors and invalid HTML and fix them before you move forward. And always work by changing things one at a time and then test if the change really does what you want. Tracy is your best bet to do testing the fastest way possibe with ProcessWire
    4 points
  4. Hi Kevin! Welcome to the forums. Add the "currentLinkMarkup" to your array, like this: $results = $baustelle->children("limit=2"); $pagination = $results->renderPager(array( 'nextItemLabel' => "Next", 'previousItemLabel' => "Prev", 'listMarkup' => "<ul class='pagination mg-b-0'>{out}</ul>", 'itemMarkup' => "<li class='page-item {class}'>{out}</li>", 'linkMarkup' => "<a class='page-link' href='{url}'>{out}</a>", 'currentLinkMarkup' => "{out}", 'currentItemClass' => "active" )); echo $pagination;
    3 points
  5. Hi Sierra, It looks like you haven't disabled the 'automatic prepend/append' option for your template. Navigate to Setup->Templates->YourTemplate Go to the 'Files' tab and tick the two 'Disable automatic...' boxes. Does that fix it?
    3 points
  6. This community is so awesome and helpful. Gideon
    3 points
  7. Hi and welcome to the forum! Your approach is good and flexible, so that's a good start! To output the alerts on all pages in the front end, you have some options. I'll show 2 of them: 1 - Do the logic in the layout file that's shared by all pages In a default PW project, all pages can share a main layout file, usually _main.php. And on this file, you can output your Alerts pages' content, like so: //_main.php file <body> <?php $alerts = $pages->find('template=alerts'); // considering your template is called "alerts" foreach ($alerts as $a): ?> <div class="alert"> <h1><?= $a->title ?></h1> <h1><?= $a->body ?></h1> </div> <?php endforeach; ?> ... rest of file 2 - Using the render function to output the content of you ALERT template in all, so the logic (the foreach etc.) is done in that file, not in _main.php
    2 points
  8. The best thing with it are all the pull-requests happening for this piece of code, which won't probably be run anymore.
    2 points
  9. NOTE 2022: Better use URL hooks! https://processwire.com/blog/posts/pw-3.0.173/#introducing-url-path-hooks Hidden option ? // site/ready.php $wire->addHookBefore('Page::render', function($event) { $page = $event->object; if($page->template == ...) include(yourcodefile.php); // or any other condition }); // yourcodefile.php <?php namespace ProcessWire; if(!$this->config->ajax) return; // early exit // any other conditions // return json header('Content-Type: application/json'); die(json_encode($yourdata)); @Guy Incognito you might also be interested in this thread:
    2 points
  10. The issue that @Robin S was having has been fixed in the latest version - seems like I wasn't seeing it because I am running PHP 7.2, but didn't investigate that too thoroughly. Thanks again Robin for reporting this and for access to test and diagnose it!
    2 points
  11. Everything looks fine to me in v1.8.9, thanks everyone for the help. It was new to me that template level sort order takes only the parent page into account, I thought the child pages' templates are also involved somehow.
    2 points
  12. One of PW 3.010's major novelty was the introduction of Horst's new image resizing engine that uses ImageMagick. Now I understand that ImageMagick can convert images to Webp, the image format that Google says can reduce image size up to 34% compared to JPEG. Mozilla is apparently adding support to Firefox, and even the Safari team is playing with it, so it looks like Webp is soon going to be available in most major browsers. If Horst's module can be extended to add Webp conversion, that would be a great addition to PW's already very powerful image manipulation arsenal. I'm currently using the free ImageEngine Lite to serve Webp images to supporting browsers, and the results are impressive. I routinely get images that are between 25 and 60% smaller compared to JPEG, with the same visual quality. I would love to eliminate the need to rely on a third-party service though.
    1 point
  13. In this tutorial I will cover how to use clsource's REST Helper classes to create a RESTful API endpoint within a PW-powered site and how to connect to it from the outside world with a REST client. This is a quite lengthy tutorial. If you follow all along and make it through to the end, you should get both, a working REST API with ProcessWire and hopefully some more basic understanding how these APIs work. As always with PW, there are many ways you could do this. My way of implementing it and the code examples are loosely based on a real world project that I am working on. Also, this is the first tutorial I am writing, so please bear with me if my instructions and examples are not that clear to understand. And please let me know if something is missing or could be made more clear. The steps covered: create templates and pages in the PW backend to get an API endpoint (an URL where the API can be accessed at) copy and save the REST Helper classes to your site create a template file and write some logic to receive and process data through our endpoint and send data back to the REST client test the whole setup with a Browser REST Client Addon I will not go into fundamentals and technical details on how RESTful APis are supposed to work. I assume that you have already read up on that and have a basic understanding of the principles behind that technology. Some helpful resources to brush up your knowledge: https://en.wikipedia.org/wiki/Representational_state_transfer http://www.restapitutorial.com/lessons/whatisrest.html The complete pages.php template is attached to this post for copy/paste. Lets get started. 1. create templates and pages in the PW backend to get an API endpoint (an URL where the API can be accessed) First we need to create some templates and pages in the PW backend to make our REST API accessible from the outside world through an URL (API endpoint). In my example this URL will be: https://mysite.dev/api/pages/ Note the "https" part. While this is not mandatory, I strongly recommend having your API endpoint use the https protocol, for security reasons. Further down in step 3 we will use this URL to create new pages / update and get data of existing pages. Go to your PW test site admin and: create 2 new templates: one is called "api", the other one "pages". For a start, they both have only a title field assigned. Just create the templates. We will create the corresponding files later, when we need them. enable "allow URL segments" for the "pages" template. We will need this later to access data sent by the requests from the client. in the Files tab of the "pages" template check "Disable automatic append of file: _main.php" create a new page under the home page with title, name and template "api" and set it to hidden create a child page for the "api" page with title, name and template "pages" The pagetree should look somewhat like this: Ok, now we're all set up for creating our API endpoint. If you browse to https://mysite.dev/api/pages/ you will most likely get a 404 error or will be redirected to your home page as we do not have a template file yet for the "pages" template. We will add that later in step 3. 2. copy and save the REST Helper classes to your site I have the REST Helper class sitting in site/templates/inc/Rest.php and include it from there. You could save it in any other location within your site/templates folder. I forked clsource's original code to add basic HTTP authentication support. Click here to open my raw gist, copy the contents and save them to /site/templates/inc/Rest.php In the next step we will include this file to make the classes "Rest" and "Request" available to our template file. 3. create a template file and write some logic to receive and process data through our endpoint and send data back to the client This will be the longest and most complex part of the tutorial. But I will try to present it in small, easy to follow chunks. Since we access our API at https://mysite.dev/api/pages/, we need to create a template file called "pages.php" for our "pages" template and save it to /site/templates/pages.php. Go ahead and create this file (if you're lazy, copy the attached file). Now right at the top of pages.php, we start with <?php require_once "./inc/Rest.php"; to include the REST Helper classes. Next, we initialize some variables that we will keep using later on // set vars with the default output $statuscode = 200; $response = []; $header = Rest\Header::mimeType('json'); 3.1 retrieve data with a GET request Now that we have the basics set up, we will next create the code for handling the easiest request type, a GET request. With the GET request we will ask the API to return data for an existing page. To let the API know which page it should return data for, we need to send the page id along with our request. I am attaching the page id as an url segment to the API endpoint. So the URL that the client will use to retrieve data for a page will look like: https://mysite.dev/api/pages/1234 where 1234 is the unique page id. Add following code to pages.php // if we have an urlsegment and it is a numeric string we get data from or update an existing page: handle GET and PUT requests if($input->urlSegment1 && is_numeric($input->urlSegment1)) { $pageId = $input->urlSegment1; // GET request: get data from existing page if(Rest\Request::is('get')) { // get the page for given Id $p = $pages->get($pageId); if($p->id) { $pdata = ["id" => $pageId]; // array for storing page data with added page id $p->of(false); // set output formatting to false before retrieving page data // loop through the page fields and add their names and values to $pdata array foreach($p->template->fieldgroup as $field) { if($field->type instanceof FieldtypeFieldsetOpen) continue; $value = $p->get($field->name); $pdata[$field->name] = $field->type->sleepValue($p, $field, $value); } $response = $pdata; } else { //page does not exist $response["error"] = "The page does not exist"; $statuscode = 404; // Not Found (see /site/templates/inc/Rest.php) } } } else { // no url segment: handle POST requests } // render the response and body http_response_code($statuscode); header($header); echo json_encode($response); Lets brake this down: First we check for a numeric url segment which is our $pageId. Then the Rest Request class comes into play and checks what type of request is coming in from the client. For the GET request, we want to return all data that is stored for a page plus the page id. This is all good old PW API code. I am using the $pdata array to store all page data. Then I am handing this array over to the $response variable. This will be used further down to render the JSON response body. If the page does not exist, I am setting an error message for the $response and a status code 404 so the client will know what went wrong. The else statement will later hold our POST request handling. The last 3 lines of code are setting the header and status code for the response and print out the response body that is sent back to the client. You can now browse to https://mysite.dev/api/pages/1 where you should see a JSON string with field names and values of your home page. If you enter a page id which does not exist you should see a JSON string with the error message. Lets move on to updating pages through a PUT request 3.2 update pages with a PUT request Since our API needs to know the id of the page we want to update, we again need to append an id to our endpoint url. In this example we will update the title and name of our homepage. So the request url will be: https://mysite.dev/api/pages/1. For the GET request above, anyone can connect to our API to retrieve page data. For the PUT request this is not a good idea. Thus we will add basic authentication so that only authorized clients can make updates. I use basic HTTP authentication with username and password. In combination with the https protocol this should be fairly safe. To set this up, we need an API key for the password and a username of our choosing. We add the API key in the PW backend: add a new text field "key" and assign it to the "api" template. edit the "api" page, enter your key and save. (I am using 123456 as key for this tutorial) Now add following code right after the if(Rest\Request::is('get')) {...} statement: // PUT request: update data of existing page if(Rest\Request::is('put')) { // get data that was sent from the client in the request body + username and pass for authentication $params = Rest\Request::params(); // verify that this is an authorized request (kept very basic) $apiKey = $pages->get("template=api")->key; $apiUser = "myapiuser"; if($params["uname"] != $apiUser || $params["upass"] != $apiKey) { // unauthorized request $response["error"] = "Authorization failed"; $statuscode = 401; // Unauthorized (see /site/templates/inc/Rest.php) } else { // authorized request // get the page for given Id $p = $pages->get($pageId); if($p->id) { $p->of(false); $p->title = $sanitizer->text($params["title"]); $p->name = $sanitizer->pageName($params["name"]); $p->save(); $response["success"] = "Page updated successfully"; } else { // page does not exist $response["error"] = "The page does not exist"; $statuscode = 404; // Not Found (see /site/templates/inc/Rest.php) } } } Breakdown: We check if the request from the client is a put request. All data that was sent by the client is available through the $params array. The $params array also includes $params["uname"] and $params["upass"] which hold our API user and key. We set API key and user and check if they match with the values that were sent by the client. If they don't match we store an error message to the response body and set the appropriate status code. If authentication went through ok, we get the page via PW API and update the values that were sent in the request body by the client. Then we put out a success message in the response body. If the page does not exist, we send the appropriate response message and status code, just like in the GET request example above. Now you might wonder how the client sends API user/key and new data for updating title and name. This is covered further down in step 4. If you want to test the PUT request right now, head down there and follow the instructions. If not, continue reading on how to setup a POST request for creating new pages. 3.2 create new pages with a POST request Final part of the coding part is creating new pages through our API. For this to work we need to implement a POST request that sends all the data that we need for page creation. We will do this at our endpoint: https://mysite.dev/api/pages/ Paste following code within the else statement that has the comment "// no url segment: handle POST requests": // POST request: create new page if(Rest\Request::is('post')) { // get data that was sent from the client in the request body + username and pass for authentication $params = Rest\Request::params(); // verify that this is an authorized request (kept very basic) $apiKey = $pages->get("template=api")->key; $apiUser = "myapiuser"; if($params["uname"] != $apiUser || $params["upass"] != $apiKey) { // unauthorized request $response["error"] = "Authorization failed"; $statuscode = 401; // Unauthorized (see /site/templates/inc/Rest.php) } else { // authorized request // create the new page $p = new Page(); $p->template = $sanitizer->text($params["template"]); $p->parent = $pages->get($sanitizer->text($params["parent"])); $p->name = $sanitizer->pageName($params["name"]); $p->title = $sanitizer->text($params["title"]); $p->save(); if($p->id) { $response["success"] = "Page created successfully"; $response["url"] = "https://mysite.dev/api/pages/{$p->id}"; } else { // page does not exist $response["error"] = "Something went wrong"; $statuscode = 404; // just as a dummy. Real error code depends on the type of error. } } } You already know what most of this code is doing (checking authorisation etc.). Here's what is new: We create a page through the PW API and assign it a template, a parent and basic content that was sent by the client. We check if the page has been saved and update our response body array with a success message and the URL that this page will be accessible at through the API for future requests. The client can store this URL for making GET or PUT requests to this page. If you're still reading, you have made it through the hard part of this tutorial. Congratulations. Having our code for reading, updating and creating pages, we now need a way to test the whole scenario. Read on to find out how this can be done. 4. test the whole setup with a Browser REST Client Addon The link in the heading will take you to a place from which you can install the very useful RESTClient addon to your favorite browser. I am using it with Firefox which is still the dev browser of my choice. Open a RESTClient session by clicking the little red square icon in the browsers addon bar. The UI is pretty straightforward and intuitive to use. 4.1 test the GET request Choose Method GET and fill in the URL to our endpoint. If you do not have a SSL setup for testing, just use http://yourrealtestdomain.dev/api/pages/1. If you happen to have a SSL test site with a self signed certificate, you need to point your browser to the URL https://yourrealtestdomain.dev/api/pages/ first in your test browser and add the security exception permanently. Otherwise RESTClient addon won't be able to retrieve data. If you have a test site with a 'real' SSL certificate, everything should be fine with using the https://... URL Hit send. In the Response Headers tab you should see a Status Code 200 and in the Response Body tabs a JSON string with data of your page. now change the 1 i the URL to some id that does not exist in your site and hit send again. You should get a 404 Status Code in the Response Headers tab and an error message "{"error":"The page does not exist"}" in the Response Body (Raw) tab. If you get these results, congrats! The GET request is working. For further testing you can save this request through the top menu Favorite Requests->Save Current Request. 4.1 test the PUT request Choose Method PUT and fill in the URL to our endpoint ending with 1 (http://yourrealtestdomain.dev/api/pages/1). In the top left click Headers->Content-Type: application/json to add the right content type to our request. If you miss this step, the request will not work. You will now see a "Headers" panel with all your headers for this request Click on Authentication->Basic Authentication. In the modal window that pops up, fill in user (myapiuser) and password (your API key). Check "Remember me" and hit Okay. You now should see Content-Type and Authorization headers in the "Headers" panel. Next, we need to send some data in the request body for updating our page title and name. Since we're using JSON, we need to create a JSON string that contains the data that we want to send. As I will update the home page for this example, my JSON reads { "title" : "Newhome", "name" : "newhome" } Be careful that you have a well formed string here. Otherwise you will get errors. Paste this into the "Body" panel of the REST Client addon. Hit send. In the Response Headers tab you should see a Status Code 200 and in the Response Body tabs a JSON string "{"success":"Page updated successfully"}". Now go to the PW backend and check if title and name of your page have been updated. If yes, congrats again. 4.2 test the POST request Choose Method POST and fill in the URL to our endpoint without any page id (http://yourrealtestdomain.dev/api/pages/). In the top left click Headers->Content-Type: application/json to add the right content type to our request. If you miss this step, the request will not work. You will now see a "Headers" panel with all your headers for this request Click on Authentication->Basic Authentication. In the modal window that pops up, fill in user (myapiuser) and password (your API key). Check "Remenber me" and hit Okay. You now should see Content-Type and Authorization headers in the "Headers" panel. Next, we need to send some data in the request body for updating our page title and name. Since we're using JSON, we need to create a JSON string that contains the data that we want to send. I will create a new page with template basic-page and parent /about/ for this example, my JSON reads { "template" : "basic-page", "parent" : "/about/", "title" : "New Page created through api", "name" : "newapipage" } Be careful that you have a well formed string here. Otherwise you will get errors. Paste this into the "Body" panel of the REST Client addon. Hit send. In the Response Headers tab you should see a Status Code 200 and in the Response Body tabs a JSON string "{"success":"Page created successfully","url":"https:\/\/mysite.dev\/api\/pages\/1019"}". Now go to the PW backend and check if title and name of your page have been updated. If yes, you're awesome! Summary By now you have learned how to build a simple REST API with ProcessWire for exchanging data with mobile devices or other websites. Notes I tested this on a fresh PW 2.7.2 stable install with the minimal site profile and can confirm the code is working. If you experience any difficulties in getting this to work for you, let me know and I will try to help. There purposely is quite a lot of repetion in the example code to make it easier to digest. In real life code you might not want to use procedural coding style but rather separate repeating logic out into classes/methods. Also, in life applications you should do more sanity checks for the authentication of clients with the API / for the data that is delivered by the client requests and more solid error handling. I skipped these to make the code shorter. RESTful services are by definition stateless (sessionless). My implementation within PW still opens a new session for each request and I haven't found a way around that yet. If anyone can help out this would be much appreciated. And finally big thanks to clsource for putting the Rest.php classes together. pages.php.zip
    1 point
  14. This is actually very easy but might be interesting for someone anyhow (and I post it here as a reminder for myself). You can use Postman (https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=de) to send requests to your ProcessWire installation and test request answers. The problem is that $config->ajax will always return FALSE. To make the $config->ajax work properly you just need to add this key-value-pair to your requests: key: X-Requested-With value: XMLHttpRequest Happy AJAXing PS: This also works inside the admin, see post 3
    1 point
  15. I did a develop and made dis, a procedural galaxy that, well... gets procedurally generated. You can use your mouse to zoom in/out and look around. You can click on stars to get their specific information. It's inspired by the galaxy maps found in games like Elite Dangerous and Eve Online. http://fransvanberendonk.com/procedural-galaxy/ Basicly I've made Templates and Fields for Spectral Classes and Subclasses, and looked up online what a realistic distribution scheme would be for these. This data is grouped under a page that renders then as JSON for the Javascript application to work with. I wrote that app in AngularJS, so I could add more controllers to it later. It also uses BabylonJS to calculate the number and position of stars and display them on screen, and assigns each a Spectral Class and Subclass after some shuffling of the dataset. Using a secondary controller only used in a ProcessModule for the CMS, I can broadcast events that redo the procedure using different variables (see screenshot below). No particular purpose, just thought I'd share a cool side project that rolled out of my exploration of these JS frameworks in conjunction with PW.
    1 point
  16. I'm a hands-on non-developer, new to ProcessWire and checking it out for future use on a particular project. The project is a forms-based collaboration web site, conceptually very simple, like a dating site or a freelance job site, where users create accounts and enter info via forms, browse content pulled from forms data, and so forth. Forms flexibility is the central requirement. Currently, I'm using WordPress, Gravity Forms (a premium plugin), and a minimal responsive theme, to rough things out. Part of the way in, I haven't hit major problems in representing the skeleton of the idea, like, you read this, fill this out, then go to this page, etc. Notably, with Gravity, I can easily add conditional logic, so, depending on the input to a field, subsequent fields will appear (different paths for different users is important). Beyond that, I'm trying not to have to customize anything, instead using other plugins to do basic things like adding custom sidebars depending on page - it's quick and easy, so far. I'm using WordPress+plugins to sketch things out, without having to think about the underlying coding. The next step plan is to use the WP version as an example (along with the written specs), and have a custom site developed - our own custom database and front-end - for efficiency, ease of future extension, and security. ProcessWire seems potentially like a great choice as the platform for the custom site, based on its apparent extreme flexibility (I'm still trying to get a handle on that). Right now, I'm wondering whether it makes sense for me to substitute PW for WP at this roughing out stage. I'm grasping the idea of PW being super flexible and atomic, but from what I've been reading, and from doing my-first-page stuff in a PW installation, there also seems to be a fairly steep learning curve for a non-dev like me. QUESTIONS: Is it worth learning to use PW to where I can do with it what I am doing now with WP, in order to get an idea of whether PW is suitable for the custom site - I'm up for substituting PW scripting for WP plugins, but don't want to get lost in the weeds? Is there a better way for me to evaluate PW? Will learning to use PW at a beginner level be an advantage later on if we have a PW developer build the production site? Any general thoughts would be...appreciated!
    1 point
  17. Found something different: my string-php.json file has two hyphens instead of 3 on the textdomain line, look: { "file": "site\\templates\\_strings.php", "textdomain": "site--templates--_strings-php", "translations": { "2f73c44cbb8a98616f8aeca67192aec6": { "text": "\/de\/" }, "77eb6543a21ba5c45f9c11f899136eee": { "text": "Kontakt" }, "68780987fca9c3f52fb511f87cd43262": { "text": "\/de\/kontakt\/" } } } I'm on Windows 10.
    1 point
  18. @rash I downloaded a fresh copy of PW master, installed the Multi language profile and replicated your settings. Everything worked! So, there's something you may have missed in your setup.
    1 point
  19. I don't know anything about translations because where I live there is no demand for multi-language websites. I'm sure someone will help you with specifics for that soon. But as some general advice, you'll find that any development problem becomes a lot less confusing and frustrating as soon as you install Tracy Debugger and learn how the basic bardump works. Then you can start dumping variables in your template files, includes and functions and that way find out where your problem lies. I can testify that it's very empowering and greatly reduces feelings of hopelessness.
    1 point
  20. Welcome @MikeM! Probably not telling you something you don't already know: the project may be simple conceptually, but it won't be a simple development task. You'll need to work with an experienced developer in order to get a good result with this project. PW is an excellent platform to use for just about any web project, and considering where you are posting this you'll probably find lots of people here who will tell you the same thing. But to be honest, there are many platforms that could be used successfully for this project - in reality the success is more likely to come down to the experience and skill of the developer you hire than the platform used. So seeing as you won't be building the site yourself, your task is really to evaluate developers rather than evaluate ProcessWire. That sounds unusual to me - I haven't heard of people developing one site just to serve as an example for another site they want developed. More typical I think is to use a wireframing tool to show the flow of interactions. This helps you clarify to yourself how the website will work and also helps communicate your intentions to the developer. The wireframe could also demonstrate the design if you wanted that, using a tool such as Invision. Here are some links to a few popular wireframing apps if you want to look at that approach instead: https://www.invisionapp.com/ https://www.mockflow.com/ https://wireframe.cc/
    1 point
  21. Why not... make a Template for months with a title (Januari-December) and index (1-12) field. Then make 12 pages with this template representing each month. make a Field (month) of the Page type. Configure it to accept only 1 choice of the template we made for the month. Voila, a translatable month picker! make a Field (year) which can be an Integer with a minimum and maximum value of your choice. This way you are 100% sure that the input of your client is clean without having to mess with a regex. The downside is that it requires two fields instead of one, and some data management. I find that permissable as you explicitly don't want to store a full datetime. You could configure the template that contains these Fields to display them next to another at 50% width to show the user their intent to be used together. Consider making these fields required.
    1 point
  22. Yes, now it is working perfectly Figured out why jumping occures, because of the page scroling when enough items is shown. So it works great Thank you R
    1 point
  23. Happy to help Sorry for this, I forgot to replace this: <div class="portfolio-item <?php echo $single->categories->first->name ?> "> with this: <div class="portfolio-item <?php echo $single->categories->implode(' ', 'name') ?> "> WireArray's explode and implode methods are cool shorthands for such a thing.
    1 point
  24. Wow, this was fast! Let me first of all thank you for all your work on this, you are the best! I usualy do that but somehow slipped my mind this time. AdminOnSteroids and Tracy Debugger are one hell of a helpers, I never used them before, not sure how could I live without those, specialy TracyDebugger ... Helps a lot when putting all code together. (not that I know how to code ) I just cleaned my other page with it also. I totaly agree and will try to follow your advice. Not sure where this one came from. About so many broken DIV's it's because I just pasted some html from a template just to see if all css works as I've planned. Didn't even focus on this so much, but yes I agree should be more precise about this. Still learning through all this. So for the portfolio part I installed your pack and everything works great. There is some weird jumping of items on FrontEnd but it doesn't really bother me. One thing is what I noticed, that is not possible to give one item to more than one category it always sticks to one only. Not a very big deal but would be really helpful sometimes, if one item belongs to more than one category. Just example, a printed book would be in -> publications, books, prints categories. Thank you again for this, You just made my day a lot nicer R
    1 point
  25. This is a new version of Yahoo! Weather module for ProcessWire, old version of the module can be found at this link. The module has been rewritten, new options have been added alongside with caching from the API (Yahoo! API allows 20.000 calls per hour when using free version, so it comes in handy if your site has a lot of page hits). I've also updated icons in the package (you can easily swap them with yours in module icons folder). You can grab the module from the Modules page or directly from Github link. Update 1.0.1 Yahoo changed their forecast API URL (http://xml.weather.yahoo.com/ instead http://weather. yahooapis.com/), tiny update in Github repo. How to use You can call the module in two different ways: This is a basic call that renders the module, use this if you want only one instance of the module shown with WOEID set in the module settings. <?php echo $modules->get('MarkupYahooWeather')->render(); ?> If you want to show multiple instances of the module, call it this way: <?php $weather = $modules->get('MarkupYahooWeather'); $weather->woeid = 12587912; // Decatur, USA echo $weather->render(); $weather->woeid = 44418; // London, United Kingdom echo $weather->render(); ?> Options This module has the following options: Yahoo! Weather WOEID WOEID (Where On Earth ID) is an unique identifier for each city, you can easily find WOEID by using this site: http://woeid.rosselliot.co.nz. Default = Zagreb Set Locale Sets PHP locale, needed for localized date display. Default = en_US.UTF-8 Set Encoding Converts international date names to right format. Default = ISO-8859-1 Date Format Sets desired date output, formatted with PHP strftime function. Default = %A, %d.%m.%Y. Cache Time Cache time in minutes, caches .xml file(s) retrieved from Yahoo! API and pulls the data locally. Default = 5 minutes Display temperature in Fahrenheit instead of Celsius? Show weather conditions in Celsius or Fahrenheit scale (temperature: C/F; wind speed: km/h, mph; sunrise and sunset: 24h, am/pm). Show 5 day forecast below current weather forecast? Shows extended 5 day forecast, if unchecked, only current weather will be shown. Default = Checked Show wind direction and speed? Shows wind direction and speed. Default = Checked Show sunrise and sunset time? Shows sunrise and sunset time. Default = Checked Autoload script and stylesheet? Renders script and stylesheet during page render, if you prefer to include them manually, turn this option off. Default = Checked Load script in the bottom of the page? If "Autoload script and stylesheet" option is checked, you can select where script should be rendered automatically, before the end of head or body tag. Default = Unchecked Delete Weather Cache Deletes locally stored and cached .xml file(s) from Yahoo! API for all instances of the module.
    1 point
  26. Are you sure $page / $page->id are even recognized?
    1 point
  27. I assume you are referring to a call of the following format: http://10.0.71.8:8105/processwire/page/ This is the call to my testing site. Works like a charm for me, both in the front and back end. Do you just use a standard installation?
    1 point
  28. I used this link https://webdesign.tutsplus.com/tutorials/how-to-develop-a-processwire-theme--cms-25692 and created custom template. But after custom template the navigation and content repeats second time as marked in attache screen shot. Could you please suggest on this Thanks
    1 point
  29. Hi, there you can find some discussions/links :
    1 point
  30. And did you clear your cookies? It's always a good idea to test pw in the browser's incognito mode when strange things occur. That has helped me several times already.
    1 point
  31. I was running quite a recent version (only a few weeks old) but not the very latest. Upgrading to the latest has reduced the number of times the textformatter is called, going from four times down to two times. This is not including any field usage in the template file (i.e. I don't get the field value in my template file, so without the Request Info panel active the textformatter isn't called at all). So it's quite an improvement, but still being called one time more often than I would expect. This is the textformatter I'm using for testing: <?php namespace ProcessWire; class TextformatterTest extends Textformatter implements Module { public static function getModuleInfo() { return array( 'title' => 'Textformatter Test', 'version' => '1', 'summary' => 'Testing', ); } public function formatValue(Page $page, Field $field, &$value) { bd('formatValue'); } } The rest of the setup is basically a clean installation of the blank profile. I can definitely live with it as is, but I'll PM you login details for the test site in case you're interested in investigating.
    1 point
  32. After a few tests, I added a new category to the blog post. I created 2 templates for the new category: categories_a.php <?php namespace ProcessWire; ?> <div class='uk-child-width-1-2@s uk-child-width-1-3@m uk-grid-match uk-margin-large-bottom' pw-append='content' uk-grid> <?php foreach(page()->children as $category_a): ?> <a class='uk-link-reset' href='<?=$category_a->url?>'> <div class='uk-card uk-card-default uk-card-hover uk-card-body'> <h3 class='uk-card-title uk-margin-remove'><?=$category_a->title?></h3> <span class='uk-text-muted'><?=$category_a->numPosts(true)?></span> </div> </a> <?php endforeach; ?> </div> <aside id='sidebar'> <?=ukNav(pages()->get('/blog/')->children('limit=3'), [ 'header' => 'Recent posts' ])?> </aside> category_a.php <?php namespace ProcessWire; ?> <div id='content'> <?php echo ukHeading1(page()->title, 'divider'); $posts = pages()->get('/blog/')->children("categories_a=$page, limit=10"); echo ukBlogPosts($posts); ?> </div> <aside id='sidebar'> <?php $categories_a = page()->parent->children(); echo ukNav($categories_a); ?> </aside> _main.php (Add new category to the navbar) <?=ukNavbarNav($home->and($home->children), [ 'dropdown' => [ 'basic-page', 'categories', 'categories_a' ] ])?> ready.php added a new hook for the categories_a category_a templates. Thats it. Thanks for the great Uikit theme.
    1 point
  33. Hehe. The PW forum is a nice snippets manager and knowledge base for free
    1 point
  34. Thanks for your feedback, I really enjoy the discussion. @mit Aggrid is also mit licensed: https://github.com/ag-grid/ag-grid/blob/master/LICENSE.txt And I don't think it's bad to have paid pro features. Quite on the contrary. I think it can ensure a long life of the software and good quality. We know that principle from somewhere, don't we?! ? @xlsx I have looked at this closely already as it is a must for me to transfer data to excel. Aggrid has the ability to export data as CSV with custom separators. It's perfectly fine to use this for excel export IMHO. It even has custom renderers that only fire when data is accessed for export. Only thing missing at CSV compared to xlsx is fancy styling and formulas etc. Personally I don't need this in any of my projects. Ok, simple links come to my mind. That might be nice to have. But we can still use the API to get data and then use any other JavaScript xlsx library to create our files. Or just pay a little fee to enable that feature. Aggrid looks really well crafted. I'm actually quite happy that I forgot my version of datatables at home over Easter so I was forced to take a pause and take a closer look to aggrid ?
    1 point
  35. OK. Since your priority is to get you site up and running, is it possible to, are you able to create an alternative database using your older MySQL version? Assuming you have a backup of the site pre-the upgrade, you would then import it into the new database and point ProcessWire to that. That would give you a breather to sort out your main issue. Just thinking out loud here. You've probably thought of these things already.
    1 point
  36. True - it does define it, even though I don't think it actually ever uses it, but that explains why it's being calling that file
    1 point
  37. Just an idea, is mysqli extension enabled ? Also, on your newly upgraded server, you could run the ProcessWire installer to check if everything required is installed. If you are tired, you can run the first step of the standalone Duplicator installer. You can delete folders in sites/assets, just keep the file and session folders, and empty the session folder manually.
    1 point
  38. At least this part could maybe be solved with clearing the modules cache. Modules > Site @ the bottom "clear compiled files". Did you check if these fields / modules actually exist physically? Perhaps something went wrong with the FTP upload. An re: troubleshooting guide: Did you check file permissions and did you set all of these to false in your config.php? $config->protectCSRF = false; $config->sessionChallenge = false; $config->sessionFingerprint = false;
    1 point
  39. Hi @adrian, I was doing some testing with a textformatter module and was wondering why the formatValue() method was firing so often, even when my template file does not get the field with the textformatter applied. I traced it back to the Request Info panel - when this panel is active the textformatter formatValue() method fires four times (not including any usages of the field in the template file). I see that the panel shows the value of each field in the template in the "Field List & Values" section, but I would have thought this would only account for one firing. Just wondering if something in that panel is getting the field values more often than necessary and could be optimised perhaps?
    1 point
  40. It would be nice if a description field will also be added to the templates. At the moment only a label field is included. In my case I use a custom dashboard on the frontend with links to the different content types. On the frontend the description field could be used as a title attribute for the links. So the editor could see if it is the right content type he is looking for by hovering over the links. On the backend side the description could be displayed under the title of the template. This could be a useful addition to give users a little more information about the template itself. Example for a description: Template for creating an event with start and endpoint and the possibility to enter prices, locations, number of participants and more.
    1 point
  41. For any field that references a page, the syntax to access and search content in the referenced page is the same. You use dot syntax in the form page_reference_field_name.field_name. This applies equally to Page Reference, PageTable and Repeater / Repeater Matrix field types. So if you use a Page Reference field called "social_networks" that contains pages for Facebook, Twitter and LinkedIn, and those pages contain a "body" field that you want to search, your selector would be: social_networks.body%=foo This will match the page that contains the social_network field rather than the referenced pages. So exactly what you are wanting to do.
    1 point
  42. I'm not quite sure how the original shuffling masonry gallery needs the css classes to be applied, but you probably need nested loops, something like: Note that in your original sample code I see this: data-filter=".cat4" meaning there is prefixing a dot there but not in your code. I also recommend storing the result of the page find selectors in variables, so that you can test easily what you really have. Assigning them to variables also makes it possible to reuse them, which will be needed if you need nested loops. I'm not saying the above code is what you need, because I do not get how the masonry should be assembled in the first place. Can you provide a working demo by any chance?
    1 point
  43. Thanks for the code. First of all it is missing the word "php" from the second loop's end: instead of <? endforeach; ?> it should be: <?php endforeach; ?> Next, your second loop variable is $single, but you have a <?= $item->title ?> in the code, it might be possible that it should be <?= $item->single ?> but maybe not, because you also have <h4><?= $single->title ?></h4> in the loop so what is that title you are trying to output in the second loop? You cannot simply reference the previous loop's variable like this, because that value is already discarded by the time the code execution gets here (that is: we have two different variable scopes). Where is this category in your code? I cannot see it being used.
    1 point
  44. @Roych I pasted your code of the first post and it has syntax errors, so you should sort those out first. I recommend you follow guidelines such us: https://www.ntchosting.com/encyclopedia/scripting-and-programming/php/php-in/ In the article there is the "Possible yet not recommended usage:" section. Do not do that For example, do not do this: <?php foreach($pages->find("parent=1034") as $item) { echo "<li><a href='index.htm#' data-filter='.{$item->select->category}'>$item->title</a></li>"; } ?> instead: <?php foreach ($pages->find("parent=1034") as $item) : ?> <li> <a href='index.htm#' data-filter='<?= $item->select->category ?>'> <?= $item->title ?> </a> </li> <?php endforeach; ?> Much cleaner and a harder to make mistakes. But most importantly, do not mix coding styles
    1 point
  45. Woah! Put down your counter arguments. Now I've got your attention, hope you all have a great Christmas
    1 point
  46. Ha yeah, me looking at the hello world module looks something like this: Not that I won’t keep trying though until I can do it.
    1 point
  47. Very useful if you want to create automatic breadcrumbs via a function. I had this problem by creating child pages under a parent that should not be displayed via a real URL. The parent was only to categorize the content. But in the breadcrumbs it was displayed. In my case I solved it by categorize the children via different templates, but if you have only one template for the children, this solution will not work any longer.
    1 point
  48. Here is the related old blogpost: https://processwire.com/blog/posts/quality-assurance-for-images-in-rich-text-fields/
    1 point
  49. Hey guys, Was just interested in your different techniques for sending HTML emails through your templates. More specifically, where you store your email codes? In the past, using smaller, simpler emails I was "OKish" with keeping all the HTML garbled in my form processing at the top of a page but am thinking there must be better ways surely? Do you use includes? ProcessWire templates? Just interested in seeing your different techniques.
    1 point
×
×
  • Create New...