Jump to content

Best way to get random quote displayed on refresh?


kathep
 Share

Recommended Posts

I am setting up a new processwire site (kathep.com/cms), and have a problem I can't find a solution to on the forum so far.

I would like the footer of one of my templates (course.php), to display a random quote in a specific category, from a collection of quotes.

I currently have the quotes stored in a text file, and have set up four fields in processwire to take the information (quote_text, quote_author, quote_category, quote_reference). 

My questions are:

1. What is the best way to store the quotes in processwire?

I'm not sure if its best to create an individual page for each quote, or to shell out for protools and store them in a table.

I saw this example from Sinnut  on this thread which looks good to me:

As an example, (part of) a fictional site tree:

items
-item(newsitem)
-item(pressrelease)
-item(statusupdate)
-item(newsitem)
-item(newsitem)
-item(pressrelease)
tools
-item_categories
--newsitem
--statusupdate
--pressrelease

But as I'm a beginner, I'm seeking advice of someone with more expertise! Would this structure suit my use case?

2. What is the best way to allow quotes to be stored in multiple categories?

Ideally I would like to be able to select multiple categories for some quotes. Would this best be done in with check boxes? I'm not sure.

3. In my course.php file, what is the best way to call a random quote from a specific category?

Thank you for reading this, and I hope someone can help.

Link to comment
Share on other sites

Hi @kathep, welcome to PW and the forums.

As with the most things here, there are no "right way" to do it. There are a few more or less equal but different solutions possible. What come into my mind are three variations:

  • a) simply going with single pages
  • b) going with repeaters
  • c) going with Profields Pagetable

I would go with single pages:

1) build a page called tools or something that only serves as parent for stuff that is not used to be displayed directly to the forntend. Set the page to hidden.

2)

  • Build a template called category, it only needs a title field I think
  • create a page under tools called categories that should serve as parent for your categories
  • build child pages under categories that have the template category and the title are the names of your categories you need

3)

  • Build a template called quotes,
  • build the fields you need to be on a quotes page:
        quote_text = textarea
        quote_author = text
        quote_category = page, best is to use it with ASM select!, the source for it is the category parent!
        etc
    and assign them to the template
  • Build a page under tools called quotes as parent for all single quote pages
  • create your quote pages there (if you have to many for a manually creation, there are also automated import solutions available)

If you have all setup you can get the quotes from every where in PW with a selector like this

// get all quote pages
$quotes = $pages->get("/tools/quotes/")->children();

// get all quote pages of a specific category
$quotes = $pages->get("/tools/quotes/")->find("quote_category.title=category1");

// get all quote pages of a few specific categories
$quotes = $pages->get("/tools/quotes/")->find("quote_category.title=category1|category2|category3");

// to get only one random out of those collections you call ->getRandom() at the end
$quote = $pages->get("/tools/quotes/")->find("quote_category.title=category1|category2|category3")->getRandom();

If you get stuck at some point with this, come back and tell us. :)

Edited by horst
corrected errors from my code example: ->get->()
  • Like 7
Link to comment
Share on other sites

You should follow what Ivan and Horst already posted

but found this also you can rebuild for your needs:

$(document).ready(function() {
    var quotes = new Array("foo", "bar", "baz", "chuck"),
    randno = quotes[Math.floor( Math.random() * quotes.length )];
    $('.quote').text( randno );
});


foreach ($quoteArray as $quote) {
    echo $quote;
}


http://www.codelifter.com/main/javascript/randomquote.shtml

Link to comment
Share on other sites

I just thought that this ozwim's new module could be of great use here. I swear I saw somewhere it can cope with csv or xml as well as yaml. So it would be quite easy to copypaste formatted csv data in the textfield for the quotes. I have used similar solution on Joomla once. The input could be much more convinient this way.

@kathep: I suggest you go the way so thoroughly described by horst as it is much more "mainstream" and usefull for learning to deal with PW in general. If you got a lot of quotes, check out this csv import module.

Link to comment
Share on other sites

Wow, thank you so much everyone.

Thank you especially @horst and @ivan gretsky. I found the video really helpful for understanding what the page field does. And @horst your detailed instructions are just what I need as a beginner. 

I have followed your steps @horst, and all went well until I added the quote_category field to the quotes template. The only difference between what I have done, and what you have suggested in steps 1-3 is that I have named the parent folder for the categories as 'quote_categories'.

