There are good tutorials on how to create URL's in the controllers like this one. Examples are:
$this->uriBuilder->reset()->setTargetPageUid($page_uid)->setCreateAbsoluteUri(TRUE)->build();
$this->controllerContext->getUriBuilder()->reset()->setTargetPageUid($page_uid)->setArguments(array('person'=>$person->getUid())->buildFrontendUri();
In works from the controller. But I cannot do the same work in a repository. Error log say that reset() in first example and getUriBuilder in second example is called on a non-object when done from a repository.
Any clue on how to get past that?
First of all, you shouldn't do this. For creating URIs in Extbase, you need access to the current controller context, because there are several factors that go into creating an URI (currently called controller action, current host name, selected language, ...). If you would create URIs within your repository (i.e. your data access layer), you would generate a dependency to the HTTP routing layer of the Extbase framework. This is undesirable from an architectural point of view, because it can be argued that it violates separation of concerns and creates a messy cross-dependency.
That being said, if you still want to do this (instead of generating URIs in your controller, or -- better yet -- using a Fluid viewhelper): all you need for building URIs is an instance of the UriBuilder class. Nothing's stopping you from simply passing the controller's UriBuilder instance into the repository, for example as a parameter:
public function fooAction() {
$records = $this->myRepository->findRecordsWithUri($this->uriBuilder);
}
Within your repository function, then simply use the passed UriBuilder instance, just as you would in the controller.
Related
The question may sound funny but I think this should be possible.
What I want is to use a repository that is purely custom but is exposed just like a Repository. This service would have methods to get, save, delete and list objects where the data could be from any arbitrary source.
Looking through the code, I think it should be possible since methods are accessed using CrudMethods and RepositoryInvoker. I belief this requires an implementation of RepositoryFactoryInformation that will be discovered by Repositories. I started experimenting a bit and it looks like a full-blown spring-data-noop module.
Am I on the right track or is there an easier way to accomplish this?
I've ended up writing spring-data-custom to create fully customized spring-data repositories, allowing custom code to be used with spring-data-rest etc.
Enable custom repositories (#EnableCustomRepositories)
Annotate eligible entities (#Custom)
Create a repository (extend CustomRepository<T, ID>)
Add custom behavior:
Let repository extend a new interface with the Custom suffix
Create an implementation of the new interface with the Impl prefix
Add one or more CRUD methods named findOne, save, findAll, delete (see DefaultCrudMethods)
Add query methods annotated with #Query
Export repository using spring-data-rest
(copied from README)
As #wwadge correctly mentioned, spring-data-keyvalue is an alternative. Repositories have to implement KeyValueAdapter, e.g. MapKeyValueAdapter.
The easier way is to use spring-data-keyvalue project which does what you are trying to do.
I have a Meteor application using angular-meteor. I need now to load different angular modules depending on url. I added iron-router to my application to do so and I continue to handle routes for each module using ngRoute and anchor nav but it behaves strangely if url contains params. I made a small test case which is available here:
https://github.com/clouchtibat/iron-router-ng-route
If you click on 'truc' link and then on 'test', next routes changes will make controller be instantiated two times. It works if urls have no params.
I also tested with ui-router (in the with-ui-router branch) and the problem is the same but in addition view is duplicated.
Is this a bug in one of the two routers or is there something wrong with my implementation?
Take a look at this conversations in the angular-meteor Github issues:
https://github.com/Urigo/angular-meteor/issues/154
https://github.com/Urigo/angular-meteor/issues/493
I think it can help you with some directions.
I am also having some hard time with mixin angular-meteor and iron:router.
I have an existing domain, controller, view (auto generated for the latter) which works as expected in the browser.
It also works in curl if I have a URL of the .../user/show/1 or .../user/show ie I use an action which goes against REST principles.
So, I have added to the URLMappings file
"/rest/user/$id?"(resource: "user")
which uses the auto generated controller.
The now works with curl and .../rest/user/1 but not .../rest/user - it runs the show method rather than the index method. But .../user does go to index and return a list.
Though the browser continues to work, I notice that the URLs are of the rest/user variety.
So I get the feeling I have not really understood this. Can I have two rules in the URLMappings file that point to the same place? According to the Grails 2.4.4 docs, a url with no id will use the index() method yet ..../rest/user is not - it goes to show().
What I have works but I am pretty sure I have not done it right.
Regards,
John
I think grails creates Restful UserController for your domain. But if you already have got the UserController your own controller is used. You have to make it RESTFul. Take a look into 9.1.5.1 Extending the RestfulController super class
Also try to create urlmapping your controller manaully.
I am trying to imeplement a rest controller in grails 2.3.7. I have a simple controller, same actions as of a scaffolded one, nothing special.
My problem is I am not able to call show, update, delete and save actions via:
GET to localhost:8080/proj/domain/1
PUT/DELETE to localhost:8080/proj/domain/1
POST to localhost:8080/proj/domain
However it works when I add this to the url in UrlMappings.groovy
"/$controller/$action?/$id?(.$format)?"{
action = [POST:"save",GET:'show',DELETE:"delete"]
}
Im following with the grails doc's '8.1.5 Implementing REST controllers'. Based on my understanding of it, it should work without doing further configurations outside of the controller. Is modifying the url mappings necessary?
Yes adding a REST controller requires you to add a URL mapping for the resource, defining it as either singular or multi resource. Example:
“/foo”(resource:”foo”)
Or
“/foos”(resources:”foo”)
You can run url-mappings-report to see the URL mappings this produces
I have a problem. Basically, depending on whether a user goes to /es or /br or /cn etc on our website, we have different language template files. So far, we were using a custom templating engine to make this work, but are making a switch over to ZF. I can't seem to figure out how to get ZF to look for a view script in say cn/about-us if the language varuable is cn.
I can't (don't want to) use Zend_Translate for this because we have way too many translated template files and it's just not feasible using Zend_Translate for bazillion different files with multi-paragraphs of Chinese/Korean/Japanese, forgetting for a second that I don't speak those languages.
Can anybody help me?
You can write a controller plugin and use it's routeStartup() method to alter Zend_View settings (path to where your view scripts are located) and change the request uri before routing starts.
class My_Controller_Plugin_LanguageSwitcher extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
// examine the $_SERVER['REQUEST_URI'] and look for your language identifier
// fetch the View and set appropriate view scripts path using setScriptPath() method
// strip the language identifier from your REQUEST_URI
// change the request uri using $request->setRequestUri('your-new-uri-without-the-language- identifier');
}
}