6415

twig: pass variables from view to controller

<strong>Setup:</strong>

    <li>Twig 1.13.1</li> <li>PHP 5.4.3</li> </ul> <hr>

    <strong>Problem:</strong>

    I have 10,000 articles in my DB. I need a way to only allow X amount of stories to display on the page. I know I can limit the number in the controller before i call the template but that number will be different depending on the template that is used. I will have one controller to handles all the articles. I need a way to pass the number from the template to the controller to limit the array. I don't want to pull down all 10,000 articles then use twig "slice" filter/func.

    I know in django you can use the below. That will only load the top 3 stories.

    {% get_latest_stories 3 sports as story_list %} {% for story in story_list %} {{ story.title }} {% endfor %}

    Here is my current files.

    Controller

    <?php $stories = news_stories::getStories("sports",5); //getStories(section,limit); ?> <?=$twig->render("storyList.html", array('stories' => $stories))?>

    View/Template

    {% for story in story_list %} {{ story.title }} {% endfor %} <hr>

    <strong>Summary</strong>

    I would like a way to pass a number from the template to the controller so that i can limit the about of rows returned from the DB

    Answer1:

    Logically speaking, it would be impossible for the view to pass something to controller since the view is being processed at the end of the stack, after everything else.

    You can however, <strong>pass a function into the view</strong>. You would want to create some sort of getViewStories function that you can access from your twig template. Since you have this already in your controller:

    <?php $stories = news_stories::getStories("sports",5); //getStories(section,limit); ?> <?=$twig->render("storyList.html", array('stories' => $stories))?>

    All you would need to do is change it around a bit, like this:

    <?php $function = new Twig_SimpleFunction('getViewStories', function (section, limit) { return news_stories::getStories(section,limit); }); $twig->addFunction($function); ?> <?=$twig->render("storyList.html")?>

    Now, from inside your template, you can call this function, like so:

    {% set story_list = getViewStories('sports',5) %} {% for story in story_list %} {{ story.title }} {% endfor %}

    And change the getViewStories parameters around in each template.

    And while you can use the slice filter, I would recommend against it in your case, as it makes for unnecessarily long database calls. This is the most optimized method (that I'm aware of).

    Answer2:

    You want to use the slice filter I think this should work for you

    http://twig.sensiolabs.org/doc/filters/slice.html

    {% for story in story_list|slice(1,5) %} {{ story.title }} {% endfor %}

    should only return the elements 1 - > 5 of the loop then break loop. You can also do it like this

    {% for story in story_list|[start:5] %} {{ story.title }} {% endfor %}

    Disclaimer: I've never actually used twig though this was just a quick browse through its docs

    Answer3:

    You can embedded controllers ( or render other urls ) from inside a twig template. This means you could have a main layout template for your site, and keep your storyList.html template very plain - just to iterate over the stories and any markup they might need.

    In your main layout you would render the action for the news stories:

    <div id="stories"> {% render url('...') with { section: 'sports', limit: 5}, {'standalone': 'js'} %} </div>

    This way requires hindclude.js included on your page. Check these docs. If you are also using symfony ( you mention MVC but not the framework ) - even better. Scroll up a bit and look at Embedded controllers.

    Otherwise, I believe this way essentially uses ajax.

Recommend

  • Center Nav Bar when window resized?
  • undefined method or my Active Record mistakes
  • IE & Ajax / XPath
  • ViewPager FragmentStatePagerAdapter keep more than three fragments in memory
  • DropColumn conditionally in a migration
  • is there a 64-bit msdasql for windows 7?
  • Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'
  • create/update user story using rally app sdk
  • Objects disappearing of ArrayList
  • Pass information from one layer to another
  • iWatch: WKInterfaceLabel is it possible to stop text from being cut off with “…” at the end of a lab
  • update module on import to python interpreter
  • Parsing CSV in PHP and trying to keep line breaks in field contents
  • DateTimeFormat.AbbreviatedMonthNames adding a dot at the end of month's name
  • Can't access my folder because of WordPress [closed]
  • Undefined navigator.push React-native 0.43.4
  • redirect_to root_url and return unless @user.activated
  • Aptana 3 remove bundle (jquery)
  • How do I retrieve the user information of a user authenticated with Apache's mod_ldap?
  • Uncaught TypeError: $(…).select2 is not a function
  • Django invalid literal for int() with base 10
  • presentShareDialogWithParams posts to FB wall, but callback handler results say error
  • MongoDB in PHP using aggregate to group by _id is null not working
  • Display issues when we change from one jquery mobile page to another in firefox
  • Modifying destination and filename of gulp-svg-sprite
  • SSO with signing and signature validation doesn't work
  • Upload files with Ajax and Jquery
  • To display the title for the current loaction in map in iphone
  • Do I've to free mysql result after storing it?
  • A cron job substitute?
  • json Serialization in asp
  • trying to dynamically update Highchart column chart but series undefined
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?
  • java string with new operator and a literal