Next problem...

I have created a field called 'quote_category' and assigned it a type of 'page'.

When I assign it an Input Field Type of 'AsmSelect', and choose 'quote_categories' as the Parent of selectable pages, I have a problem. When entering text into my quotes template, for the 'quote_category' field I get a drop down list that only contains the text '1051' (see screenshot here).

UPDATE: Resolved

I think '1051' was showing up in the dropdown list because I had not published my quote_categories child pages. When I published them, they showed up in the drop down list. Other beginners take note!

I will keep you updated on how I go with this random quote display exercise. Stay tuned!

  • Like 3
Link to comment
Share on other sites

@kathep,

sorry if this was already answered;  this is how i'm doing it (the random quote is shown on pages that are in a page select called landing_pages;

quotes are stored as pages..

we use the title field for the name of the person, and the summary field for the quote text, so there is no markup (since in my design the quote is displayed in an h3

<?php $quote = $pages->find("template=quote, landing_pages=$page")->getRandom(); ?>
<blockquote>
   <h3><?php echo nl2br($quote->summary)?></h3>
   <cite title=""><?php echo $quote->title?></cite>
</blockquote>
  • Like 1
Link to comment
Share on other sites

Hey all, 

I have successfully made the quote categories and added about 100 quotes. The new 'tools' part of my page tree now looks like this:

post-2947-0-81223700-1419312892_thumb.pn

I added the following code to my course.php template (as recommended by @horst):

$quotes = $pages->get->("/tools/quotes/")->find("quote_category.title=life")->getRandom(); 
 
The only thing I changed was changing 'category 1' to 'life' - this is one of my quote categories.
 
Now I get the following error: 
 
post-2947-0-81789800-1419311477_thumb.pn
 
I'm new to php and can't figure out what it means. Does anyone have and idea how I can resolve this? 
Link to comment
Share on other sites

Hey,

this is a parse error that says there is a sign missing or there is one to much somewhere in your code between line 1 and line 167 in course.php. So, nothing one can say without seeing the code.

With wich Editor do you write your code? I would recommend an editor with syntaxHighlighting and syntaxChecking (!!) for PHP. If you don't have any, you can ask here what other users can recommend on free software for your system (Mac?). I have worked many years with Active State Komodo Edit, what is available for Win, Mac and Linux for free.

Link to comment
Share on other sites

I have a list of pages with quotes. The quote is in the headline of the page, other stuff like author etc goes into other fields.

On the home page the code is

$randomtxt = $pages->find('parent=/resources/quotes/, headline!="", sort=random')->getRandom(1);
echo "<br><br><center><b>{$randomtxt->headline}</b></center>";

http://www.performan.org - text under video.

Before that I used an old script 'GetRandomText' that just grabs text from a text file with all your quotes.

http://www.clubmoral.com/ddv - text at top of page. here the image also changes randomly.

Link to comment
Share on other sites

hi kathep,

the error comes from horsts code snippet (feeling a little embarassed to correct him  :rolleyes: )

$pages->get->("/tools/quotes/")

should be

$pages->get("/tools/quotes/")

see the docs about selectors: https://processwire.com/api/selectors/

and a hint on how to efficiently search the forum with google: https://www.google.at/search?q=site:processwire.com+random&gws_rd=cr&ei=RnSZVKnFAcH9UP35gbAL (see the howto in my signature)

  • Like 2
Link to comment
Share on other sites

Hey,

this is a parse error that says there is a sign missing or there is one to much somewhere in your code between line 1 and line 167 in course.php. So, nothing one can say without seeing the code.

With wich Editor do you write your code? I would recommend an editor with syntaxHighlighting and syntaxChecking (!!) for PHP. If you don't have any, you can ask here what other users can recommend on free software for your system (Mac?). I have worked many years with Active State Komodo Edit, what is available for Win, Mac and Linux for free.

Thanks for the quick reply @Horst. I think the problem must be on line 167 (the new code to add random quote), because the page works fine without that new code. I use Chocolat for writing code, and I really like it. It has syntax markup, and all looks fine... see below:

Start of course.php code:

post-2947-0-32170200-1419351350_thumb.pn

In between there is nothing much - more calls to html.

End of course.php code:

post-2947-0-95144700-1419351068_thumb.pn

I am using _init.php and _main.php from the default PW template for most of the markup. I am a little embarrassed to show my code, as I think this is not the best way to make a template. However, it has worked so far, so I am hesitant to change it. 

Do these screenshots help clarify the problem with my code?

Link to comment
Share on other sites

hi kathep,

please read my post - i already showed you what's wrong ;)

and again i recommend you the post about how to search the forum with google (not especially for your problem here but very very helpful in general)

edit: this is what a google search for "random" brings up on a processwire-site-search: https://www.google.at/search?q=site:processwire.com+random&gws_rd=cr&ei=RnSZVKnFAcH9UP35gbAL

Link to comment
Share on other sites

hi kathep,

the error comes from horsts code snippet (feeling a little embarassed to correct him  :rolleyes: )

$pages->get->("/tools/quotes/")

should be

$pages->get("/tools/quotes/")

Ah @BernhardB, thank you! I missed your post, so thanks for reminding me. :)

