bytesource Posted January 11, 2013 Share Posted January 11, 2013 Hi,I have a field sidebar_content of type file that I use to select different snippets of code like the following: /site/templates/snippets/sidebar/content/projects_page_promotion.inc <h5>Information</h5> <section class="infobox"> <p><?php echo __("Make sure to visit our new 'Projects' page"); ?></p> </section> The snippets are included in the template as follows: <?php if ($page->sidebar_content) { foreach($page->sidebar_content as $content) { echo "<li>"; include($content->filename); echo "</li>"; } } ?> This approach works, but when the locale changes if($config->httpHost == 'es.example.com') { $user->language = $languages->get("spanish"); } the sentence in the above snippet <?php echo __("Make sure to visit our new 'Projects' page"); ?> is still shown in English, while translatable strings in other template files output the Spanish versions correctly.I would be glad if someone could point me to my error or maybe suggest a better approach. Cheers,Stefan Link to comment Share on other sites More sharing options...
ryan Posted January 11, 2013 Share Posted January 11, 2013 I have a field sidebar_content of type file that I use to select different snippets of code like the following: I am confused about how your includes are being done. You mentioned you are using a File field and including them, which sounds concerning from a security standpoint. But the snippet you mentioned (/site/templates/snippets/...) is not in the path where file uploads go, so I'm confused on that point. As for why they aren't translating--have you specifically translated them? By that I mean, did you go to Setup > Languages > [some language] > Translate New File > Enter filename: /site/templates/snippets/sidebar/content/projects_page_promotion.inc ? If you have translated them, then the translation will only work so long as the file stays in the location that you translated it from. That location is called the "textdomain", and it's the primarily way that set of translations relates to a file. So if you translated the above file, and then uploaded to your site somewhere else, it would not continue to be translated. Link to comment Share on other sites More sharing options...
bytesource Posted January 12, 2013 Author Share Posted January 12, 2013 I am confused about how your includes are being done. You mentioned you are using a File field and including them, which sounds concerning from a security standpoint. But the snippet you mentioned (/site/templates/snippets/...) is not in the path where file uploads go, so I'm confused on that point. I include each snippet from the admin choosing its file path from the sidebar_content field of type file. No person other than my is allowed to include these files. If you have translated them, then the translation will only work so long as the file stays in the location that you translated it from. That location is called the "textdomain", and it's the primarily way that set of translations relates to a file. So if you translated the above file, and then uploaded to your site somewhere else, it would not continue to be translated. I guess that might be the problem. The original snippets/files are stored in /site/templates/snippets/sidebar/content/, but after uploading they are pulled from /site/assets/files/a_number/. Link to comment Share on other sites More sharing options...
bytesource Posted January 12, 2013 Author Share Posted January 12, 2013 Apparently my solution did not work out. I also tried including the snippets into the sidebar area via page references, where each page had a template infobox that just rendered the body field of that page. However, this didn't work out either, as the body field often contains HTML and PHP code. Is there a more elegant way of choosing and displaying different sidebar content? Cheers, Stefan Link to comment Share on other sites More sharing options...
Pete Posted January 12, 2013 Share Posted January 12, 2013 I'm confused by your last statement - you cant have a field in ProcessWire containing PHP code. It would just spit it out as text. Even if you put PHP into a text field the only way you could parse the PHP is with eval() and that's really not recommended. Or am I misunderstanding? Link to comment Share on other sites More sharing options...
ryan Posted January 12, 2013 Share Posted January 12, 2013 I guess that might be the problem. The original snippets/files are stored in /site/templates/snippets/sidebar/content/, but after uploading they are pulled from /site/assets/files/a_number/. You could just perform the translation from its final location, rather than it's temporary location. But the truth is that anything that allows one to upload code or files that will be executed on the server is considered a security hole. It's true that it's probably fine if you are the only one that can write or upload that code. But it's also far from a best practice, and ProcessWire is written towards enforcing best practices, which is why it's not making it easy here. One way to do it that would be workable would be to keep your files in the original location (off /site/templates/) and use your fields to refer to them rather than pull code from them. For instance, you might have a text field where you type "projects_page_promotion" in it, and your template file automatically includes the file matching the name in /site/templates/snippets/sidebar/content/. To take it further, you could make it a Page reference field, so that they could be selectable and even draggable/droppable (via an asmSelect field). Let me know if I can describe more detail on that. There are all kinds of possibilities here. But it would require you to maintain the best practice of keeping the actual code out of your site's content and as part of your site's development files. Link to comment Share on other sites More sharing options...
bytesource Posted January 13, 2013 Author Share Posted January 13, 2013 I agree that uploading any code that gets executed on the server is always a bad idea. I just couldn't come up with a better solution. That's why I am especially gratefull for your suggestions. Following your first approach I solved the problem as follows: 1) Added field sidebar_content of type textarea to the respective templates. sidebar_content contains the names of the snippet files to be included (please see attachment). 2) Template code: <?php // Variables to be set: // $content // $sidebar include_once("./helpers.inc"); // content $t_content = new TemplateFile(wire('config')->paths->templates . 'snippets/pages/_contact.php'); $content = $t_content->render(); // sidebar $side = new TemplateFile(wire('config')->paths->templates . 'snippets/sidebar/sidebar.php'); $sidebar = $side->render(); include("./main.inc") ?> 3) Code of sidebar.php: <?php $filenames = $page->sidebar_content; if ($filenames) { $filenames = explode("\n", $filenames); foreach ($filenames as $name) { $name = trim($name); echo "<li>"; $t = new TemplateFile(wire('config')->paths->templates . "snippets/sidebar/content/" . $name . ".php"); echo $t->render(); echo "</li>"; } } ?> While the above approach is working, I am not sure if it is in any way ideomatic. Any suggestions, especially regarding the php code are highly welcome! Cheers, Stefan Link to comment Share on other sites More sharing options...
ryan Posted January 14, 2013 Share Posted January 14, 2013 I think that's a definite improvement. If your need allows it, you might want to prevent the inclusion of slashes so that someone can't have it pull in PHP files outside of the directory where you are allowing them. $name = $sanitizer->pageName($name); That will replace anything that's not in this set of characters: "-_.a-z0-9", with hyphens. That adds some reasonable security here. Link to comment Share on other sites More sharing options...
bytesource Posted January 14, 2013 Author Share Posted January 14, 2013 Thanks for explaining the need for the sanitizer in my code. I will definitely add this line. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now