Use latest form text

* Take the opportunity to reformat the source to not have so many hugely long lines.
* Put a few things through gettext that weren't going through it before
* Move 'Hold down Ctrl to select multiple files at once.' text to widget, out of
  help text for each individual control.
This commit is contained in:
Anna Sidwell 2019-04-07 15:55:29 +01:00
parent dc84e1a09a
commit 5cc0b7cdc1
6 changed files with 238 additions and 160 deletions

View File

@ -253,6 +253,16 @@ class MultipleFilesWidget {
} }
$(function() { $(function() {
// Display OS-specific stuff
function os_class() {
if (navigator.platform.indexOf("Win") != -1) return "os-windows";
if (navigator.platform.indexOf("Mac") != -1) return "os-mac";
return "os-other";
}
document.querySelector('body').classList.add(os_class())
// Get the CSRF token for form submitting
let csrf_token = document.querySelector("[name=csrfmiddlewaretoken]").value let csrf_token = document.querySelector("[name=csrfmiddlewaretoken]").value
window.images = new MultipleFilesWidget( window.images = new MultipleFilesWidget(

View File

@ -18,13 +18,14 @@ from .widgets import JSONFileListWidget
SECTOR_HELP = { SECTOR_HELP = {
'RN': _("Including electricity, heat or combined heat and power generation"), 'RN': _("Including electricity, heat or combined heat and power generation"),
'PG': '', 'PG': '',
'ST': _('Biological, chemical, electrical, electromagnetic, electrochemical, mechanical including gravitational potential, thermal etc.'), 'ST': _('Biological, chemical, electrical, electromagnetic, electrochemical,'
' mechanical including gravitational potential, thermal, etc.'),
'SM': _("Including supply of minerals"), 'SM': _("Including supply of minerals"),
'MA': '', 'MA': '',
} }
POWER_TECHNOLOGY_HELP = { POWER_TECHNOLOGY_HELP = {
'PT': _('Lines, transformers, machinery etc.'), 'PT': _('Lines, transformers, machinery, etc.'),
'HN': _('District heating/cooling, etc.'), 'HN': _('District heating/cooling, etc.'),
'OT': '', 'OT': '',
} }
@ -58,7 +59,9 @@ class PointOfInterest(forms.models.ModelForm):
self.helper.include_media = False self.helper.include_media = False
self.helper.form_action = reverse('point-of-interest-form') self.helper.form_action = reverse('point-of-interest-form')
self.helper.add_input(Submit('submit', _('Submit'), css_class='btn-success center-block')) self.helper.add_input(
Submit('submit', _('Submit'), css_class='btn-success center-block')
)
class Meta: class Meta:
model = PointOfInterest model = PointOfInterest
@ -192,6 +195,8 @@ class LongCaseStudyForm(BaseCaseStudyForm):
) )
shapefiles = forms.FileField( shapefiles = forms.FileField(
label=CaseStudy.shapefiles_label,
help_text=CaseStudy.shapefiles_help_text,
widget=BootstrapClearableFileInput(attrs={ widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'), 'url': reverse_lazy('files:upload'),
'field': 'shapefiles_files', 'field': 'shapefiles_files',
@ -385,10 +390,18 @@ class LongCaseStudyForm(BaseCaseStudyForm):
), ),
Tab( Tab(
_("Socio-environmental analysis"), _("Socio-environmental analysis"),
HTML("<p>" + _("In the following, we expect the analysis to reflect the perspective of the organization(s) or person(s) describing the case.") + "</p>"), HTML(
"<p>" +
_("In the following, we expect the analysis to reflect the"
" perspective of the organization(s) or person(s) describing"
" the case.") + "</p>"
),
'positive_or_negative', 'positive_or_negative',
Div( Div(
HTML("<label class='col-md-3 control-label'>What kind of case is this entry about?</label>"), HTML(
"<label class='col-md-3 control-label'>" +
_("What kind of case is this entry about?") +
"</label>"),
Div( Div(
'positive_case_type', 'positive_case_type',
'negative_case_reasons', 'negative_case_reasons',
@ -407,7 +420,6 @@ class LongCaseStudyForm(BaseCaseStudyForm):
'who_has_been_involved', 'who_has_been_involved',
'participation_mechanisms', 'participation_mechanisms',
'identified_partnerships', 'identified_partnerships',
'wants_conversation_with_ojuso',
Div( Div(
css_class="common_questions" css_class="common_questions"
), ),

View File

@ -76,7 +76,7 @@ class CaseStudy(models.Model):
TYPE_OF_ECOSYSTEM_CHOICES = ( TYPE_OF_ECOSYSTEM_CHOICES = (
('MARINE', _('Marine (e.g. ocean, sea)')), ('MARINE', _('Marine (e.g. ocean, sea)')),
('FRESH', _('Freshwater (e.g. freshwater, lake)')), ('FRESH', _('Freshwater (e.g. river, lake)')),
('FOREST', _('Forest/jungle')), ('FOREST', _('Forest/jungle')),
('AGRI', _('Agricultural land')), ('AGRI', _('Agricultural land')),
('GRASS', _('Grassland')), ('GRASS', _('Grassland')),
@ -94,7 +94,7 @@ class CaseStudy(models.Model):
) )
PROJECT_STATUS_CHOICES = ( PROJECT_STATUS_CHOICES = (
('INIT', _('Initiation/ideation')), ('INIT', _('Initial/conceptual')),
('PROJCD', _('In planning and design')), ('PROJCD', _('In planning and design')),
('FAIL', _('Failed')), ('FAIL', _('Failed')),
('UCONST', _('Under construction')), ('UCONST', _('Under construction')),
@ -119,7 +119,6 @@ class CaseStudy(models.Model):
('EC', _('European Commission (EC)')), ('EC', _('European Commission (EC)')),
('EIB', _('European Investment Bank (EIB)')), ('EIB', _('European Investment Bank (EIB)')),
('IADB', _('Inter-American Development Bank Group (IDB, IADB)')), ('IADB', _('Inter-American Development Bank Group (IDB, IADB)')),
('IFFIm', _('International Finance Facility for Immunisation (IFFIm)')),
('IFAD', _('International Fund for Agricultural Development (IFAD)')), ('IFAD', _('International Fund for Agricultural Development (IFAD)')),
('IIB', _('International Investment Bank (IIB)')), ('IIB', _('International Investment Bank (IIB)')),
('IsDB', _('Islamic Development Bank (IsDB)')), ('IsDB', _('Islamic Development Bank (IsDB)')),
@ -141,9 +140,9 @@ class CaseStudy(models.Model):
) )
GENERATION_TYPE_CHOICES = ( GENERATION_TYPE_CHOICES = (
('POW', _('Power')), ('POW', _('Electricity')),
('HOT', _('Heat/Cool')), ('HOT', _('Heat/Cold')),
('CHP', _('Combined Heat/Cool and Power (CHP)')), ('CHP', _('Combined Heat/Cold and Power (CHP, CCP or CCHP)')),
) )
GENERATION_TECHNOLOGY_CHOICES = ( GENERATION_TECHNOLOGY_CHOICES = (
@ -151,7 +150,7 @@ class CaseStudy(models.Model):
('GEOT', _('Geothermal electricity')), ('GEOT', _('Geothermal electricity')),
(_('Hydro'), ( (_('Hydro'), (
('uHYD', _('Micro hydro (<100kW)')), ('uHYD', _('Micro hydro (<100kW)')),
('SHYD', _('Small-scale hydro (<1MW)')), ('SHYD', _('Small-scale hydro (100kW-1MW)')),
('MHYD', _('Medium-scale hydro (1-30MW)')), ('MHYD', _('Medium-scale hydro (1-30MW)')),
('LHYD', _('Large-scale hydro (>30MW - often not considered renewable)')), ('LHYD', _('Large-scale hydro (>30MW - often not considered renewable)')),
)), )),
@ -173,11 +172,11 @@ class CaseStudy(models.Model):
('SSWE', _('Small-scale wind (<500kW)')), ('SSWE', _('Small-scale wind (<500kW)')),
('LSWE', _('Large-scale wind (>500kW)')) ('LSWE', _('Large-scale wind (>500kW)'))
)), )),
('OTHR', _('Other (tidal, wave, etc.)')) ('OTHR', _('Other'))
) )
POWER_TECHNOLOGY_CHOICES = ( POWER_TECHNOLOGY_CHOICES = (
('PT', _('Electrical power transmission')), ('PT', _('Electrical power transmission/distribution')),
('HN', _('Heat networks')), ('HN', _('Heat networks')),
('OT', _('Other')), ('OT', _('Other')),
) )
@ -195,15 +194,18 @@ class CaseStudy(models.Model):
('BER', _('Beryllium')), ('BER', _('Beryllium')),
('CAD', _('Cadmium')), ('CAD', _('Cadmium')),
('CHR', _('Chromium')), ('CHR', _('Chromium')),
('COK', _('Coking')), ('COK', _('Coking coal (for steel)')),
('COA', _('Coal (for steel)')),
('COP', _('Copper')), ('COP', _('Copper')),
('GAL', _('Gallium')), ('GAL', _('Gallium')),
('GER', _('Germanium')), ('GER', _('Germanium')),
('GLD', _('Gold')), ('GLD', _('Gold')),
('HRE', _('Heavy rare earth elements (gadolinium, terbium, dysprosium, holmium, erbium, thulium, ytterbium, lutetium, yttrium, scandium)')), ('HRE', _(
'Heavy rare earth elements (gadolinium, terbium, dysprosium, holmium,'
' erbium, thulium, ytterbium, lutetium, yttrium, scandium)')),
('IRN', _('Iron')), ('IRN', _('Iron')),
('LRE', _('Light rare earth elements (lanthanum, cerium, praseodymium, neodymium, promethium, samarium, europium)')), ('LRE', _(
'Light rare earth elements (lanthanum, cerium, praseodymium, neodymium,'
' promethium, samarium, europium)')),
('LED', _('Lead')), ('LED', _('Lead')),
('LIT', _('Lithium')), ('LIT', _('Lithium')),
('MAN', _('Manganese')), ('MAN', _('Manganese')),
@ -211,7 +213,9 @@ class CaseStudy(models.Model):
('MOL', _('Molybdenum')), ('MOL', _('Molybdenum')),
('NIC', _('Nickel')), ('NIC', _('Nickel')),
('NIO', _('Niobium')), ('NIO', _('Niobium')),
('PGM', _('Platinum group metals (ruthenium, rhodium, palladium, osmium, iridium, and platinum)')), ('PGM', _(
'Platinum group metals (ruthenium, rhodium, palladium, osmium,'
' iridium, and platinum)')),
('RHE', _('Rhenium')), ('RHE', _('Rhenium')),
('SIL', _('Silicon')), ('SIL', _('Silicon')),
('SIV', _('Silver')), ('SIV', _('Silver')),
@ -227,13 +231,13 @@ class CaseStudy(models.Model):
) )
USE_IN_ENERGY_ECONOMY_CHOICES = ( USE_IN_ENERGY_ECONOMY_CHOICES = (
('CPV', _('Concentrated solar power (CSP)')), ('CPV', _('Concentrated solar power (CSP) tower')),
('EPT', _('Electrical power transmission infrastructure')), ('EPT', _('Electrical power transmission/distribution infrastructure')),
('ESS', _('Energy storage')), ('ESS', _('Energy storage')),
('GGM', _('Geothermal')), ('GGM', _('Geothermal')),
('HGM', _('Hydropower')), ('HGM', _('Hydropower')),
('HNT', _('Heat networks')), ('HNT', _('Heat networks')),
('SPM', _('Solar PV')), ('SPM', _('Solar photovoltaic')),
('STM', _('Solar thermal systems')), ('STM', _('Solar thermal systems')),
('WTM', _('Wind power')), ('WTM', _('Wind power')),
('ESS', _("Don't know")), ('ESS', _("Don't know")),
@ -243,7 +247,7 @@ class CaseStudy(models.Model):
MANUFACTURING_TYPE_CHOICES = ( MANUFACTURING_TYPE_CHOICES = (
('GENERATE', _('Manufacturing of renewable energy generation equipment')), ('GENERATE', _('Manufacturing of renewable energy generation equipment')),
('TRANSSTORE', _('Manufacturing of energy transmission or storage equipment')), ('TRANSSTORE', _('Manufacturing of energy transmission or storage equipment')),
('RECYCLE', _('Recycling / reusing equipment or raw materials')), ('RECYCLE', _('Recycling/reusing equipment or raw materials')),
('DISPOSAL', _('Disposal of equipment')), ('DISPOSAL', _('Disposal of equipment')),
('OTHER', _('Other')), ('OTHER', _('Other')),
) )
@ -272,23 +276,31 @@ class CaseStudy(models.Model):
POSITIVE_CASE_TYPE_CHOICES = ( POSITIVE_CASE_TYPE_CHOICES = (
('CREP', _('Community project (co-)owned by individuals')), ('CREP', _('Community project (co-)owned by individuals')),
('EACP', _('Community project owned by not-for-profit organizations and/or serving the public interest')), ('EACP', _(
'Community project owned by not-for-profit organizations and/or serving'
' the public interest')),
('PSEP', _('Public/state (federal, state, municipal) project')), ('PSEP', _('Public/state (federal, state, municipal) project')),
('CORS', _('Reuse / recycling / circular economy project')), ('CORS', _('Circular economy project / Reuse / Recycling')),
) )
NEGATIVE_CASE_REASONS_CHOICES = ( NEGATIVE_CASE_REASONS_CHOICES = (
('VOLR', _('Violation of land rights')), ('VOLR', _('Violation of land rights')),
('VOHR', _('Violation of fundamental human rights, indigenous rights and/or other collective rights')), ('VOHR', _(
('EIMP', _('Environmental impacts (severe impacts on ecosystems / violation of laws,' 'Violation of fundamental human rights, indigenous rights and/or other'
' plans or programs of environmental conservation or territorial governance systems,' ' collective rights')),
' etc.')), ('EIMP', _(
('NCUL', _('Negative cultural impacts (erosion/destruction of bio-cultural heritage,' 'Environmental impacts (severe impacts on ecosystems / violation of laws'
' impacts on sacred land, etc.)')), ' plans or programs of environmental conservation, etc.')),
('AGGR', _('Aggression/threats to community members opposed to the project, collaboration' ('NCUL', _(
' with organized crime, etc.')), 'Negative cultural impacts (erosion/destruction of bio-cultural heritage,'
' impacts on sacred land, etc.)')),
('AGGR', _(
'Aggression/threats to community members opposed to the project,'
' collaboration with organized crime, etc.')),
('ALAB', _('Abusive labour practices')), ('ALAB', _('Abusive labour practices')),
('CRUP', _('Corruption and/or irregular permitting or contracting, conflicts of interest, etc.')), ('CRUP', _(
'Corruption and/or irregular permitting or contracting, conflicts of'
' interest, etc.')),
) )
# Dynamically generate a list of choices 40 years prior and after the current year. # Dynamically generate a list of choices 40 years prior and after the current year.
@ -329,16 +341,27 @@ class CaseStudy(models.Model):
verbose_name=_("Project location") verbose_name=_("Project location")
) )
shapefiles_label = _(
"Do you have geographic information files about the territory impacted by"
" this project?"
)
shapefiles_help_text = _(
"For example, of the limits of the land within which a project is taking"
" place, or of sites of particular importance. You can upload data in"
" different formats (ESRI Shapefiles with file extensions like .cpg, .dbf,"
" .prj, .qpj, .shp, .shx., or GeoPackage gpkg, GeoJSON, KML, GML, etc.)."
" Write to database@ojuso.org if you need help."
)
shapefiles = models.ManyToManyField( shapefiles = models.ManyToManyField(
'files.File', 'files.File',
related_name='shapefile_for', related_name='shapefile_for',
verbose_name=_("Geographic data"), verbose_name=shapefiles_label,
help_text=_("If you have territory that you would like to show in relation to this project i.e. area(s) of land or water affected by the project, or maybe the limits of the land within which a project is taking place or the sites of particular objects of importance. ESRI Shapefiles are a popular file type: they comprise a set of 3 or more (often 5-6) files with file extensions like .cpg, .dbf, .prj, .qpj, .shp, .shx. Hold down Control, or Command on a Mac, to select more than one. You may have data as GeoPackage (gpkg), GeoJSON, KML, GML, etc. or have data in PostGIS or another spatial database management system already. Let us know (database@ojuso.org) if you have other file types or need help and we can work out how to import it."), help_text=shapefiles_help_text,
blank=True blank=True
) )
coordinate_reference_system = models.ForeignKey( coordinate_reference_system = models.ForeignKey(
SpatialRefSys, SpatialRefSys,
null=True, null=True,
@ -368,7 +391,7 @@ class CaseStudy(models.Model):
# 1.4 # 1.4
country = CountryField( country = CountryField(
verbose_name=_("Country"), verbose_name=_("Country"),
help_text=_("Select the country of the project") help_text=_("Please select the country of the project.")
) )
# 1.5.1 # 1.5.1
@ -388,9 +411,9 @@ class CaseStudy(models.Model):
# 1.5.3 # 1.5.3
land_ownership_details = models.TextField( land_ownership_details = models.TextField(
verbose_name=_("Land ownership/tenure details"), verbose_name=_("Land ownership/tenure details"),
help_text=_("<p class='text-muted'>Please specify details about land ownership, including" help_text=_("<p class='text-muted'>Please specify details about land ownership,"
" conflicting claims, unrecognized customary rights, conflicts" " including conflicting claims, unrecognized customary rights, "
" around land lease or purchase contracts, etc." " conflicts around land lease or purchase contracts, etc."
"" ""
"<p class='text-muted'>We understand this is a difficult question, so" "<p class='text-muted'>We understand this is a difficult question, so"
" please try to provide <b>just the information you know</b>.</p>"), " please try to provide <b>just the information you know</b>.</p>"),
@ -401,7 +424,8 @@ class CaseStudy(models.Model):
# 1.5.4 # 1.5.4
location_context = models.CharField( location_context = models.CharField(
verbose_name=_("Location"), verbose_name=_("Location"),
help_text=_("Select the context that is most applicable to this case study."), help_text=_(
"Please select the context that is most applicable to this case study."),
max_length=3, max_length=3,
choices=LOCATION_CONTEXT_CHOICES choices=LOCATION_CONTEXT_CHOICES
) )
@ -416,7 +440,7 @@ class CaseStudy(models.Model):
# 1.5.5.3 # 1.5.5.3
describe_ecosystem = models.TextField( describe_ecosystem = models.TextField(
verbose_name=_("Describe the ecosystem"), verbose_name=_("Please describe the ecosystem."),
) )
affected_communities = MultiSelectField( affected_communities = MultiSelectField(
@ -443,9 +467,9 @@ class CaseStudy(models.Model):
# 1.7 # 1.7
start_year = models.IntegerField( start_year = models.IntegerField(
verbose_name=_("Construction start year"), verbose_name=_("Construction start year"),
help_text=_("Select the year project construction began. If the project is not yet" help_text=_("Please select the year project construction began."
" in construction, select the assumed start year as detailed in company" "If the project is not yet in construction, select the assumed"
" information or media."), " start year as detailed in company information or media."),
choices=YEAR_CHOICES, choices=YEAR_CHOICES,
blank=True, blank=True,
null=True null=True
@ -454,9 +478,10 @@ class CaseStudy(models.Model):
# 1.8 # 1.8
completion_year = models.IntegerField( completion_year = models.IntegerField(
verbose_name=_("Operation start year"), verbose_name=_("Operation start year"),
help_text=_("Select the year the project's operation and maintenance (O&M) phase began." help_text=_(
" If the project is not yet in operation, select the year operation is expected" "Please select the year the project's operation and maintenance (O&M) phase"
" to begin as detailed in company information or media."), " began. If the project is not yet in operation, select the year operation "
" is expected to begin as detailed in company information or media."),
choices=YEAR_CHOICES, choices=YEAR_CHOICES,
default=None, default=None,
null=True, null=True,
@ -466,45 +491,48 @@ class CaseStudy(models.Model):
# 1.9 # 1.9
synopsis = models.TextField( synopsis = models.TextField(
verbose_name=_("Project synopsis"), verbose_name=_("Project synopsis"),
help_text=_("Briefly summarise the project. This will be displayed at the top of the case study page. (Maximum 500 chars)") help_text=_("Please briefly summarise the project. (Maximum 500 characters.)"),
max_length=500
) )
# 1.10 # 1.10
full_description = models.TextField( full_description = models.TextField(
verbose_name=_("Full description"), verbose_name=_("Full description"),
help_text=_("Describe the project in full. Separate paragraphs with two" help_text=_("Please describe the project in full. Separate paragraphs with two"
" new lines. Please add as much detail as you feel is necessary" " new lines. Please add as much detail as you feel is necessary"
" here.") " here.")
) )
# 1.11 # 1.11
project_owners = models.TextField( project_owners = models.TextField(
verbose_name=_("Project and facility owners"), verbose_name=_("Project owners"),
help_text=_("List companies or organisations that own the project and/or facilities." help_text=_("Please list companies or organisations that own the project."
" Provide company numbers etc. if available. Separate with a new line."), " Write each name in a new line."),
blank=True blank=True
) )
consultants_contractors = models.TextField( consultants_contractors = models.TextField(
verbose_name=_("Consultants and contractors"), verbose_name=_("Consultants and contractors"),
help_text=_("List consultants, planners or organisations that are doing the planning," help_text=_("Please list consultants, planners or organisations that are doing"
" construction, operation or maintenance work relating to the project" " the planning, construction, operation or maintenance work relating"
" and/or facilities. Separate each with a new line."), " to the project and/or facilities. Separate each with a new line."),
blank=True blank=True
) )
# 1.12 # 1.12
shareholders = models.TextField( shareholders = models.TextField(
verbose_name=_("Shareholders of the project owners"), verbose_name=_("Shareholders of the project owners"),
help_text=_("List shareholders of the project owners you've just listed. Separate with a new line."), help_text=_("List the shareholders of the company/companies that own the"
" project, if you have this information. Separate with a new line."),
blank=True blank=True
) )
# 1.13.1 # 1.13.1
financial_institutions = MultiSelectField( financial_institutions = MultiSelectField(
verbose_name=_("Financial institutions"), verbose_name=_("Financial institutions"),
help_text=_("Select any financial institutions (public or private) that have," help_text=_("Please select any financial institutions (public or private) that"
" or are considering, extending loans or guarantees to the project."), " have, or are considering extending loans or guarantees to the"
" project."),
choices=FINANCIAL_INSTITUTIONS, choices=FINANCIAL_INSTITUTIONS,
blank=True blank=True
) )
@ -512,7 +540,8 @@ class CaseStudy(models.Model):
# 1.13.2 # 1.13.2
financial_institutions_other = models.TextField( financial_institutions_other = models.TextField(
verbose_name=_("Financial institutions other"), verbose_name=_("Financial institutions other"),
help_text=_("List any other financial institutions not listed above. Put each on a new line."), help_text=_("Please list any other financial institutions not listed above."
" Separate with a new line."),
blank=True blank=True
) )
@ -550,37 +579,42 @@ class CaseStudy(models.Model):
# 1.17.1 # 1.17.1
media_coverage_mainstream = models.TextField( media_coverage_mainstream = models.TextField(
verbose_name=_("Links to media reports"), verbose_name=_("Links to media reports"),
help_text=_("Provide any links to mainstream media coverage."), help_text=_("Please provide any links to mainstream media coverage."),
blank=True, blank=True,
) )
# 1.17.2 # 1.17.2
media_coverage_independent = models.TextField( media_coverage_independent = models.TextField(
verbose_name=_("Independent grassroots reports"), verbose_name=_("Independent grassroots reports"),
help_text=_("Provide any links to grassroots/independent media coverage."), help_text=_("Please provide any links to grassroots/independent media coverage."),
blank=True, blank=True,
) )
# 1.18.1 # 1.18.1
community_voices = models.TextField( community_voices = models.TextField(
verbose_name=_("Community Voices"), verbose_name=_("Community Voices"),
help_text=_("Add any direct quotes from members of the community that relate to this project"), help_text=_(
"Please add any direct quotes from members of the community that relate"
" to this project."),
blank=True, blank=True,
) )
# 1.18.2 # 1.18.2
direct_comms = models.TextField( direct_comms = models.TextField(
verbose_name=_("Reports of direct communications"), verbose_name=_("Reports of direct communications"),
help_text=_("Add any reports of direct communication between community members and" help_text=_(
" representatives of developers/companies/investors. If you have files" "Please add any reports of direct communication between community members"
" to upload, you can do this in 'other documents' on the 'uploads' tab."), " and representatives of developers/companies/investors. If you have files"
" to upload, you can do this in 'other documents' on the 'uploads' tab."),
blank=True, blank=True,
) )
# 1.18.3 # 1.18.3
social_media_links = models.TextField( social_media_links = models.TextField(
verbose_name=_("Social media links"), verbose_name=_("Social media links"),
help_text=_("Add any links to social media accounts directly relating to the project."), help_text=_(
"Please add any links to social media accounts directly relating"
" to the project."),
max_length=500, max_length=500,
blank=True, blank=True,
) )
@ -590,14 +624,14 @@ class CaseStudy(models.Model):
## ##
sector_of_economy = models.CharField( sector_of_economy = models.CharField(
verbose_name=_("Sector of economy"), verbose_name=_("Sector of renewable energy economy"),
max_length=3, max_length=3,
choices=SECTOR_CHOICES choices=SECTOR_CHOICES
) )
energy_details = models.CharField( energy_details = models.CharField(
verbose_name=_("Further details"), verbose_name=_("Technology type"),
help_text=_("Please give more information about the transmission, network or storage technology."), help_text=_("Please provide more information about the type of technology this case study focuses on."),
max_length=200, max_length=200,
blank=True blank=True
) )
@ -605,7 +639,7 @@ class CaseStudy(models.Model):
## Energy generation project ## Energy generation project
generation_type = models.CharField( generation_type = models.CharField(
verbose_name=_('What is being generated?'), verbose_name=_('What kind of energy is generated?'),
max_length=4, max_length=4,
choices=GENERATION_TYPE_CHOICES, choices=GENERATION_TYPE_CHOICES,
blank=True blank=True
@ -613,7 +647,8 @@ class CaseStudy(models.Model):
generation_technology = models.CharField( generation_technology = models.CharField(
verbose_name=_("Generation technology"), verbose_name=_("Generation technology"),
help_text=_("Select the type of renewable energy generation that most applies to this case study."), help_text=_("Please select the type of renewable energy generation that most"
" applies to this case study."),
max_length=4, max_length=4,
choices=GENERATION_TECHNOLOGY_CHOICES, choices=GENERATION_TECHNOLOGY_CHOICES,
blank=True blank=True
@ -623,14 +658,15 @@ class CaseStudy(models.Model):
biomass_detail = models.CharField( biomass_detail = models.CharField(
verbose_name=_("Bio-energy feedstock"), verbose_name=_("Bio-energy feedstock"),
help_text="<div class='text-muted'>" + _( help_text="<div class='text-muted'>" + _(
"<p>Please describe the source of the fuel and how it is processed/used. Please consider:</p>" "<p>Please describe the source of the fuel and how it is processed/used."
"<ul>" " Please consider:</p>\n"
"<li>where the fuel came from e.g. corn, forestry, algae, commercial food waste," "<ul>\n"
" landfill gas, sewage, livestock farm, etc.</li>" "<li>where the fuel came from e.g. corn, forestry, algae,"
"<li>how it is processed e.g. direct-fired, co-firing with other renewable input," " commercial food waste, landfill gas, sewage, livestock farm, etc.</li>\n"
" gasification, bacterial decomposition (anaerobic digestion, AD), pyrolysis," "<li>how it is processed e.g. direct-fired, co-firing with other renewable"
" small/modular, artificial photosynthesis, fuel cell, etc.</li>" " input, gasification, bacterial decomposition (anaerobic digestion, AD), "
"</ul>" " pyrolysis, artificial photosynthesis, fuel cell, etc.</li>\n"
"</ul>\n"
"<p>We do not expect users to know this information, but if you do " "<p>We do not expect users to know this information, but if you do "
" it may be useful to give a fuller picture.</p>" " it may be useful to give a fuller picture.</p>"
) + "</div>", ) + "</div>",
@ -641,17 +677,17 @@ class CaseStudy(models.Model):
# 1.14 # 1.14
energy_customers = models.TextField( energy_customers = models.TextField(
verbose_name=_("Energy service consumers/off-takers"), verbose_name=_("Energy service consumers/off-takers"),
help_text=_("List any energy customers/off-takers that take energy from the" help_text=_(
" development. E.g. 'national grids' or private energy suppliers." "Please list the customers that buy energy from the project, e.g. the"
" Also refer to if carbon markets, credits, blockchain etc. are" " national grid provider, or private companies. Also mention whether"
" involved in the process. Please separate with a new line."), " credits are being sold in the carbon markets. Separate with a new line."
),
blank=True blank=True
) )
# 2.1.2 # 2.1.2
total_generation_capacity = models.PositiveIntegerField( total_generation_capacity = models.PositiveIntegerField(
verbose_name=_("Total generation capacity (in kW)"), verbose_name=_("Total generation capacity (kW)"),
help_text=_("Please enter the total generation capacity of the project in kW"),
blank=True, blank=True,
null=True null=True
) )
@ -659,7 +695,9 @@ class CaseStudy(models.Model):
# 2.1.4 # 2.1.4
total_investment = models.IntegerField( total_investment = models.IntegerField(
verbose_name=_("Total investment (in USD)"), verbose_name=_("Total investment (in USD)"),
help_text=_("The approximate total investment for the project in US dollars."), help_text=_(
"Please enter the approximate total investment for the project in"
" United State Dollars (USD)."),
blank=True, blank=True,
null=True null=True
) )
@ -689,7 +727,7 @@ class CaseStudy(models.Model):
) )
energy_transmission_capacity = models.DecimalField( energy_transmission_capacity = models.DecimalField(
verbose_name=_("Total transmission capacity (kW)"), verbose_name=_("Total transmission or distribution capacity (kW)"),
max_digits=20, max_digits=20,
decimal_places=3, decimal_places=3,
blank=True, blank=True,
@ -698,18 +736,21 @@ class CaseStudy(models.Model):
# TODO: Auto-completion based on previous entries so we can query case-studies with the same answer. # TODO: Auto-completion based on previous entries so we can query case-studies with the same answer.
contractor_or_supplier_of_technology = models.TextField( contractor_or_supplier_of_technology = models.TextField(
verbose_name=_('Contractor and/or supplier of technology'), verbose_name=_('Supplier of technology'),
help_text=_('List companies that act as contractors or suppliers  e.g. Siemens Gamesa, GE, Alstom, Vestas, Hanwha Q CELLS, Mitsubishi, First Solar, Jinko Solar, Trina Solar, Suzlon Energy, Statkraft, Shanghai Electric, Ballard Power Systems, Panasonic, etc.'), help_text=_("Please list companies that supply the energy generation equipment"
" - e.g. Siemens Gamesa, GE, Alstom, Vestas, Hanwha Q CELLS,"
" Mitsubishi, First Solar, Jinko Solar, Trina Solar,"
" Suzlon Energy, Statkraft, Shanghai Electric,"
" Ballard Power Systems, Panasonic, etc."),
blank=True, blank=True,
) )
# 2.2.5 # 2.2.5
additional_technical_details = models.TextField( additional_technical_details = models.TextField(
verbose_name=_("Additional technical or economic details"), verbose_name=_("Additional technical or economic details"),
help_text=_("Add any additional details such as: length, from-to, voltage," help_text=_(
" substations, power output, (dis)charge rates, how this technology or" "Please add any additional details that may help to explain the technical"
" project interacts with the energy system (e.g. provides reactive power" " and economic aspects of this case study."),
" to ensure power supply in phase etc.)"),
blank=True blank=True
) )
@ -719,7 +760,7 @@ class CaseStudy(models.Model):
minerals_or_commodities = models.CharField( minerals_or_commodities = models.CharField(
verbose_name=_("Primary mineral mined"), verbose_name=_("Primary mineral mined"),
help_text=_("What mineral commodity is primarily mined in this project?"), help_text=_("What mineral commodity is primarily mined here?"),
max_length=3, max_length=3,
choices=MINERAL_COMMODITY_CHOICES, choices=MINERAL_COMMODITY_CHOICES,
blank=True blank=True
@ -727,7 +768,9 @@ class CaseStudy(models.Model):
minerals_or_commodities_other = models.TextField( minerals_or_commodities_other = models.TextField(
verbose_name=_("Other mineral commodities"), verbose_name=_("Other mineral commodities"),
help_text=_("Enter any mineral commodities not in the list. Separate each with a new line."), help_text=_(
"Please enter any mineral commodities not in the list."
" Separate each with a new line."),
blank=True blank=True
) )
@ -753,15 +796,20 @@ class CaseStudy(models.Model):
size_of_concessions = models.CharField( size_of_concessions = models.CharField(
verbose_name=_("Size of concessions (land/marine area)"), verbose_name=_("Size of concessions (land/marine area)"),
help_text=_("Describe the size of concession(s) granted to company/companies (e.g. 'one concession of 2,300 hectares')"), help_text=_(
"Please describe the size of concession(s) granted to company/companies"
" (e.g. 'one concession of 2,300 hectares (23km²)')"),
max_length=200, max_length=200,
blank=True blank=True
) )
projected_production_of_commodities = models.CharField( projected_production_of_commodities = models.CharField(
verbose_name=_("Estimated production of key commodities"), verbose_name=_("Estimated production of key commodities"),
help_text=_('Describe the projected production of commodities per annum and overall.<br>' help_text=_(
'For example, "40 million tonnes of iron ore per year", "200 million tonnes over 5 year life of mine"'), 'Please describe the projected production of commodities per annum and'
' overall.<br>\n'
'For example, "40 million tonnes of iron ore per year",'
' "200 million tonnes over 5 year life of mine"."'),
max_length=256, max_length=256,
blank=True blank=True
) )
@ -775,7 +823,11 @@ class CaseStudy(models.Model):
associated_infrastructure = models.CharField( associated_infrastructure = models.CharField(
verbose_name=_("Associated infrastructure in the locality"), verbose_name=_("Associated infrastructure in the locality"),
help_text=_("List any associated infrastructure in the locality (e.g. tailings dams/mine waste storage and treatment facilities; ore processing facilities; smelting facilities; hydroelectric dams/energy infrastructure; transport infrastructure e.g. roads or rail)."), help_text=_("Please list any associated infrastructure in the locality"
" (e.g. tailings dams / mine waste storage and treatment facilities;"
" ore processing facilities; smelting facilities;"
" hydroelectric dams / energy infrastructure;"
" transport infrastructure e.g. roads or rail)."),
max_length=256, max_length=256,
blank=True blank=True
) )
@ -791,7 +843,9 @@ class CaseStudy(models.Model):
manufacturing_description = models.TextField( manufacturing_description = models.TextField(
verbose_name=_("Description"), verbose_name=_("Description"),
help_text=_("Briefly describe manufacturing process and components/outputs. (less than 500 characters)."), help_text=_(
"Please briefly describe manufacturing process and components/outputs."
" (less than 500 characters)."),
max_length=500, max_length=500,
blank=True blank=True
) )
@ -804,14 +858,16 @@ class CaseStudy(models.Model):
) )
manufacturing_factors = MultiSelectField( manufacturing_factors = MultiSelectField(
verbose_name=_("Choose the factors that make this case remarkable, in a positive or negative way"), verbose_name=_(
"Please choose the factors that make this case remarkable, "
"in a positive or negative way."),
max_length=128, max_length=128,
choices=MANUFACTURING_FACTORS_CHOICES, choices=MANUFACTURING_FACTORS_CHOICES,
blank=True blank=True
) )
manufacturing_factors_description = models.TextField( manufacturing_factors_description = models.TextField(
verbose_name=_("Describe these factors"), verbose_name=_("Please describe these factors."),
blank=True blank=True
) )
@ -851,21 +907,21 @@ class CaseStudy(models.Model):
negative_socioenvironmental_impacts = models.TextField( negative_socioenvironmental_impacts = models.TextField(
verbose_name=_("Describe the socio-environmental impacts (positive and negative):"), verbose_name=_("Describe the socio-environmental impacts (positive and negative):"),
help_text=_("Provide a detailed description of the socio-environmental impacts" help_text=_(
" (please provide all relevant details, such as type of ecosystem and" "Please provide a detailed description of the socio-environmental impacts"
" presence of any existing reserve in the area, land to have increased" " (all relevant details, such as type of ecosystem, presence of any"
" biodiversity as a result of the project, new protection of lands/waters," " existing reserve in the area, biodiversity impacts, new protection of"
" specific communities affected by the project, total geographic footprint" " lands/waters, total geographic footprint of the project,"
" of the project, and tenure system affected in the case of land grabs," " tenure system affected in the case of land grabs, etc.)."),
" kind of permits that were irregularly issued if this is the case."),
blank=True blank=True
) )
isolated_or_widespread = models.TextField( isolated_or_widespread = models.TextField(
verbose_name=_("Is the project part of developments which are causing a cumulative effect?"), verbose_name=_("Is the project part of developments which are causing a cumulative effect?"),
help_text=_("Is this an isolated project or are there similar projects in the same" help_text=_(
" geographic area? If so, can you describe them? Is there an analysis of" "Is this an isolated project or are there similar projects in the same"
" cumulative or synergetic effects?"), " geographic area? If so, can you please describe them? Is there an"
" analysis of cumulative or synergetic effects?"),
blank=True blank=True
) )
@ -876,7 +932,7 @@ class CaseStudy(models.Model):
project_status_detail = models.TextField( project_status_detail = models.TextField(
verbose_name=_('Current status of the case'), verbose_name=_('Current status of the case'),
help_text=_("Describe the current situation and likely future scenarios."), help_text=_("Please describe the current situation and likely future scenarios."),
blank=True blank=True
) )
@ -907,7 +963,9 @@ class CaseStudy(models.Model):
# 3.2.4.1 # 3.2.4.1
when_did_organising_start = models.CharField( when_did_organising_start = models.CharField(
verbose_name=_("When did local organising efforts begin?"), verbose_name=_("When did local organising efforts begin?"),
help_text=_("Before the project started? During project implementation? After project implementation? Describe in your own words."), help_text=_(
"Before the project started? During project implementation?"
" After project implementation? Please describe in your own words."),
max_length=512, max_length=512,
blank=True blank=True
) )
@ -921,15 +979,19 @@ class CaseStudy(models.Model):
# 3.2.4.3 # 3.2.4.3
participation_mechanisms = models.TextField( participation_mechanisms = models.TextField(
verbose_name=_("What mechanisms of participation have been used?"), verbose_name=_("What mechanisms of participation have been used?"),
help_text=_("e.g. direct action, local referendums, legal cases, letters or petitions, etc."), help_text=_("e.g. direct action, local referendums, legal cases,"
" letters or petitions, etc."),
blank=True blank=True
) )
# 3.2.7 # 3.2.7
wants_conversation_with_ojuso = models.BooleanField( wants_conversation_with_ojuso = models.BooleanField(
verbose_name=_("Would you like to have a conversation with the <b>ojuso</b> team?"), verbose_name=_(
help_text=_("This would be a conversation about challenging or engaging related developers, companies and investors."), "Would you like to have a conversation with the <b>ojuso</b> team?"),
default=True help_text=_(
"This would be a conversation about challenging or engaging related"
" developers, companies and investors."),
default=False
) )
@ -979,8 +1041,7 @@ class CaseStudy(models.Model):
'files.File', 'files.File',
related_name='official_project_document_for', related_name='official_project_document_for',
verbose_name=_("Official project documents"), verbose_name=_("Official project documents"),
help_text=_("Attach any legal or official documents that relate to the project." help_text=_("Please attach any legal or official documents that relate to the project."),
" Hold down Control, or Command on a Mac, to select more than one."),
blank=True, blank=True,
) )
@ -989,8 +1050,7 @@ class CaseStudy(models.Model):
'files.File', 'files.File',
related_name='other_document_for', related_name='other_document_for',
verbose_name=_("Other documents"), verbose_name=_("Other documents"),
help_text=_("Attach any other documents that relate to the project." help_text=_("Please attach any other documents that relate to the project."),
" Hold down Control, or Command on a Mac, to select more than one."),
blank=True, blank=True,
) )
@ -1013,17 +1073,16 @@ class CaseStudy(models.Model):
"""The String representation of the case study. (Entry name with country name.)""" """The String representation of the case study. (Entry name with country name.)"""
return "%s in %s" % (self.entry_name, self.country.name) return "%s in %s" % (self.entry_name, self.country.name)
def clean(self, *args, **kwargs):
"""Perform validation on the model as a whole and throw a ValidationError if anything isn't how it should be."""
pass
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
"""Override the save method to create a slug when the model is created. Slug is only created and never modified """
as we are basing our URLs on it and don't want it to change - ever.""" Override the save method to create a slug when the model is created.
Slug is only created and never modified as we are basing our URLs on it and
don't want it to change - ever.
"""
if not self.pk: if not self.pk:
# Newly created object, so set slug # Newly created object, so set slug
self.slug = slugify(self.entry_name) self.slug = slugify(self.entry_name)
# Continue normal save method by calling original save method.
super(CaseStudy, self).save(*args, **kwargs) super(CaseStudy, self).save(*args, **kwargs)
def is_video_youtube(self): def is_video_youtube(self):
@ -1044,8 +1103,6 @@ class CaseStudy(models.Model):
verbose_name_plural = 'case studies' verbose_name_plural = 'case studies'
class PointOfInterestQuerySet(models.QuerySet): class PointOfInterestQuerySet(models.QuerySet):
def approved(self): def approved(self):
return self.filter( return self.filter(
@ -1063,11 +1120,11 @@ class PointOfInterest(models.Model):
objects = PointOfInterestQuerySet.as_manager() objects = PointOfInterestQuerySet.as_manager()
author = models.ForeignKey( author = models.ForeignKey(
User, User,
models.SET_NULL, models.SET_NULL,
blank=True, blank=True,
null=True, null=True,
editable=False editable=False
) )
date_created = models.DateTimeField(auto_now_add=True, null=False) date_created = models.DateTimeField(auto_now_add=True, null=False)

View File

@ -1,7 +1,14 @@
{% load i18n %}
<div class="filewidget" data-field="{{ widget.attrs.field }}"> <div class="filewidget" data-field="{{ widget.attrs.field }}">
<label class="filewidget--add btn btn-success"> <div style="display: flex; align-items: center">
<input class="filewidget--input" type="file" multiple data-url="{{ widget.attrs.url }}"> <div>
<i class="fa fa-plus"></i>&nbsp;Add files <label class="filewidget--add btn btn-success">
</label> <input class="filewidget--input" type="file" multiple data-url="{{ widget.attrs.url }}">
<i class="fa fa-plus"></i>&nbsp;{% trans "Add files" %}
</label>
</div>
<p class="only-windows" style="padding-left: 1em; margin-bottom: 0">{% trans "Hold down <span class='label label-default'>Ctrl</span> to select multiple files at once." %}</p>
<p class="only-mac" style="padding-left: 1em; margin-bottom: 0">{% trans "Hold down <span class='label label-default'>⌘ Cmd</span> to select multiple files at once." %}</p>
</div>
<ul class="filewidget--list"></ul> <ul class="filewidget--list"></ul>
</div> </div>

View File

@ -46,25 +46,12 @@ html, body, #main {
<img class="hello--logo" align="center" src="{% static 'map/images/ojuso-logo-black.png' %}" alt="Ojuso"> <img class="hello--logo" align="center" src="{% static 'map/images/ojuso-logo-black.png' %}" alt="Ojuso">
{% blocktrans trimmed with forum_url='//forum.ojuso.org' %} {% blocktrans trimmed with forum_url='//forum.ojuso.org' %}
<p> <p>
<b>ojuso</b>s aim is to promote best practice in the renewable energy <b>ojuso</b>s aims are to promote best practice in the renewable energy industry, to avoid investment in ecologically and socially destructive projects, and to foster improvements in supply chain and lifecycle management in the sector.
industry, to encourage divestment from ecologically and socially
destructive projects, and to foster improvements in supply chain and
lifecycle management in the sector.
</p> </p>
<p> <p>
<b>ojuso</b> provides a platform for information exchange and <b>ojuso</b> provides a platform for information exchange and cooperation between different sectors involved in the renewable energy economy and is supportive of ethical and ecologically sound practices. This platform consists of an online map and database of positive and negative case studies, contributed by communities affected by, or leading, renewable energy projects, and of a series of discussion fora and features, contributed by diverse players.</p>
cooperation between different sectors involved in the renewable energy
economy and is supportive of ethical and ecologically sound practices.
This platform consists of an online map and database of positive and
negative case studies, contributed by communities affected by and
leading the transition, and a series of discussion fora and features,
contributed by a diversity of players.
</p>
<p> <p>
You are welcome to submit a case study through this map tool. You are welcome to submit a case study through this tool. Following submission, cases will be moderated and, if successful, placed on the map. If you need any help or have any suggestions, please post messages on <a href="{{ forum_url }}">our forum</a>.
Following submission, cases will be moderated and, if successful,
placed on the map. If you need any help or have any suggestions,
please post messages on <a href="{{ forum_url }}">our forum</a>.
</p> </p>
{% endblocktrans %} {% endblocktrans %}
<p class="text-muted"> <p class="text-muted">

View File

@ -30,6 +30,11 @@ h1 {
.mx-1 { margin-left: 10px; } .mx-1 { margin-left: 10px; }
.only-windows { display: none; }
.os-windows .only-windows { display: initial; }
.only-mac { display: none; }
.os-mac .only-mac { display: initial; }
/* /*
* LAYOUT * LAYOUT