I am using code igniter.
What I want to do is,
if a page is visited that does not exist
example.com/idontexist
Then I want to first check a database to see if idontexist is in the database.
If it is then I want to route the user to
example.com/action/idontexist.
How can I do this?
I feel like this gets asked every week.
Open up your application/config/routes.php, then add something like this:
$route['^(:any)'] = "my_controller/get_article/$1";
Please note that it will route everything to a controller called action. If you have other controllers then you should add a route for them too (preferably placed before this one).
// EDIT: Using this you can goto http://your-site.com/secrets-of-internet-marketing and it will call the get_article function in the my_controller controller, and pass "secrets-of-internet-marketing" as the first argument. Which can then process with something like this:
public function get_article($article_name) {
// something like this:
$article = $this->article_model->get_model_by_name($article_name);
$this->load->view('article', $article);
}
One solution would be to extend the CI_Router class with your own in application/core/MY_Router.php and just copy the method _set_routing() in your class.
Your changes would go somewhere after routes.php file is included and set to $this->routes property, you can add your custom routes.
include(APPPATH.'config/routes'.EXT);
...
$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
unset($route);
//Get your custom routes:
$your_routes = $this->_get_custom_routes();
foreach($your_routes as $custom_route)
{
$this->routes[$custom_route['your_regex_match']] = $custom_route['controller'].'/'.$custom_route['action'];
}
Of course you might not need this, but I hope it gives you some idea.
This way you can add custom routes and since you will have to fetch them from database, consider caching them for better speed.
Related
Hello guys I'm new to MediaWiki and trying to build my own extension. Using this extension I'm trying to show some content blow page heading but only to a page specific to a category.
For that, I'm using two hooks:
onArticleViewHeader ( To add my HTML content below the page heading)
onOutputPageMakeCategoryLinks (To get all the category of page being loaded)
From the first hook, I'm able to show my content using the following code:
public static function onArticleViewHeader( &$article, &$outputDone, &$pcache ) {
$article->getContext()->getOutput()->addHTML("Printed from a hook");
}
The above code prints the HTML below every page heading but I want to load HTML only to a specific page category. So for that, I'm trying to load the category and I'm just trying to call my first hook only if the category gets caught.
public static function onOutputPageMakeCategoryLinks( &$out, $categories, &$links ) {
foreach($categories as $category){
if($category=="my_page_category"){
MyExtentionClass::onArticleViewHeader();
}
}
}
I know I'm calling the hook in a bad manner which is not correct. But I just wanted to call my 1st hook 'onArticleViewHeader' from inside of my 2nd hook so that I can print my HTML only to a page with a specific category.
Just use $article->getPage()->getCategories() in the header hook.
Haven't really got the exact solution of the question I asked but has got the way out to solve the problem I have been facing.
I just tried getting the current categories in the "onArticleViewHeader" itself by using some of MediaWiki's global variables.
global $wgOut;
$title = Title::newFromText( $wgOut->getPageTitle() );
$categories = $title->getParentCategories();
if(isset($categories['Category:my_cat_name']){
//formed my logic here
}
This might help some other people facing this kind of issue.
I have a site on Wordpress where I am trying to find the best way to create a dropdown which displays data from a custom taxonomy to eventually integrate it into a different site (also on Wordpress).
Where I have go to is trying to obtain the correct Routes/URL's to fetch this information.
I have a Post type called listings which has a taxonomy called listing_area which has different areas where posts are associated, e.g. Wales, East Anglia.
I have got so far that I have decided to use the Plugin WP-API (whether this is the right thing I don't know, I am aware that Wordpress now had an API in it's new update). I have managed to get this URL working and pulling in the terms of listing_area - http://scd.blaze.wpengine.com/wp-json/taxonomies/listing_area/terms/174
This is the test page I have going which is linking to these URL's in turn -
http://scd.blaze.wpengine.com/test/
I have no idea if I'm doing the right thing here and I have very basic knowledge on it and would hugely appreciate it if someone could point me in the right direction!
Thanks
You're going on the right path, but I suggest to work straight with the fresh Wordpress REST API if you can upgrade your websites to 4.4. Otherwise you can still use your REST plugin as it is pretty much the same. I'll try to explain how to go through what you want to achieve (navigate through terms of a distant Wordpress website and display posts related to this terms).
Get the terms from the other WP
Using the new WP REST API, here is a small function that you can use to get your taxonomy terms:
public function getDistantTerms($taxonomy) {
$response = wp_remote_get('http://www.yourwebsite.com/wp-json/wp/v2/terms/' . $taxonomy);
if(is_wp_error($response)) {
return array();
}
return json_decode(wp_remote_retrieve_body($response));
}
Here I make use of wp_remote_get function to get the JSON return from the REST function terms by passing it as parameter the taxonomy slug (ex:listing_area) - here is a demo of what it returns. Add this function to your functions.php then use it in your template to build up your select:
<select name="term_select">
<option value="">Please choose a term</option>
<?php foreach(getDistantTerms('listing_area') as $term): ?>
<option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
It seems that's pretty much what you actually got.
Link your select to a custom template
So the next step is to redirect to a page that list the posts of the term you choose. First we handle the redirection in JS:
$('select[name="term_select"]').change(function() {
if($(this).val() != "") {
window.location = "/show-post-term/" + $(this).val();
}
});
We add a little rewrite rule to redirect this url (change it to whatever you want) to a template we'll name distant-posts.php (all of this take place in your theme functions.php):
1. Add the rewrite rule
add_action('init', 'distantposts_rewrite_rules');
function distantposts_rewrite_rules() {
add_rewrite_rule('show-post-term/([^/]+)/?$', 'index.php?term_slug=$matches[1]&distant_post=true', 'top');
}
2. Add two query vars
add_filter('query_vars', 'distantposts_query_vars' );
function distantposts_query_vars($vars) {
$vars[] = 'term_slug';
$vars[] = 'distant_post';
return $vars;
}
3. Redirect to the template if query vars are set
add_filter('template_include', 'yourpluginname_blah_template_include', 1, 1);
function yourpluginname_blah_template_include($template) {
global $wp_query;
$distant_post = $wp_query->query_vars['distant_post'];
$term_slug = $wp_query->query_vars['term_slug'];
if($distant_post && $term_slug) {
$tpl = locate_template(array('distant-posts.php'));
if(!empty($tpl)) {
return $tpl;
}
}
return $template;
}
So in short what we're doing here: we add a rule that handle the /show-post-term/term-slug URL by redirecting it to index with two query vars: one that tell we're in a "distant posts" mode and one that carry the term slug. Then we declare those query vars to Wordpress, and use them to change the template that Worpdress should display if they're set.
List the distants posts from the taxonomy term
Back to the REST API. We use the GET REST function posts by passing it as GET parameters the taxonomy name as key, and the term slug as value. Here is a demo of what kind of return you get.
An important note before going further: after you updated to WP 4.4, you need to change your taxonomy declaration in order to make this work. You need to add to your declaration the parameter show_in_rest set to true, and set query_var to true.
So we add this little function to functions.php to retrieve the posts from the template:
public function getDistantPosts($taxonomy, $term) {
$response = wp_remote_get('http://www.yourwebsite.com/wp-json/wp/v2/posts?' . $taxonomy . '=' . $term);
if(is_wp_error($response)) {
return array();
}
return json_decode(wp_remote_retrieve_body($response));
}
And then in your template, you call it this way:
global $wp_query;
$posts = getDistantPosts('listing_area', $wp_query->query_vars['term_slug']);
Then use the $posts array to display your posts (it contain regular post objects).
Going further
A few things that you may want to do now that you have the context established:
Add cache to the REST return
In order to avoid to overload your main website server, you should really consider caching your REST calls results. I will not detail this here as there is some work to do on it, but a good start could be this script.
Add pagination to your distant posts template
If you have a lot of posts associated to your terms, you might want to add a pagination. You can change a bit the distant posts REST function to add the page parameter for this - see the documentation.
Add a "single page" for your distant posts
You might want to have individual pages for your distant posts on your main website, as the text might be too long for the list mode. You can start on the distant-posts.php code and add a post_id query var, then use the REST posts function to get your post like this : /wp-json/wp/v2/posts/<post_id>
To understand the basics of the WP REST API I strongly suggest you to visit the wp-api.org website. There is a pretty good article on the REST API on wpmudev.org that you can read too. If you need to learn about the REST basics, I suggest you to read the Wikipedia post about it.
Hope you'll manage to get through this, have fun!
I found this this url got me the results I needed -
http://scd.blaze.wpengine.com/wp-json/posts?type=listings&filter[listing_area]=channel
my post type being listings and the slug of my term channel
There are many examples of doing this in axml, but I would like to have a complete binding using code behind. To be honest, I would like to have NO axml, but seems like creating all the controls programmatically is a nightmare.
I first tried the suggestions at:
MvxListView create binding for template layout from code
I have my list binding from code-behind, and I get six rows (so source binding is working); but the cells itself does not bind.
Then at the following url:
Odd issue with MvvmCross, MvxListViewItem on Android
Stuart has the following comment: Have looked through. In this case, I don't think you want to use DelayBind. DelayBind is used to delay the binding action until next time the DataContext is set. In Android's MvxAdapter/MvxListItemView case, the DataContext is passed in the ctor - so DataContext isn't set again until the cell is reused. (This is different to iOS MvxTableDataSource).
So in essence, the only example I see shows DelayBind, which shouldn't work.
Can someone please show me some examples... thanks in advance.
Added reply to Comments:
Cheesebaron, first of all, a huge thank you and respect for all your contributions;
Now, why not use axml? Well, as programmers, we all have our own preferences and way of doing stuff - I guess I am old school where we didn't have any gui designer (not really true).
Real reasons:
Common Style: I have a setup where Core has all the style details, including what all the colors would be. My idea is, each platform would get the style details from core and update accordingly. It's easy for me to create controls with the correct style this way.
Copy-Paste across platform (which then I can even have as linked files if I wanted). For example, I have a login screen with web-like verification, where a red error text appears under a control; overall on that screen I have around 10 items that needs binding. I have already got iOS version working - so starting on Droid, I copied the whole binding section from ios, and it worked perfectly. So, the whole binding, I can make it same across all platform... Any possible error in my way will stop at building, which I think is a major advantage over axml binding. Even the control creation is extremely similar, where I have helpers with same method name.
Ofcourse I understand all the additional layout that has to be handled; to be honest, it's not that bad if one really think it through; I have created a StackPanel for Droid which is based on WP - that internally handles all the layouts for child views; so for LinearLayout, all I do is setup some custom parameters, and let my panel deal with it. Relative is a different story; so far, I have only one screen that's relative, and I can even make it Linear to reduce my additional layout code.
So, from my humble point of view, for my style, code-behind creation allows me to completely copy all my bindings (I do have some custom binding factories to allow that), copy all my control create lines; then only adding those controls to the view is the only part that is different (then again, droid and WP are almost identical). So there is no way I can miss something on one platform and all are forced to be the same. It also allows me to change all the styles for every platform just by changing the core. Finally, any binding error is detected during compile - and I love that.
My original question wasn't about NOT using axml... it was on how to use MvxListView where all the binding is done in code-behind; as I have explained, I got the list binding, but not the item/cell binding working.
Thanks again in advance.
Here is part of my LoginScreen from droid; I think it's acceptable amount of code for being without axml file.
//======================================================================================================
// create and add all controls
//======================================================================================================
var usernameEntry = ControlHelper.GetUITextFieldCustom(this, "Username.", maxLength: 20);
var usernameError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Username);
var passwordEntry = ControlHelper.GetUITextFieldCustom(this, "Password.", maxLength: 40, secureTextEntry: true);
var passwordError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Password);
var loginButton = ControlHelper.GetUIButtonMain(this);
var rememberMe = new UISwitch(this);
var joinLink = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var copyRightText = ControlHelper.GetUILabel(this, textAlignment: UITextAlignment.Center);
var copyRightSite = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var layout = new StackPanel(this, Orientation.Vertical)
{
Spacing = 15,
SubViews = new View[]
{
ControlHelper.GetUIImageView(this, Resource.Drawable.logo),
usernameEntry,
usernameError,
passwordEntry,
passwordError,
loginButton,
rememberMe,
joinLink,
ControlHelper.GetSpacer(this, ViewGroup.LayoutParams.MatchParent, weight: 2),
copyRightText,
copyRightSite
}
};
I just came across a similar situation myself using Mvx4.
The first link you mentioned had it almost correct AND when you combine it from Staurts comment in the second link and just remove the surrounding DelayBind call, everything should work out ok -
public class CustomListItemView
: MvxListItemView
{
public MvxListItemView(Context context,
IMvxLayoutInflater layoutInflater,
object dataContext,
int templateId)
: base(context, layoutInflater, dataContext, templateId)
{
var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
set.Bind(control).To(vm => vm.Title);
set.Apply();
}
}
p.s. I have asked for an Edit to the original link to help others.
Tumblr is really impressive in the sense that it allows users to customize their profiles and such. You're allowed to edit the HTML and CSS of your profile.
This is something I want to apply to my own site. However, I'm sure that this will be a big burden on security.
Does anyone have any tips or precautions for a feature like Tumblr's? Also, is it advisable to store the editable HTML and CSS in a database? Thank you :D
P.S.
What about server-side scripting? Lets say I wanted to grant the option of allowing the user to script a button that does something to the database. Any thoughts on how to do this?
This is a very difficult thing to get right, in my experience, if you want users to be able to use absolutely all of HTML/CSS. What you could do, however, is strip all CSS and HTML attributes, and only put "safe" code on a whitelist.
Examples
<p>This is legal code.</p>
<p><a onload="alert('XSS!')">The attribute should be filtered out</a></p>
<p>This is a legal link.
Of course you should still sanitize the href attribute!</p>
<h1>This is bad, because the rest of the page is going to huge,
so make sure there's a closing tag
<style>
.blue {
color: #00f; // keep this (by whitelist)
strange-css-rule: possibly-dangerous; // Filter this out!
}
</style>
Those are just some of the pitfalls you can encounter, though.
I'm not familiar with Tumblr, but I'm pretty sure they're doing something similar to this.
As for the database question, of course you can store HTML and CSS in a database, many systems do this. In your case, you would just need one representation anyway, anything else would just confuse the user ("Why is my CSS rule not applied; it's right there in the code!")
If you are using php then, for database issue you can use mini API system. For example, you want user to allow comment on something and save it in your database, then you can use API like this.
First, api.php file, (URL Location: http://yoursite.com/api.php)
<?php
// ID and Key can be different for all users.
// id = 1234
// key = 'secret_key'
// function = name of the function, user can call
// option = parameter passed to the function
// Now check if id, key, function and option are requested and then
// call function if it exists.
if(isset($_GET['id'], $_GET['key'], $_GET['function'], $_GET['option']) {
$id = $_GET['id'];
$key = $_GET['key'];
if($id == '1234' && $key == 'secret_key') {
// define all functions here
function make_comment($option) {
...code for saving comment to database...
}
if(function_exists($_GET['function'])) {
$_GET['function']($_GET['option']);
}
}
}
?>
Then uesr can call this function from any button using simple call to the API, like
<a href='http://yoursite.com/api.php?id=1234&key=secret_key&function=make_comment&option=i_am_comment'></a>
I need to have a place to put some common functions that various view scripts will use such as creating some html by passing it a variable. I know about using helpers, but I want to be able to put many functions inside it not just one helper for each function.
Is it a plugin that I need to create?
thanks
A view helper is definitively the way to go. You can group a collection of similar or related functions using a simple design pattern for your view helper:
class App_View_Helper_Example extends Zend_View_Helper_Abstract
{
/**
* #param mixed|null $var
* #return App_View_Helper_Example
*/
public function example($var = null)
{
if ($var === null) {
return $this;
}
return $this->function1($var); // shortcut to method most used
}
public function function1($var)
{
return $this->view->escape($var);
}
public function function2($var1, $var2)
{
return $this->view->escape(sprintf('%s: %d', $var1, $var2));
}
// and so on...
}
This allows you to call your helper methods in your view like this:
$this->example($var);
$this->example()->function1($var);
$this->example()->function2($var1, $var2);
I used this approach for a Google Static Map helper which provides a centered()-method to display a map centered at a given location and a byMarkers()-method that displays a static map automatically centered and zoomed around a list of given markers.
The only problem you may encounter is keeping a state in your helper across different view scripts (e.g. when using layouts or partials) as the helper will be reconstructed with every single view script. To store state across these boundaries you'll have to resort to Zend_Registry or some static member field.
Hm, 'sounds a bit smelly'. What kind of functions would these be? If your design is ok, you shouldn't have a need for this kind of dustbin class. If it is really all about view then you should create view helpers, view partials or partial loops!
Sounds like what you want is the partial helper
If you don't want to use helpers (including the partial helper) you might as well just create some global functions, stick them in some file, and include it from your bootstrap file.
If you don't want a 'bunch of helpers' (which isnt really all that bad, as other posters have suggested), you can extend Zend_View, add the member methods, then set the Viewrenderer to your extended View.
http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.viewrenderer
Thank you all for the suggestions.
I discovered that you can use a view helper (like Stefan said) to store more functions by just returning $this from it like :
class Zend_View_Helper_FormVars
{
public function formVars(){
return $this;
}
public function openFormFieldGroup($name=''){
$html='';
$html.='<div id="formFldGrpWrapper">';
$html.='<div id="formFldGrpName"><b>'.$name.'</b></div>';
return $html;
}
}
Now in my view script I can use it like this:
$formVars=$this->formVars();
$html.=$formVars->openFormFieldGroup('General');
But I'm also interested in what Justin stated that I can have a common extended view helper?
That all my views or controllers can access for doing repetative tasks like some html divs/styles, etc.... How would I go about getting that set up?
thanks.
But I'm also interested in what Justin stated that I can have a common extended view helper? That all my views or controllers can access for doing repetative tasks like some html divs/styles, etc.... How would I go about getting that set up?
In the answers you ask this additional question. My answer deals with that too.
First you need to ask yourselves why you want to have multiple helper functions in one class
One reason is that you saves you extra classes and file includes. How could you do so?
If they are related you can put them into one view helper. But don't do things like
$this->htmlWrapper()->wrapParapgraph()->wrapContentBox()
->translateFromTo('NL', 'EN');
translateFromTo(…) has nothing to with html-wrapping.
If you want to optimize your includes, you can put you common helper code into a derived View-class:
class MyView extends Zend_View
{
function wrapParagraph() {}
function otherFunction() {}
}
This option is also mentioned in the zend framework guide as a means of optimization.
Please note that view helper reusability isn't affected by the choice to create view helpers as separate classes. You automatically get access to the current view oject if your helper extends Zend_View_Helper_Abstract.
class My_View_Helper extends Zend_View_Helper_Abstract
{
function wrapParagraph($content) {
// do something …
return $this->someOtherViewHelper();
}
}
Further you wrote
$formVars=$this->formVars();
This doesn't make sense actualy, since Zend_View registers only one view helper per view isntance.
$formVars=$this->formVars();
$formVars->doOneThing();
$formVars->doSecondThing();
is equivalent to
$this->formVars()->doOneThing();
$this->formVars()->doSecondThing();
The Singleton aspect has a severe impact on the way you design view helpers as you see.