How to enhance the views in one Django app with code in a different app - django-templates

I am working on my first Django website and I've factored independent parts of the website into different apps. There is one fundamental app (I'll call it MainApp for the purposes of this question) on which other apps depend (I'll call the dependent apps AppX, AppY, and AppZ). The MainApp provides some views that I'd like dependent apps to contribute to, but I'm not sure how to do that without making MainApp dependent on AppX, AppY, and AppZ.
Let's say that MainApp has a view at URL /MainApp/TheView/. Does Django provide any mechanism that could be used as "hooks" such that App[XYZ] could inject additional content into /MainApp/TheView/? I.e. is there a way to create MainApp views such that they can easily be extended by other arbitrary apps?

Here's what I ended up doing:
First I added an extra_content_providers attribute to the view class in MainApp. It will contain references to extra content providers. The get method fetches the extra content and passes it along to the template.
class SpamView(View):
extra_content_providers = []
def get(self, request, ...):
...
extra_content = ""
for provider in self.extra_content_providers:
extra_content += provider(...)
params = {..., 'extra_content': extra_content}
return render(request, 'example.html', params)
Then I defined a decorator next to the view class:
def spamview_content_provider(f):
SpamView.extra_content_providers.append(f)
return f
Finally, AppX defined its contribution this way:
from MainApp.views import spamview_content_provider
#spamview_content_provider
def x_content(...):
return "Hello, I'm X."
This is a plain-old Python solution and it lets App[XYZ] provide extra content to MainApp views without introducing any new inter-app dependencies.

Related

How The Form Validation Is Done In JHIpster Front End?

I need to modify a form validation because some of the inputs are generated by the system instead of human input, those input fields will be filled in a controller. In other words, its DTO has fewer fields with validation constraints than the entity class. I am investigating
$v.myEntity.$invalid
I have a look at all related typescript files and don't see how it is done. Vue is the framework for the front end. I assume that it is the same for the front end regardless of the Javascript framework.
JHipster + Vue uses vuelidate for form validation. Look for an object called validations near the top of your .component.ts files.
Something like this:
const validations: any = {
testEntity: {
testField: {
required,
},
},
};
For example, to make testField no longer required on the front end, remove required, on that .component.ts and the required keyword on the corresponding input on your .vue file.
Remember to also remove the #NotNull on the entity DTO so it's not rejected, and then you can fill it up with whatever you need on the server side.

Same paginator for every controller in ZF2

I'm writing my first app in ZF2, and I want to create pagination system.
Currently, I have something like this in my controllers:
$pagLimit = $this->params()->fromQuery('limit', 1000);
$pagPage = $this->params()->fromQuery('page', 1);
$orderDir = $this->params()->fromQuery('dir', 'ASC');
$orderBy = $this->params()->fromQuery('column', 'id');
$result = $this->getMapper()->getList($orderDir, $orderBy);
$paginator = new Paginator(new ArrayAdapter($result));
$paginator->setItemCountPerPage($pagLimit);
$paginator->setCurrentPageNumber($pagPage);
I think that my solution is not quite good..
If I want to change e.g. default limit of items per page, I have to modify all my controllers. Also, I have to remember to send two arguments for all mapper methods which are getting lists of data.
My first thought was to use inheritance ("MyController" with methods like: setPaginationParams(), and setPaginator($data)).
Then I would have to remember to invoke "my controller" methods in every controller.
But maybe there is a better way to implement the same paginator for every controller in my module? MVC event? Create custom class and use DI?
What is the best way to implement this functionality?
Could you just give me some hints?
I'm new to ZF2 and OOP concepts. :(
You could always extend the paginator with your own, and have default values set.
You could even just pass in the request object or params object and then let the Paginator internally handle some things for you to save setting up default values etc.

Yii global variables and setting issue

I am developing a social networking website using Yii. While frequently using the following things I am having great data manageability issue.
- User ID
- Current user ID (the user which profile is the owner viewing)
- Is owner???
where can I define these things.
I would something like
if(Yii::app()->owner==ME){
//do something
}
// and similarly
if($this->isMyFreind(<Current user ID>){
}
// $this(CanIView()){
}
I want these functions to be public for any page? But how?
In other words
Where can I put my library which contains my own favorite functions like text shortening, image cropping, date time format etc etc??
In Yii, you can do achieve this by making a class (under protected/compoents) which inherits
CApplicationComponent
class. And then you call any property of this class globally as a component.
class GlobalDef extends CApplicationComponent {
public $aglobalvar;
}
Define this class in main config under components as:
'globaldef' => array('class' => 'application.components.GlobalDef '),
And you can call like this:
echo Yii::app()->globaldef->aglobalvar;
Hope that can help.
According to the MVC model, things like image cropping or date time formats would go in models. You would simply create models for that.
I usually use a globals.php file with all my common functions
In the index.php (yip the one in the root):
$globals='protected/globals.php';
require_once($globals);
I can then call my global functions anywhere. For example, I shorten certain Yii functions like:
function bu($url=null){
static $baseUrl;
if ($baseUrl===null)
$baseUrl=Yii::app()->request->baseUrl;
return $url===null ? $baseUrl : $baseUrl.'/'.ltrim($url,'/');
}
So I can then call the Yii::app()->request->baseUrl by simply calling bu()

How do you check if the current page is the frontpage using YII?

Drupal has a function called "drupal_is_front_page". Does YII have something similar to deal with navigation in this way?
Unfortunately not. And while the information needed to piece this together is available, doing so is really more pain than it should be.
To begin with, the front page is defined by the CWebApplication::defaultController property, which can be configured as discussed in the definitive guide. But there's a big issue here: defaultController can in reality be any of the following:
a bare controller name, e.g. site
a module/controller pair, e.g. module/site
a controller/action pair, e.g. site/index
a module/controller/action tuple, e.g. module/site/index
If you have specified the defaultController as #4 (which is the same as #3 if your application does not include any modules) then everything is easy:
function is_home_page() {
$app = Yii::app();
return $app->controller->route == $app->defaultController;
}
The problem is that if defaultController is specified as #1 or #2 then you have to examine a lot of the runtime information to convert it to form #3 or #4 (as appropriate) so that you can then run the equality check.
Yii of course already includes code that can do this: the CWebApplication::createController method, which can accept any of the valid formats for defaultController and resolve that to a controller/action pair (where controller is dependent on the module, if applicable). But looking at the source doesn't make you smile in anticipation.
To sum it up: you can either assume that defaultController will always be fully specified and get the job done with one line of code, or borrow code from createController to determine exactly what defaultController points to (and then use the one line of code to check for equality).
I do not recommend looking into solutions based on URLs because the whole point of routes is that different URLs can point to the same content -- if you go that way, can never be sure that you have the correct result.
In my experience, there is no such function in Yii. However, you can retrieve the followings:
base url: Yii::app()->request->baseUrl
current URL : Yii::app()->request->requestUri.
current page controller with Yii::app()->getController()->getAction()->controller->id .
With these APIs, it should be possible to find out whether the current page is front page.
another simple idea:
in your action (that one you use to present your 'main front page'), you could set up a variable using a script in its view:
Yii::app()->getClientScript()->registerScript("main_screen",
"var main_front_page = true;",CClientScript::POS_BEGIN);
put that code in the "main view", (the rest view pages dont have this piece of code).
so when you need to check if a page is the "main page" you could check for it using javascript, quering for:
if(main_front_page){..do something..}.
if you need to recognize the main page in php (in server side), use the method proposed by Jon.
another solution, based on a common method for your controller:
Your controllers all of them must extend from CController, but, when you build a new fresh yii application Gii creates a base Controller on /protected/components/Controller.php so all your controllers derives from it.
So, put a main attribute on it, named:
<?php
class Controller extends CController {
public $is_main_front_page;
public function setMainFrontPage(){ $this->is_main_front_page = true; }
public function getIsMainFrontPage(){ returns $this->is_main_front_page==true; }
}
?>
well, when you render your main front page action, set up this core varible to true:
<?php
class YoursController extends Controller {
public function actionPrimaryPage(){
$this->setMainFrontPage();
$this->render('primarypage');
}
public function actionSecondaryPage(){
$this->render('secondarypage');
}
}
next, in any view, you could check for it:
<?php // views/yours/primaryview.php
echo "<h1>Main Page</h1>";
echo "is primary ? ".$this->getIsMainFrontPage(); // must say: "is primary ? true"
?>
<?php // views/yours/secondaryview.php
echo "<h1>Secondary Page</h1>";
echo "is primary ? ".$this->getIsMainFrontPage(); // must say: "is primary ? false"
?>

ASP.net MVC: Execute Razor from DB String?

I was thinking about giving end users the ability to drop Partial Views (controls) into the information being stored in the database. Is there a way to execute a string I get from the database as part of the Razor view?
Update (I forgot all about this)
I had asked this question previously (which lead me to create RazorEngine) Pulling a View from a database rather than a file
I know of at least two: RazorEngine, MvcMailer
I have a bias towards RazorEngine as it's one that I've worked on but I have a much simpler one at Github called RazorSharp (though it only supports c#)
These are all pretty easy to use.
RazorEngine:
string result = RazorEngine.Razor.Parse(razorTemplate, new { Name = "World" });
MvcMailer
I haven't used this one so I can't help.
RazorSharp
RazorSharp also supports master pages.
string result = RazorSharp.Razor.Parse(new { Name = "World" },
razorTemplate,
masterTemplate); //master template not required
Neither RazorSharp, nor RazorEngine support any of the Mvc helpers such as Html and Url. Since these libraries are supposed to exist outside of Mvc and thus require more work to get them to work with those helpers. I can't say anything about MvcMailer but I suspect the situation is the same.
Hope these help.