I have corrected that problem, but now I have another challenge...

The page displays, but where I hoped the quote would appear, a number appears instead. 

Here is the code:

$quote_w_heading = "Quote goes here: " . $quotes = $pages->get("/tools/quotes/")->find("quote_category.title=life")->getRandom();

// Primary content goes here
$content = $course_number_w_heading . $course_summary_w_heading . $course_resources_w_heading . $course_readings_w_heading . $course_objectives_w_heading . $grading . "<h2>Getting Help</h2>" . $remind . $equipment . $success . $ability . "<h2>Conduct</h2>" . $honesty . $recording . $quote_w_heading; 

And here is what displays:

post-2947-0-60603200-1419354656_thumb.pn

Numbers also appear on my quote pages where the 'quote_category' fields should display:

post-2947-0-66048800-1419354808_thumb.pn

Perhaps I need to tweak something in my code, but I'm not sure what. Anyone see something suspect in there?

post-2947-0-16812000-1419352463_thumb.pn

post-2947-0-01439500-1419352464_thumb.pn

Link to comment
Share on other sites

it's better to post your code as text, not as image - so we can copy/paste it ;)

post-2137-0-99972800-1419352917_thumb.pn

just quick, not tested - try something like this:

$quote = $pages->find("parent=/tools/quotes, quote_category.title=life")->getRandom();
// quote is now your random quote page with all its fields
// i don't know what fields you have? title / body / ...?

$quote_w_heading = "quote goes here: " . $quote->title; // or $quote->body 

you can't have 2 equal signs on one line ;)

$this = $is . $correct;

$this = $is . $not = $correct;

  • Like 3
Link to comment
Share on other sites

@BernhardB Ah, thank you for your many tips! I am learning fast by doing things wrong  ^_^

I am trying your improved code suggestion now...


UPDATE: It worked! Successful result:

post-2947-0-08000400-1419355413_thumb.pn

Below is a breakdown of the steps I took in very simple terms for other beginners to follow (all credit to previous posters, especially @Horst and @BernhardB - you are truly patient :rolleyes:).

Steps for creating random quote/text selection from a large pool (for an absolute beginner)

