How to get page from content include into front controller</a></h1> </div> <div class="grid fw-wrap pb8 mb16 bb bc-black-075"> <div class="grid--cell ws-nowrap mr16 mb8" title="2016-01-12 19:07:53Z"> <span class="fc-light mr2">Asked</span> <time itemprop="dateCreated" datetime="2015-02-10T19:07:33.203" class="fromnow">Feb 10 '15 at 19:07</time> </div> <div class="grid--cell ws-nowrap mr16 mb8"> <span class="fc-light mr2">Active</span> <time class="fromnow" title="2015-02-10T19:38:55.227" datetime="2015-02-10T19:38:55.227">Feb 10 '15 at 19:38</a> </div> <div class="grid--cell ws-nowrap mb8" title="Viewed 1,102 times"> <span class="fc-light mr2">Viewed</span> 1,102 times </div> </div> <div id="mainbar" role="main" aria-label="questions and answers"> <div id="question" class="question" data-questionid="28439801" data-ownerid="925897" data-score="1"> <div class="post-layout"> <div class="votecell post-layout--left"> <div class="js-voting-container grid jc-center fd-column ai-stretch gs4 fc-black-200" data-post-id="28439801"> <button class="js-vote-up-btn grid--cell s-btn s-btn__unset c-pointer"><svg aria-hidden="true" class="m0 svg-icon iconArrowUpLg" width="36" height="36" viewBox="0 0 36 36"><path d="M2 26h32L18 10 2 26z"></path></svg></button> <div class="js-vote-count grid--cell fc-black-500 fs-title grid fd-column ai-center" itemprop="upvoteCount" data-value="1">1</div> <button class="js-bookmark-btn s-btn s-btn__unset c-pointer py4"> <svg aria-hidden="true" class="svg-icon iconBookmark" width="18" height="18" viewBox="0 0 18 18"><path d="M6 1a2 2 0 00-2 2v14l5-4 5 4V3a2 2 0 00-2-2H6zm3.9 3.83h2.9l-2.35 1.7.9 2.77L9 7.59l-2.35 1.7.9-2.76-2.35-1.7h2.9L9 2.06l.9 2.77z"></path></svg> <div class="js-bookmark-count mt4" data-value=""></div> </button> </div> </div> <div class="postcell post-layout--right"> <div class="s-prose js-post-body" itemprop="text"><p>I'm using a PHP based front controller pattern such that <code>index.php</code> provides the page structure and template, and all content for each page is in include files within <code>/pages/</code>.</p> <pre><code>index.php /pages/home.inc /pages/about.inc /pages/contact.inc </code></pre> <p>The include pages are mostly simple HTML so that clients can edit the pages without having to get into anything too complex. </p> <p>The problem with this layout is that because all page information is in the page include, the <code><title></code> element can't get populated. I could put a <code>$title</code> variable in each include, but it loads after the head, which is too late:</p> <pre><code><html> <head> <title><?php echo $title; ?></title> #$title is not set yet! </head> <body> <?php include($content); ?> #now $title is set </body> </html> </code></pre> <p>It's important that the content files are self contained and mostly HTML, but with the ability to have PHP code as well, as I mentioned, because customers will be modifying these and adding too much complexity is a problem. Thus, for example, setting up a separate database of page titles won't work because customers won't update the database when they make new pages.</p> <p><strong>Edit:</strong> a typical page include might look like this.</p> <pre><code><h1>Welcome</h1> <p>blah</p> <?php include("nav.php"); ?> <p>more blah</p> <p>more blah</p> <p>more blah</p> <?php $pageJavascript = "alert('js!');"; $pageTitle = "Cyberdyne Welcome Page"; ?> </code></pre></div> <div class="mt24 mb12"> <div class="post-taglist grid gs4 gsy fd-column"> <div class="grid ps-relative"> <a href="../../questions/tagged/php" class="post-tag js-gps-track" title="show questions tagged 'php'" rel="tag">php</a> <a href="../../questions/tagged/front-controller" class="post-tag js-gps-track" title="show questions tagged 'front-controller'" rel="tag">front-controller</a> </div> </div> </div> <div class="mb0"> <div class="mt16 grid gs8 gsy fw-wrap jc-end ai-start pt4 mb16"> <div class="grid--cell mr16 fl1 w96"></div> <div class="post-signature grid--cell"> <div class="user-info "> <div class="user-action-time">edited <span title="2015-02-10T19:30:06.293" class="relativetime">Feb 10 '15 at 19:30</span></div> <div class="user-gravatar32"></div> <div class="user-details" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span class="d-none" itemprop="name">brentonstrine</span> <div class="-flair"></div> </div> </div> </div> <div class="post-signature owner grid--cell"> <div class="s-user-card s-user-card"> <time class="s-user-card--time" datetime="asked Feb 10 '15 at 19:07">asked Feb 10 '15 at 19:07</time> <a href="../../users/925897/brentonstrine" class="s-avatar s-avatar__32 s-user-card--avatar"> <img class="s-avatar--image" src="../../users/profiles/925897.webp" data-jdenticon-width="32" data-jdenticon-height="32" data-jdenticon-value="brentonstrine" /> </a> <div class="s-user-card--info"> <a href="../../users/925897/brentonstrine" class="s-user-card--link">brentonstrine</a> <ul class="s-user-card--awards"> <li class="s-user-card--rep" title="reputation score">21,694</li> <li class="s-award-bling s-award-bling__gold" title="25 gold badges">25</li> <li class="s-award-bling s-award-bling__silver" title="74 silver badges">74</li> <li class="s-award-bling s-award-bling__bronze" title="120 bronze badges">120</li> </ul> </div> </div> </div> </div> </div> </div> <div class="post-layout--right js-post-comments-component"> <div id="comments-28439801" class="comments js-comments-container bt bc-black-075 mt12 " data-post-id="28439801" data-min-length="15"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-45209332" class="comment js-comment " data-comment-id="45209332" data-comment-owner-id="3790680" data-comment-score="0"> <div class="js-comment-actions comment-actions"> <div class="comment-score js-comment-edit-hide"> </div> </div> <div class="comment-text js-comment-text-and-form"> <a name="comment45209332_28439801"></a> <div class="comment-body js-comment-edit-hide"> <span class="comment-copy">Are the .inc files all text? Or do they use variables as well?</span> – <a href="../../users/3790680/drifter" title="281 reputation" class="comment-user ">Drifter</a> <span class="comment-date" dir="ltr"><a class="comment-link" href="../../questions/28439801/how-to-get-page-title-from-content-include-into-front-controller#comment45209332_28439801"><span title="2015-02-10T19:13:24.730 License: CC BY-SA 3.0" class="relativetime-clean">Feb 10 '15 at 19:13</span></a></span> </div> </div> </li> <li id="comment-45209399" class="comment js-comment " data-comment-id="45209399" data-comment-owner-id="925897" data-comment-score="0"> <div class="js-comment-actions comment-actions"> <div class="comment-score js-comment-edit-hide"> </div> </div> <div class="comment-text js-comment-text-and-form"> <a name="comment45209399_28439801"></a> <div class="comment-body js-comment-edit-hide"> <span class="comment-copy">They're HTML and PHP. Usually the PHP is just to include nav menus and such, but might be a small self-contained PHP script. They also do things like `<?php $pageJavascript = "function runAfterOtherJS(){demo}"; ?>` which gets `echo`'d in at the bottom of the page below all other JS is included.</span> – <a href="../../users/925897/brentonstrine" title="21,694 reputation" class="comment-user owner">brentonstrine</a> <span class="comment-date" dir="ltr"><a class="comment-link" href="../../questions/28439801/how-to-get-page-title-from-content-include-into-front-controller#comment45209399_28439801"><span title="2015-02-10T19:15:13.043 License: CC BY-SA 3.0" class="relativetime-clean">Feb 10 '15 at 19:15</span></a></span> </div> </div> </li> <li id="comment-45209568" class="comment js-comment " data-comment-id="45209568" data-comment-owner-id="3790680" data-comment-score="0"> <div class="js-comment-actions comment-actions"> <div class="comment-score js-comment-edit-hide"> </div> </div> <div class="comment-text js-comment-text-and-form"> <a name="comment45209568_28439801"></a> <div class="comment-body js-comment-edit-hide"> <span class="comment-copy">I'm making the assumption that the moment you include it, it will do some output directly, content related. Is that right?</span> – <a href="../../users/3790680/drifter" title="281 reputation" class="comment-user ">Drifter</a> <span class="comment-date" dir="ltr"><a class="comment-link" href="../../questions/28439801/how-to-get-page-title-from-content-include-into-front-controller#comment45209568_28439801"><span title="2015-02-10T19:20:29.900 License: CC BY-SA 3.0" class="relativetime-clean">Feb 10 '15 at 19:20</span></a></span> </div> </div> </li> <li id="comment-45209671" class="comment js-comment " data-comment-id="45209671" data-comment-owner-id="925897" data-comment-score="0"> <div class="js-comment-actions comment-actions"> <div class="comment-score js-comment-edit-hide"> </div> </div> <div class="comment-text js-comment-text-and-form"> <a name="comment45209671_28439801"></a> <div class="comment-body js-comment-edit-hide"> <span class="comment-copy">Yes, e.g. `<h1>Welcome</h1><?php include('nav.php'); ?>`</span> – <a href="../../users/925897/brentonstrine" title="21,694 reputation" class="comment-user owner">brentonstrine</a> <span class="comment-date" dir="ltr"><a class="comment-link" href="../../questions/28439801/how-to-get-page-title-from-content-include-into-front-controller#comment45209671_28439801"><span title="2015-02-10T19:23:19.580 License: CC BY-SA 3.0" class="relativetime-clean">Feb 10 '15 at 19:23</span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div id="answers"> <a name="tab-top"></a> <div id="answers-header"> <div class="answers-subheader grid ai-center mb8"> <div class="grid--cell fl1"> <h2 class="mb0" data-answercount="9">2 Answers<span style="display:none;" itemprop="answerCount">2</span></h2> </div> </div> </div> <a name="28440080"></a> <div id="answer-28440080" class="answer " data-answerid="28440080" data-ownerid="620813" data-score="1" itemprop="suggestedAnswer" itemscope="" itemtype="https://schema.org/Answer"> <div class="post-layout"> <div class="votecell post-layout--left"> <div class="js-voting-container grid jc-center fd-column ai-stretch gs4 fc-black-200" data-post-id="28440080"> <button class="js-vote-up-btn grid--cell s-btn s-btn__unset c-pointer"><svg aria-hidden="true" class="m0 svg-icon iconArrowUpLg" width="36" height="36" viewBox="0 0 36 36"><path d="M2 26h32L18 10 2 26z"></path></svg></button> <div class="js-vote-count grid--cell fc-black-500 fs-title grid fd-column ai-center" itemprop="upvoteCount" data-value="1">1</div> </div> </div> <div class="postcell post-layout--right"> <div class="s-prose js-post-body" itemprop="text"><p>Options:</p> <h1>1: Use output buffering</h1> <pre><code><?php ob_start(); include($content); $body = ob_get_contents(); ob_end_clean(); ?> <html> <head> <title><?php echo $title; ?></title> </head> <body> <?php echo $body; ?> </body> </html> </code></pre> <p><strong>Pros</strong>:</p> <ul> <li>The browser gets fully rendered page</li> <li>More SEO-friendly (than the javascript title update)</li> <li>No JS required</li> </ul> <p><strong>Cons</strong>:</p> <ul> <li>Need to buffer all the page in memory</li> </ul> <h1>2: Set some kind of general title and update it later with javascript.</h1> <pre><code><script type="text/javascript"> with(document) { window.title = <?php echo json_encode($title); ?>; } </script> </code></pre> <p><strong>Pros</strong>:</p> <ul> <li>You keep the same kind of flow You use now.</li> </ul> <p><strong>Cons</strong>:</p> <ul> <li>Not SEO friendly</li> <li>Requires javascript use</li> </ul></div> <div class="mb0"> <div class="mt16 grid gs8 gsy fw-wrap jc-end ai-start pt4 mb16"> <div class="grid--cell mr16 fl1 w96"></div> <div class="post-signature grid--cell"> <div class="s-user-card s-user-card"> <time class="s-user-card--time" datetime="edited Jun 20 '20 at 09:12">edited Jun 20 '20 at 09:12</time> <a href="../../users/-1/community" class="s-avatar s-avatar__32 s-user-card--avatar"> <img class="s-avatar--image" src="../../users/profiles/-1.webp" data-jdenticon-width="32" data-jdenticon-height="32" data-jdenticon-value="Community" /> </a> <div class="s-user-card--info"> <a href="../../users/-1/community" class="s-user-card--link">Community</a> <ul class="s-user-card--awards"> <li class="s-user-card--rep" title="reputation score">1</li> <li class="s-award-bling s-award-bling__silver" title="1 silver badges">1</li> </ul> </div> </div> </div> <div class="post-signature grid--cell"> <div class="s-user-card s-user-card"> <time class="s-user-card--time" datetime="answered Feb 10 '15 at 19:22">answered Feb 10 '15 at 19:22</time> <a href="../../users/620813/poncha" class="s-avatar s-avatar__32 s-user-card--avatar"> <img class="s-avatar--image" src="../../users/profiles/620813.webp" data-jdenticon-width="32" data-jdenticon-height="32" data-jdenticon-value="poncha" /> </a> <div class="s-user-card--info"> <a href="../../users/620813/poncha" class="s-user-card--link">poncha</a> <ul class="s-user-card--awards"> <li class="s-user-card--rep" title="reputation score">7,726</li> <li class="s-award-bling s-award-bling__gold" title="2 gold badges">2</li> <li class="s-award-bling s-award-bling__silver" title="34 silver badges">34</li> <li class="s-award-bling s-award-bling__bronze" title="38 bronze badges">38</li> </ul> </div> </div> </div> </div> </div> </div> <div class="post-layout--right js-post-comments-component"> </div> </div> </div> <a name="28440375"></a> <div id="answer-28440375" class="answer " data-answerid="28440375" data-ownerid="3790680" data-score="1" itemprop="suggestedAnswer" itemscope="" itemtype="https://schema.org/Answer"> <div class="post-layout"> <div class="votecell post-layout--left"> <div class="js-voting-container grid jc-center fd-column ai-stretch gs4 fc-black-200" data-post-id="28440375"> <button class="js-vote-up-btn grid--cell s-btn s-btn__unset c-pointer"><svg aria-hidden="true" class="m0 svg-icon iconArrowUpLg" width="36" height="36" viewBox="0 0 36 36"><path d="M2 26h32L18 10 2 26z"></path></svg></button> <div class="js-vote-count grid--cell fc-black-500 fs-title grid fd-column ai-center" itemprop="upvoteCount" data-value="1">1</div> </div> </div> <div class="postcell post-layout--right"> <div class="s-prose js-post-body" itemprop="text"><p>If there is a assumption the title is always on the first line: "My page Title";</p> <pre><code>$filename = '/pages/home.inc'; $fileLines = file($filename, FILE_SKIP_EMPTY_LINES); $title = yourFunctionThatStripsKomma($fileLines[0]); </code></pre> <p>Only bad thing is, is that you have to be sure the first line has the title.</p></div> <div class="mb0"> <div class="mt16 grid gs8 gsy fw-wrap jc-end ai-start pt4 mb16"> <div class="grid--cell mr16 fl1 w96"></div> <div class="post-signature grid--cell"> <div class="s-user-card s-user-card"> <time class="s-user-card--time" datetime="answered Feb 10 '15 at 19:38">answered Feb 10 '15 at 19:38</time> <a href="../../users/3790680/drifter" class="s-avatar s-avatar__32 s-user-card--avatar"> <img class="s-avatar--image" src="../../users/profiles/3790680.webp" data-jdenticon-width="32" data-jdenticon-height="32" data-jdenticon-value="Drifter" /> </a> <div class="s-user-card--info"> <a href="../../users/3790680/drifter" class="s-user-card--link">Drifter</a> <ul class="s-user-card--awards"> <li class="s-user-card--rep" title="reputation score">281</li> <li class="s-award-bling s-award-bling__silver" title="1 silver badges">1</li> <li class="s-award-bling s-award-bling__bronze" title="9 bronze badges">9</li> </ul> </div> </div> </div> </div> </div> </div> <div class="post-layout--right js-post-comments-component"> <div id="comments-28440375" class="comments js-comments-container bt bc-black-075 mt12 " data-post-id="28440375" data-min-length="15"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-45211652" class="comment js-comment " data-comment-id="45211652" data-comment-owner-id="925897" data-comment-score="0"> <div class="js-comment-actions comment-actions"> <div class="comment-score js-comment-edit-hide"> </div> </div> <div class="comment-text js-comment-text-and-form"> <a name="comment45211652_28440375"></a> <div class="comment-body js-comment-edit-hide"> <span class="comment-copy">Thanks. Just found [this](http://stackoverflow.com/questions/4521936/quickest-way-to-read-first-line-from-file) which shows a few other ways to grab just the first line. This is a decent option.</span> – <a href="../../users/925897/brentonstrine" title="21,694 reputation" class="comment-user owner">brentonstrine</a> <span class="comment-date" dir="ltr"><a class="comment-link" href="../../questions/28439801/how-to-get-page-title-from-content-include-into-front-controller#comment45211652_28440375"><span title="2015-02-10T20:18:15.360 License: CC BY-SA 3.0" class="relativetime-clean">Feb 10 '15 at 20:18</span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> </div> </div> </div> </div> <script src="../../static/js/stack-icons.js"></script> <script src="../../static/js/fromnow.js"></script> </body> </html>