I work on a Symfony1 application.
For part of the application we use the symfony admin generator which builds default actions and templates for a particular module.
The autogenerated action methods can be overridden in the child action class and the templates can be overridden, by making one with the same name in the module's template folder.
Local templates are used instead of the autogenerated ones, which are stored in a cache folder (I assume this is normal symfony behaviour).
apps/
my_app
modules/
post/
actions/
actions.class.php
lib/
templates/
...
cache/
my_app/
environment/
modules/
autoPostcd /
actions/
actions.class.php
lib/
templates/
indexSuccess.php
_part_1.php
_part_2.php
I am currently working on a separate application that is not using the admin generator.
But I have 3 modules that do very similar things, that I would like to share.
I have all 3 actions extending the same custom action class so that they all implement the same methods and share the ones that are identical.
The problem that I am having is sharing the templates.
The main templates and most of the partials can be reused as is.
apps/
other_app/
lib/
printingActions.class.php
modules/
ticket/
actions/
actions.class.php
lib/
templates/
printSuccess.php //exactly the same for all 3
_part_1.php
_part_2.php //exactly the same for all 3
_part_3.php
receipt/
actions/
actions.class.php
lib/
templates/
printSuccess.php //exactly the same for all 3
_part_1.php
_part_2.php //exactly the same for all 3
_part_3.php
voucher/
actions/
actions.class.php
lib/
templates/
printSuccess.php //exactly the same for all 3
_part_1.php
_part_2.php //exactly the same for all 3
_part_3.php
What I would like to do is pull out the common ones so that each module and any future modules with a similar interface, only have to have the partials with module specific information.
This would be my ideal setup:
apps/
other_app/
lib/
printingActions.class.php
printingCommonTemplates/
printSuccess.php //exactly the same for all 3
_part_2.php //exactly the same for all 3
modules/
ticket/
actions/
actions.class.php
lib/
templates/
_part_1.php
_part_3.php
receipt/
actions/
actions.class.php
lib/
templates/
_part_1.php
_part_3.php
voucher/
actions/
actions.class.php
lib/
templates/
_part_1.php
_part_3.php
I know this kind of thing can be done, since the admin generator does it, but after hours of digging, I can't find where exactly it does it.
Could someone point me in the right direction for this one?
Ideally, if there is a fallback template setting that I can set for a particular module or a filter class that I can extend to do what I need?
If you want to use a common module action class with a default layout you can use the following approach:
class printingActions extends sfActions {
public function preExecute() {
$this->setLayout('print_success_common');
}
public function executeIndex() {
}
}
Then in your module action you may have:
class ticketActions extends printingActions
{
public function executePrint(sfWebRequest $request)
{
$this->txt = 1234;
return $this->renderPartial('part_1', array('txt' => $this->txt));
}
}
You can use a different(common) layout from your action by using:
class ticketActions extends printingActions
{
public function executePrint(sfWebRequest $request)
{
$template = $this->getContext()->getConfiguration()->getTemplateDir('printing', 'print_success_common_alt.php');
$this->setLayout($template . '/print_success_common_alt');
...
$this->txt = 1234;
return $this->renderPartial('part_1', array('txt' => $this->txt));
}
}
I found a partial solution, to at least be able to share templates.
In the Partials section of the docs for symfony1, it mentions that there are 3 places that you can call partials from:
From the current module
From a different module in the same application
From the global template folder for the current application
So, what I can do is put the common partials in a single place and reference them from each of the modules that need to use them.
I can also pass in a variable with the current modules name, so that it can call module specific templates from within the common ones, dynamically.
I considered putting the common partials directly in the global template directory, but it would get messy and confusing if there were more than one type of module that did this.
The awkward work around was to create a directory inside the template directory, which I could put these files in.
apps/
other_app/
lib/
printingActions.class.php
modules/
ticket/
actions/
actions.class.php
lib/
templates/
printSuccess.php //common parts extracted to partial
_part_1.php
_part_3.php
receipt/
actions/
actions.class.php
lib/
templates/
printSuccess.php //common parts extracted to partial
_part_1.php
_part_3.php
voucher/
actions/
actions.class.php
lib/
templates/
printSuccess.php //common parts extracted to partial
_part_1.php
_part_3.php
templates/
_printing_common/
print_success_common.php //common parts of PrintSuccess extracted as partial
part_2.php //exactly the same for all 3
It created a less than ideal problem, of having to underscore the new directory and remove the underscore from the partials inside.
But, using this method I was able to share the common bits and have the module specific code be the only thing that needed to be specified in the module template directories.
Here is an example of the contents of some of these files:
apps/other_app/modules/ticket/templates/printSuccess.php
<?php
include_partial(
'global/printing_common/print_success_common',
array(
'moduleNameText' => $moduleNameText
)
);
apps/other_app/templates/_printing_common/print_success_common.php
...
<?php include_partial($moduleNameText.'/part_1',array('moduleNameText' => $moduleNameText)); ?>
...
<?php include_partial('global/printing_common/part_2',array('moduleNameText' => $moduleNameText)); ?>
...
<?php include_partial($moduleNameText.'/part_3',array('moduleNameText' => $moduleNameText)); ?>
This is not the ideal solution, so I will leave this question open to a better solution, but they is my work around until then.
Related
I was searching for an answer but could not get the solution for this exact case:
So, my project structure is like this
project/
myproject/
...
app/
...
views.py
...
logic/
do_stuff.py
db.sqlite3
manage.py
And this do_stuff.py contains a function call_me()
How can I call call_me() function from views.py (For example, upon a successful file upload)?
Many thanks!
Update:
I'm able to import a do_stuff() function from a single logic.py file from project/ like this: from .logic import do_stuff
But the problem is that the logic package is already written and has its folder structure.
I just thought of installing this package via settings.py, is there any way to do so?
Normally from project.logic.do_stuff import call_me should work in views.py. Have you tried?
In my Advent of Code repository I've had a utility library since last year and have been using stuff from that also this year.
This year I wanted to add a second one for loading the input files quicker. For some reason unittests and using it works for the old library but not for the second.
I tried to unify the two folders as much as possible until the Project.toml for instance are equal now.
The two directories look like this (ProblemParser failing and Utils working):
ProblemParser ⛔
├── Manifest.toml
├── Project.toml
├── src
│ └── ProblemParser.jl
└── test
├── Manifest.toml
├── Project.toml
└── runtests.jl
Utils ✅
├── Manifest.toml
├── Project.toml
├── src
│ └── Utils.jl
└── test
├── Manifest.toml
├── Project.toml
└── runtests.jl
Adding them to the Project (Manifest) works fine (other stuff left out):
(AoC 2021) pkg> status
Status `~/src/me/AoC/21/Project.toml`
[16064a1e] ProblemParser v0.1.0 `../ProblemParser`
[c4255648] Utils v0.1.0 `../Utils`
However trying to use ProblemParser doesn't go so well.
julia> using Utils
julia> # that worked
julia> using ProblemParser
ERROR: KeyError: key ProblemParser [16064a1e-6b5f-4a50-97c7-fe66cda9553b] not found
Stacktrace:
[1] getindex
# ./dict.jl:481 [inlined]
[2] root_module
# ./loading.jl:1056 [inlined]
[3] require(uuidkey::Base.PkgId)
# Base ./loading.jl:1022
[4] require(into::Module, mod::Symbol)
# Base ./loading.jl:997
The same yes/no happens when trying to run the tests.
(AoC 2021) pkg> activate ../Utils/
Activating project at `~/src/me/AoC/Utils`
(Utils) pkg> test
Testing Utils
Status `/tmp/jl_AGawpC/Project.toml`
[c4255648] Utils v0.1.0 `~/src/me/AoC/Utils`
[8dfed614] Test `#stdlib/Test`
Status `/tmp/jl_AGawpC/Manifest.toml`
[79e6a3ab] Adapt v3.3.1
----- 8< snipped 8< -----
[4536629a] OpenBLAS_jll `#stdlib/OpenBLAS_jll`
[8e850b90] libblastrampoline_jll `#stdlib/libblastrampoline_jll`
Testing Running tests...
Test Summary: | Pass Total
#something_nothing | 15 15
Testing Utils tests passed
(Utils) pkg> activate ../ProblemParser/
Activating project at `~/src/me/AoC/ProblemParser`
(ProblemParser) pkg> test
Testing ProblemParser
Status `/tmp/jl_6v5Y3D/Project.toml`
[16064a1e] ProblemParser v0.1.0 `~/src/me/AoC/ProblemParser`
[8dfed614] Test `#stdlib/Test`
Status `/tmp/jl_6v5Y3D/Manifest.toml`
[16064a1e] ProblemParser v0.1.0 `~/src/me/AoC/ProblemParser`
[2a0f44e3] Base64 `#stdlib/Base64`
----- 8< snipped 8< -----
[9e88b42a] Serialization `#stdlib/Serialization`
[8dfed614] Test `#stdlib/Test`
Testing Running tests...
ERROR: LoadError: ArgumentError: Package ProjectParser not found in current path:
- Run `import Pkg; Pkg.add("ProjectParser")` to install the ProjectParser package.
Stacktrace:
[1] require(into::Module, mod::Symbol)
# Base ./loading.jl:967
[2] include(fname::String)
# Base.MainInclude ./client.jl:451
[3] top-level scope
# none:6
in expression starting at /home/tsbr/src/me/AoC/ProblemParser/test/runtests.jl:1
ERROR: Package ProblemParser errored during testing
What is the difference between the two? What makes one work and the other not?
I just don't see it.
Ah, you have the module name defined wrong in src/ProblemParser.jl - the first line is module ProjectParser instead of module ProblemParser.
having below directory structure.
home/
└── jobs/
├── jobname1/
│ ├── builds/
│ └── config.xml
└── jobname2/
├── builds/
└── config.xml
having many job names under jobs folder.
I wish to copy all config.xml files to another backup directory without missing its jobname folder structure.
could you please help me understand how to use shutil libraray in more efficient way.
My target folder Backup structure something like below
Backup/
└── jobs/
├── jobname1/
│ └── config.xml
└── jobname2/
└── config.xml
Please help.
Please find below my actual requirement.
Algorithm to write python2.7 scrpt
1. git clone Backup folder , where Backup is empty folder
2. Find list of files having file name "config.xml in the HOME folder
3. Copy all config.xml files to Backup folder with out changing the folder structure
3.1. If config.xml is new file then git add all config.xml to git repository , and commit followed by git push
3.2. If config.xml is existing and unchanged then git push is not required
3.3. If config.xml is existing and modified then commit followed by git push
I found the logic. May be this might be useful to someone. Regret the code as it is novice level.
def walkfs(self,findfile):
## dictionary to store full path of each source findfile
matches_fullpath_dict = {}
## dictionary to store relative path of each findfile
matches_trunc_dict = {}
## dictionary to store full path of each target file location
matches_target_fullpath_dict = {}
i =0
source = self.jenkins_Home
destination = self.backupRepositoryPath
for root, dirnames, filenames in os.walk(source):
for filename in fnmatch.filter(filenames, findfile):
i=i+1
matches_fullpath_dict[i]=os.path.join(root, filename)
matches_trunc_dict[i]=os.path.join(root.replace(source,""), filename)
matches_target_fullpath_dict[i]=os.path.join( os.path.sep, destination + root.replace(source,""))
keys = matches_target_fullpath_dict.keys()
for key in keys:
if not os.path.exists(matches_target_fullpath_dict.get(key)):
try:
os.makedirs(matches_target_fullpath_dict.get(key))
except OSError:
pass
keys = matches_target_fullpath_dict.keys()
for key in keys:
shutil.copy2(matches_fullpath_dict.get(key,None), matches_target_fullpath_dict.get(key,None))
I'm a reader and a big fan of the popular book Two Scoops of Django.
The book is full of great ideas, but there is one which is not that clear to me.
The authors advice to create a static and a templates folder in the Django project root.
That template folder is meant for "site-wide templates" (stated at pag.24).
Plus at pag.162 they say that "templates should usually go into the root folder of the Django project... The only exception is when you bundle up an app into a third-party package".
They don't mention it explicitly in ch.12 but I guess it is good to create a folder for each app (with the same name as the app) in the templates root.
Let's suppose that in my icecreamratings Django project I have 2 apps:
flavors with 2 templates: new_flavor.html and details.html
profiles with 1 template: details.html
All templates inherit from base.html.
I guess they would suggest the following structure:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/
|-- templates/
|-- 404.html
|-- 500.html
|-- base.html
|-- flavors/ # same name as app flavor
| |-- new_flavor.html
| |-- details.html
|-- profiles/ # same name as app profiles
|-- details.html
Did I get it correctly?
On the other hand, the Django official docs suggests to create a static folder in each app and, inside it, a subfolder with the same name as the app, like: my_app/static/my_app/myimage.jpg.
So we have 2 different strategies: a unique template folder and many static folders (one in each app).
Having two different strategies is clearly a bad choice.
So, what do you think of storing in each app a template and static folder?
Something like this:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/ # site-wide static files
| |-- bootstrap/ # bootstrap source files
| |-- jquery/ # jquery source files
| |-- css/ # css files used by base.html (and others in templates root)
| |-- js/ # javascript files used base.html (and others in templates root)
| |-- img/ # img files files used base.html (and others in templates root)
|-- templates/ # site-wide templates
| |-- 404.html
| |-- 500.html
| |-- base.html
|-- flavors/ # an app
|-- static/
| |-- flavors/ # static files specific for this app
| |-- css/ # css files for flavor app templates
| |-- js/ # javascript files for flavor app templates
| |-- img/ # img files for flavor app templates
|-- templates/ # template files specific for this app
|-- new_flavor.html
|-- details.html
The django official doc does not suggest your to create a static folder in each app. Instead it prefer to store the static dir under the project dir.
Static file namespacing
Now we might be able to get away with putting our static files
directly in my_app/static/ (rather than creating another my_app
subdirectory), but it would actually be a bad idea. Django will use
the first static file it finds whose name matches, and if you had a
static file with the same name in a different application, Django
would be unable to distinguish between them. We need to be able to
point Django at the right one, and the easiest way to ensure this is
by namespacing them. That is, by putting those static files inside
another directory named for the application itself.
The official doc also answered your question about templates structure.
class app_directories.Loader
Loads templates from Django apps on the filesystem. For each app in
INSTALLED_APPS, the loader looks for a templates subdirectory. If
the directory exists, Django looks for templates in there.
This means you can store templates with your individual apps. This
also makes it easy to distribute Django apps with default templates.
The Two Scoops of Django is a great book. But you should read the official doc first.
About templates, as per Django official docs (https://docs.djangoproject.com/en/3.2/ref/templates/api/#loader-types):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], #add this line
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Each site should have its own domain, database, settings.py, urls.py, views.py and so on. As far as I understand, it's impossible, but I don't quite sure.
EDIT: jdi suggests to use different settings files with different apps. Can you explain, please, how to do it?
Additional problem is that I use Webfaction and after selecting existing Django webapp receive following error:
Site app with this Site, Path and Account already exists
So I need to know, is it limitation of Django or Webfaction.
Version of Django is 1.3
This project structure is for Django 1.4, though the concepts remain the same
You can do all of that, just not with a single process. Create a single virtualenv for your project, which can store a shared set of every lib you need. Then create different settings files for each site, which each load different django apps, all located within the project:
djangoProject
|- bin/
|- include/
|- lib/
|- manage.py
|- djangoProject/
|- settings_site1.py
|- settings_site2.py
|- settings_site3.py
|- wsgi_site1.py
|- wsgi_site2.py
|- wsgi_site3.py
|- site1_app/
|- models.py
|- views.py
|- urls.py
|- site2_app/
|- models.py
|- views.py
|- urls.py
|- site3_app/
|- models.py
|- views.py
|- urls.py
settings_site1.py (example)
...
# or you could make multiple urls_siteX.py files in the root
ROOT_URLCONF = 'djangoProject.site1_app.urls'
...
INSTALLED_APPS = (
...
'djangoProject.site1_app'
)
wsgi_site1.py (example)
...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoProject.settings_site")
...
But to be perfectly honest... all of this is even much more easily accomplished if you just create a single virtualenv with multiple django projects. Then you don't have to much with segregating your apps:
projectEnv
|- bin/
|- include/
|- lib/
|- project1/
|- manage.py
|- project1/
|- project2/
|- manage.py
|- project2/
|- project3/
|- manage.py
|- project3/
Either way you do it, I don't think it is necessary to think about trying to get them all to run under the same single process. Django isn't designed to do that. It is designed to let you run multiple processes on the same project, for different sites, via the sites framework.