url segments based redirect in modx Evo - .htaccess

let's say you have a url like this entered in modx Evo
www.zipit.com.org/reference/toamovie/
if I have a page called toamovie whose parent is called reference
but when someone enters that url I want it to do the equivalent of this
www.zipit.com.org/reference.html?myvar=toamovie
additionally, or more importantly,
I'd like the result to be more like this, where 12 wouls be the id of a document
`www.zipit.com.org/reference.html?myid=12'
I'm wondering if this is at all possible with modx Evolution.I'm thinking that this should be possible to do with some htaccess magic, well the first part anyway. How could I get a value that the document? This would be quite inaccessible with htaccess, so there would need to be another part to it that could plug into the database and get that value.

It should be possible with a custom plugin called on the "OnPageNotFound" event.
<?php
$url = $_SERVER['REQUEST_URI']; //get the url
//split the url into pieces and remove empty values
$pieces = array_filter(explode('/', $url));
//reset the array keys
$temp = array();
foreach ($pieces as $piece) {
$temp[] = $piece;
}
$pieces = $temp;
//basic checking of the url
if (count($pieces) == 2) {
$modx->sendRedirect('http://www.zipit.org/' . $pieces[0] .".html?myid=" . $pieces[1]);
}
?>
remember that plugins aren't wrapped in php tags.
also that this script will pass any incorrect urls to zipit.org. Some error handling is probably desireable.

Related

Kodi addons : how to correctly set an URL using xbmcplugin.addDirectoryItems and xbmcgui.ListItem?

I'm trying to update a plugin for Kodi 19 (and Python3).
But! Hell! Their documentation is a mess, and when you search the internet, a lot of code is outdated.
I cannot understand how correctly create a virtual folder with items using xbmcplugin.addDirectoryItems.
here's my (simplified) code:
this is my KODI menu function
def menu_live():
#this is were I get my datas (from internet)
datas = api.get_live_videos()
listing = datas_to_list(datas)
sortable_by = (xbmcplugin.SORT_METHOD_DATE,
xbmcplugin.SORT_METHOD_DURATION)
xbmcplugin.addDirectoryItems(common.plugin.handle, listing, len(listing))
xbmcplugin.addSortMethod(common.plugin.handle, xbmcplugin.SORT_METHOD_LABEL)
xbmcplugin.endOfDirectory(common.plugin.handle)
this builds a list of items for the virtual folder
def datas_to_list(datas):
list_items = []
if datas and len(datas):
for data in datas:
li = data_to_listitem(data)
url = li.getPath()
list_items.append((url, li, True))
return list_items
this create a xbmcgui.ListItem for our listing
def data_to_listitem(data):
#here I parse my data to build a xbmcgui.ListItem
label = ...
url = ...
...
list_item = xbmcgui.ListItem(label)
list_item.setPath(url)
return list_item
I don't understand well how to interact with the media url.
It seems that it can be defined within xbmcgui.ListItem using
list_item.setPath(url)
which seems ok to me (an url is set to the item itself)
but then, it seems that you also need to set the URL when adding the item to the list,
li = data_to_listitem(data)
list_items.append((url, li, True))
This looks weird since it means you have to know the URL outside the function that builds the item.
So currently, my workaround is
li = data_to_listitem(data)
url = li.getPath() #I retrieve the URL defined in the above function
list_items.append((url, li, True))
That code works. But the question is: if I can define an URL on the ListItem using setPath(), then why should I also fill that URL when appending the ListItem to my listing list_items.append((url, li, True)) ?
Thanks a lot !
I'm not exactly sure what your question is. But Video/audio add-on development is thoroughly explained in these guides: https://kodi.wiki/view/HOW-TO:Audio_addon, https://kodi.wiki/view/Audio-video_add-on_tutorial and https://kodi.wiki/view/HOW-TO:Video_addon. Have a look at them, especially the video-add-on guide (as pointed out by Roman), and try to adapt to your case.
Edit
But the question is: if I can define an URL on the ListItem using setPath(), then why should I also fill that URL when appending the
ListItem to my listing?
I'm far from an expert, but from my understanding and in the context of https://kodi.wiki/view/HOW-TO:Video_addon tutorial, the url in
list_items.append((url, li, is_folder))
is used to route your plugin to your playback function, as well as passing arguments to it (e.g. video url and possibly other useful stuff needed for playback). That is, the list item passed here doesn't need to have its path set.
ListItem.setPath(video_url)
on the other hand, is for resolving the video url and start the playback after you have selected an item.

Modx TV multi select list not saving values

I have a TV multi select list type that is evaluating a snippet:
#EVAL return $modx->runSnippet('getFeaturedResourceTree');
Evaluating this snippett:
<?php
$output = array();
$context = $modx->resource->get('context_key');
$sql = "select * from modx_site_content where context_key = '$context' order by `pagetitle`;";
$results = $modx->query($sql);
foreach($results as $result){
$output[] = $result['pagetitle'].'=='.$result['id'];
}
$output = implode('||', $output);
echo $output;
return;
This does work in the manager, I can select and pick multiple resources in the list. However, when I save the TV, nothing is actuially saved. the TV values are not present in the database and when I reload the resource, the TV field is blank.
what could the problem be here?
I'm fairly certain you can accomplish what you're trying to do with an #SELECT binding rather than #EVAL. This has 2 potential benefits:
#EVAL is Evil, LOL. Not all the time, mind you—there are certainly legitimate uses of #EVAL but I've personally always tried very hard to find an alternative, whenever I've considered using #EVAL.
The method I'm about to show you has worked for me in the past, so I'm speculating it will work for you.
#SELECT pagetitle, id FROM modx_site_content WHERE context_key = 'web' ORDER BY `pagetitle`
If you're using #EVAL because you have multiple contexts and you want the context of the Resource currently being edited, then you could use your Snippet, but I would try:
Rather than echo-ing your output, return it.
Call the snippet in a Chunk, and render the Chunk on a test page to ensure it has the output you want, formatted for the TV Input Options exactly the way it should be.
If the Chunk output passes the test, call it into the TV Input Options field with the #CHUNK binding.
One more note: I can't remember if the current Resource is available in the TV as $modx->resource or $resource, but that might be something you want to double check.

how do we add url parameters? (EJS + Node + Express)

I understood how we parse the url parameters in express routes, as in the example
How to get GET (query string) variables in Express.js on Node.js?
But where do the url parameters come from in the first place?
EDIT:
Apparently, I can build such a query with jquery (i.e $.get). I can append params to this query object. It s cool, but still i m trying to understand how we achieve this in the query that renders the page as a whole.
An example : when i choose the oldest tab below, how does SO add ?answertab=oldest to the url so it becomes :
https://stackoverflow.com/questions/30516497/how-do-we-add-url-parameters-ejs-node-express?answertab=oldest#tab-top
The string you're looking at is a serialization of the values of a form, or some other such method of inputing data. To get a sense of this, have a look at jQuery's built in .serialize() method.
You can construct that string manually as well, and that's pretty straight forward as well. The format is just ?var1=data1&var2=data2 etc. If you have a JSON object {"name": "Tim", "age": 22} then you could write a very simple function to serialize this object:
function serializeObject(obj) {
var str = "?";
for(var i = 0; i < Object.keys(obj).length; i++) {
key = Object.keys(obj)[i];
if (i === Object.keys(obj).length - 1)
str += encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
else
str += encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]) + "&";
}
return str;
}
Running seralizeObject({"name": "Tim", "age": 22}) will output '?name=Tim&age=22'. This could be used to generate a link or whatnot.
The page author writes them so. This is how they "come in the first place". The authors of an HTML page decide (or are told by website designers) where to take the user when he clicks on a particular anchor element on it. If they want users to GET a page with some query parameters (which their server handles), they simply add query string of their choice to the link's href attribute.
Take a look at the href attribute of the oldest tab you clicked:
<a
class="youarehere"
href="/questions/30516497/how-do-we-add-url-parameters-ejs-node-express?answertab=oldest#tab-top"
title="Answers in the order they were provided"
>
oldest
</a>
When you clicked it, the browser simply took you to path indicated in href attribute /questions/30516497/how-do-we-add-url-parameters-ejs-node-express?answertab=oldest#tab-top relative to the base URL http://stackoverflow.com. So the address bar changed.
stackoverflow.com may have its own system of generating dynamic HTML pages. Their administrators and page authors have configured their server to handle particular query parameters and have put in place their own methods to make sure that links on their pages point to the URL(including query string) they wish.
You need to provide URIs with query strings of your choice (you can build them using url.format and querystring.stringify) to your template system to render. Then make your express routes process them and generate pages depending on their value.

Extracting all text from a website to build a concordance

How can I grab all the text in a website, and I don't just mean ctrl+a/c. I'd like to be able to extract all the text from a website (and all the pages associated) and use it to build a concordance of words from that site. Any ideas?
I was intrigued by this so I've written the first part of a solution to this.
The code is written in PHP because of the convenient strip_tags function. It's also rough and procedural but I feel in demonstrates my ideas.
<?php
$url = "http://www.stackoverflow.com";
//To use this you'll need to get a key for the Readabilty Parser API http://readability.com/developers/api/parser
$token = "";
//I make a HTTP GET request to the readabilty API and then decode the returned JSON
$parserResponse = json_decode(file_get_contents("http://www.readability.com/api/content/v1/parser?url=$url&token=$token"));
//I'm only interested in the content string in the json object
$content = $parserResponse->content;
//I strip the HTML tags for the article content
$wordsOnPage = strip_tags($content);
$wordCounter = array();
$wordSplit = explode(" ", $wordsOnPage);
//I then loop through each word in the article keeping count of how many times I've seen the word
foreach($wordSplit as $word)
{
incrementWordCounter($word);
}
//Then I sort the array so the most frequent words are at the end
asort($wordCounter);
//And dump the array
var_dump($wordCounter);
function incrementWordCounter($word)
{
global $wordCounter;
if(isset($wordCounter[$word]))
{
$wordCounter[$word] = $wordCounter[$word] + 1;
}
else
{
$wordCounter[$word] = 1;
}
}
?>
I needed to do this to configure PHP for the SSL the readability API uses.
The next step in the solution would be too search for links in the page and call this recursively in an intelligent way to hance the associated pages requirement.
Also the code above just gives the raw data of a word-count you would want to process it some more to make it meaningful.

Specify a page for pagination - Laravel 4

I'm trying to "remember" the page the user was on as he browses through records so that when he returns to the list, he is returned to the page where he left off.
How do I change the "current page" value for paginator?
I've tried Input::set('page', $x); but there's no such function.
$_GET['page'] = $x; doesn't work too.
This the code:
$list = Publication::orderBy($this->data['sort_by'], $this->data['order_by']);
foreach ($this->data['filter_data'] AS $field => $value) {
$list->where($field, 'LIKE', "%$value%");
}
$this->data['list'] = $list->paginate(15);
I looked at the API --- turns out this is much easier now in 2014.
All you have to do is set
Paginator::setCurrentPage(2);
any time before you call ->paginate(), I believe, and it should override the page set (or not set) by ?page=.
You can adjust the page of the pagination environment through the DB connection.
DB::getPaginator()->setCurrentPage(2);
Not entirely sure but you might be able to go through your model with something like this.
Publication::getConnection()->setCurrentPage(2);
If the above isn't working (as it seems from your comment), then do it with an instance of Publication.
$publication = new Publication;
$publication->getConnection()->setCurrentPage(2);
$list = $publication->orderBy(...);
Try
$pager->setCurrentPage(2);

Resources