All steps are completed through the ProcessWire admin panel, unless otherwise stated. These steps assume you are using the _main.php and _init.php files in your templates.

  1. Build a page called tools. This serves as a parent for stuff that is not used to be displayed directly in the frontend.
    • Assign this page the pw_default template.
    • Set the page to hidden.
    • When saving this page, choose 'save + keep unpublished'.
  2. Create a new template called quote_category. This template only needs one field: title. Later, you will use the title field of this template to enter categories you want to use to classify quotes.

    Note: this is different to @horst's suggestion of a generic category field only for scalability - if you need to make other categories for other types of information in the future, and don't want them both to be called by the same function.
     
  3. In the code editor of your choice, create a file called quote_category.php.
    • In the body of the file, enter: 
      <?php 
      
      // quote_categories.php template file 
    • Save this file to your computer. 
    • Using an FTP program, upload this file to your processwire installation at: site/templates/.
  4. Create a page under tools called quote_categories. This serves as parent for the categories you use to classify your quotes.
    • Assign this page the pw_default template.
    • Set the page to hidden.
    • When saving this page, choose 'publish'.
  5. Under the page quote_categories, create child pages.
    • Assign each child page the quote_category template.
    • In the title field of each new child page, enter the name of one category you need.
    • For every child page, set the page to hidden.
    • When saving each child page, choose 'publish'.
    • Create as many child pages as categories you need.
  6. Create some fields to be used on a new template (see next step):
    1. field label: Quote text
      field name: quote_text
      field type: textarea or text (depending on how long your quotes are, and how much formatting they require)
    2. field label: Quote Author
      field name: quote_author
      field type: text
    3. field label: Quote Category
      field name: quote_category
      field type: page
      Note: for this field, there are extra settings required - you can find them under the 'Input' section of field options.
      input field type: ASMselect*
      parent of selectable pages: /tools/quote_categories
    4. Any other field you need. For example, I have a quote_reference field to cite where the quote came from. This is not necessary though.
       
  7. Create a new template called quotes. Add the templates you just created to this template: quote_text, quote_author, quote_category and any others you made.
     
  8. In the code editor of your choice, create a file called quotes.php.
    • In the body of the file, enter:
      <?php 
      
      // quotes.php template file 
      
      // Primary content goes here
      $content = "'" . $page->quote_text . "'". "—". $page->quote_author . "<br>" . "$page->quote_category";
      
    • Save this file to your computer. 
    • Using an FTP program, upload this file to your processwire installation at: site/templates/.
  9. Create a page under tools called quotes. This serves as parent for all single quote pages.
     
  10. Under the page quotes, create child pages.
    • Assign each child page the quote_category template.
    • When saving each child page, choose 'publish'.
    • Create one child page for every quote you have.
  11. In an FTP client, download the template where you want a random quote to appear.

    In your code editor of choice, open the template where you want a random quote to appear. Enter the the following code: 
    $quote = $pages->find("parent=/tools/quotes, quote_category.title=category1|category2")->getRandom();
    
    //add nice formatting
    $quote_w_heading = "quote: '" . $quote->quote_text . "' —". $quote->quote_author;  
    

    In the above example, replace the text 'category1|category' with the name of the category/ies you want to display a quote from.

    Then, at the $content or $sidebar function (or wherever you want your quote to display), add the following code to the end of the string: 

    . $quote_w_heading
    

    So the $content string should look something like this: 

    // Primary content goes here
    $content = $course_number_w_heading . $course_summary_w_heading . $recording . $quote_w_heading; 
    
    

    Save your template file.
    Upload it back to to site/templates/
     

  12. In your browser, view a page that uses the template you just changed. Refresh the view, and marvel at your new random quote appearing!

Now that I have written out all these instructions, I see that this is perhaps not a beginner project. 

More experienced people, please offer corrections to any steps you see that could be improved.

Thanks again all for your help!

  • Like 4
Link to comment
Share on other sites

you can't have 2 equal signs on one line  ;)

$this = $is . $correct;

$this = $is . $not = $correct;

Not to be pedantic, but you can actually do this. It can be a bit of a shortcut way of assigning things to variables. That said, I generally think it looks confusing and ugly, but can occasionally be useful, but not in this case since you aren't using $quotes anywhere else :)

$quote_w_heading = "Quote goes here: " . $quotes = "The quote";
echo $quote_w_heading;

You would end up with: 

Quote goes here: The quote

and $quotes would equal: The quote

  • Like 3
Link to comment
Share on other sites

Not to be pedantic, but you can actually do this. It can be a bit of a shortcut way of assigning things to variables. That said, I generally think it looks confusing and ugly, but can occasionally be useful, but not in this case since you aren't using $quotes anywhere else :)

$quote_w_heading = "Quote goes here: " . $quotes = "The quote";
echo $quote_w_heading;

You would end up with: 

Quote goes here: The quote

and $quotes would equal: The quote

i knew that would come - but i only knew that things like this were possible:

$a = $b = $c = "any value";

didn't know that it was possible to assign different values to different variables in one line. thank you! php.net reference

@kathep

great writeup indeed!

more to come... have to restart my pc

$content = "'" . $page->quote_text . "'". "—". $page->quote_author . "<br>" . "$page->quote_category";

https://processwire.com/talk/topic/8626-multiple-random-ads/?p=83345

  • Like 1
Link to comment
Share on other sites

Great writeup!

Now that you have learned the full way to create the templates and pages for populating a page field you are qualified to do it the easy way ;)

http://modules.processwire.com/modules/process-page-field-select-creator/

Aaah! I can't believe I missed this for a week! This will save me so much time!

I'm constantly surprised by how many extra pages I'm making as my PW site develops. All in the name of scalability.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...