Compare commits

...
Sign in to create a new pull request.

8 commits

Author SHA1 Message Date
5445cb86a4 Split title 2026-01-14 14:50:51 -08:00
23425bc7c7 Capitalize start of sentence; expand breadth of link 2026-01-14 14:50:08 -08:00
d38fa0955e Fix “Year in Review” to now be “2025 in Review” 2026-01-14 14:49:24 -08:00
f09847283b Close <a> tag. 2026-01-14 14:47:51 -08:00
2e760344f6 Rework copy to make this a bit shorter. 2026-01-14 14:43:32 -08:00
2cd8df0d92 Numbers should *not* be hard-coded in this file.
It is difficult to do math in a template (see the `intcomma` thing),
but we shouldn't hardcode numbers in the template.
2026-01-14 14:33:02 -08:00
f2c2b86892 update frontpage for match extension 2026-01-14 14:32:31 -08:00
cf5bd77c56 Support two fundraising bars for a stretch match
Long ago, when the bar was all Javascript, we had the ability to have
sub-targets in a single bar.  I was not able to invest the time
necessary to figure out how to do that again using the newer setup
for the fundraising bar, so instead I've added the ability to have a
stretch match bar that appears above the other one once the first
match period ends.

While it handles most of the weird cases with some grace, it will
probably look weird unless you set up a `SITE_FUNDGOAL_0` as a match
that finishes at least a week or two before `SITE_FUNDGOAL_1`.

The two aren't really aware of each other, either, so you have to
make sure the objects are updated properly (i.e., it *will* display
the stretch when `SITE_FUNDGOAL_0` ends even if there are match funds
remaining in `SITE_FUNDGOAL_0`).

A better solution should be found and implemented before 2026-11-22.
If you're actually reading this commit message for a reason other
than historical interest and that date has past, you're probably in
big trouble right now. 😬
2026-01-14 14:16:44 -08:00
6 changed files with 118 additions and 53 deletions

View file

@ -4,10 +4,14 @@ from .fundgoal.models import FundraisingGoal
def sitefundraiser(request): def sitefundraiser(request):
try: try:
fundgoal = FundraisingGoal.objects.get(fundraiser_code_name=settings.SITE_FUNDGOAL) fundgoal0 = FundraisingGoal.objects.get(fundraiser_code_name=settings.SITE_FUNDGOAL_0)
except FundraisingGoal.DoesNotExist: except FundraisingGoal.DoesNotExist:
fundgoal = None fundgoal0 = None
return {'sitefundgoal': fundgoal} try:
fundgoal1 = FundraisingGoal.objects.get(fundraiser_code_name=settings.SITE_FUNDGOAL_1)
except FundraisingGoal.DoesNotExist:
fundgoal1 = None
return {'sitefundgoal0': fundgoal0, 'sitefundgoal1': fundgoal1 }
def host_url(request): def host_url(request):

View file

@ -1,51 +1,106 @@
{% load humanize %} {% load humanize %}
{% if sitefundgoal.days_remaining >= -22 %}{# i.e. 7 days over completion #} {% if sitefundgoal1.days_remaining >= -22 or sitefundgoal0.days_remaining >= -22 %} {# IF LEVEL 0 (only show this at all for 7 days after fundraiser and stretch are over) #}
<div class="fundraiser-top-text ph3 pt2 pb3 mb2 mb3-ns"> <div class="fundraiser-top-text ph3 pt2 pb3 mb2 mb3-ns">
<div class="mw8 center ph2 ph4-ns"> <div class="mw8 center ph2 ph4-ns">
<div class="mt2 mb3 tc"> <div class="mt2 mb3 tc">
{% if sitefundgoal.days_remaining >= 0 %} {% if sitefundgoal0.match_remaining <= 0 %} {# IF LEVEL 0.1 #}
{% if sitefundgoal.match_remaining <= 0 %} {% if sitefundgoal1.days_remaining >= 0 %} {# IF LEVEL 0.1.0 #}
Thanks to so many donors, we earned our full match! {% if sitefundgoal1.match_remaining <= 0 %} {# IF LEVEL 0.1.0.0 #}
Help us go further to stand up for software freedom &mdash; <a href="/sustainer">sign up now</a>! Thanks to all our donors who participated in our historic donation match challenge!
{% else %} Thanks to all of you, we raised our goal of <b>$503,878</b> to support software freedom:
{% if sitefundgoal.days_remaining == 0 %} {% else %} {# ELSE LEVEL 0.1.0.0 when sitefundgoal1.match_remaining > 0 #}
For the next {{ sitefundgoal.hours_remaining }} hour{{ sitefundgoal.hours_remaining|pluralize }} <strong>only</strong>, the Thanks to so many donors, we met <em>our largest match donation ever of <strong>$211,939</strong></em>.
{% elif sitefundgoal.days_remaining == 1 %} Two generous anonymous <a href="/news/2026/jan/14/match-challenge-extended-by-40012/">donors have provided</a> <em>another ${{ sitefundgoal1.fundraiser_goal_amount|floatformat:0|intcomma }}</em> of <em>additional</em> matching funds.
Help us reach our goal of <b>$503,878</b> this season to keep SFC going. Through tomorrow only, the <a href="/sustainer/">Give now to help us</a> reach <a href="/news/2026/jan/14/match-challenge-extended-by-40012/">this stretch goal</a>!<br/>
{% elif sitefundgoal.days_remaining < 14 %} {% if sitefundgoal1.days_remaining == 0 %} {# IF LEVEL 0.1.0.0.0 sitefundgoal1.days_remaining alternatives #}
Help us reach our goal of <b>$503,878</b> this season to keep SFC going. For only {{ sitefundgoal.days_remaining }} more days, the For <strong>only</strong> the next {{ sitefundgoal1.hours_remaining }} hour{{ sitefundgoal1.hours_remaining|pluralize }}, the
{% else %} {% elif sitefundgoal1.days_remaining == 1 %} {# ELIF LEVEL 0.1.0.0.0 sitefundgoal1.days_remaining alternatives #}
Help us reach our goal of <b>$503,878</b> this season to keep SFC going. Until January 15, the Through tomorrow only, the
{% endif %} {% elif sitefundgoal1.days_remaining < 14 %} {# ELIF LEVEL 0.1.0.0.0 sitefundgoal1.days_remaining alternatives #}
next <b>${{ sitefundgoal.match_remaining|floatformat:0|intcomma }}</b> of <a href="/sustainer/">support we receive</a> will be matched! For only {{ sitefundgoal1.days_remaining }} more days, the
{% endif %} {% else %} {# ELIF LEVEL 0.1.0.0.0 sitefundgoal1.days_remaining alternatives #}
{% else %} Until February 5, the
Thanks to all our donors who participated in our {% endif %} {# ELSE LEVEL 0.1.0.0.0 sitefundgoal1.days_remaining alternatives #}
historic donation match challenge! Thanks to you, <a href="https://sfconservancy.org/blog/2025/jan/16/end-of-year-2024-fundraiser-a-massive-success/">we next <b>${{ sitefundgoal1.match_remaining|floatformat:0|intcomma }}</b> of <a href="/sustainer/">financial support we receive</a> will be matched!
raised more than $480k to support software freedom</a>: {% endif %} {# ENDIF LEVEL 0.1.0.0 (testing whether or not sitefundgoal1.match_remaining has anything left in it) #}
{% endif %} {% else %} {# ELSE LEVEL 0.1.0 when (sitefundgoal1.days_remaining < 0) #}
</div> {# The problem with automating this is that it does not actually test here if we made the match or not; we are usually watching it so carefully that it should not matter? We also have made ever match we did since 2015, so no one has probably thought hard about this problem. -- bkuhn #}
Thanks to all our donors who participated in our historic donation match challenge!
Thanks to all of you, we raised our goal of <b>$503,878</b>.
Help us go further to stand up for software freedom &mdash; <a href="/sustainer">sign up now</a>!
{% endif %} {# ENDIF LEVEL 0.1.0 (whether or not there are any sitefundgoal1.days_remaining) #}
<a href="/sustainer/" style="text-decoration: none !important"> <a href="/sustainer/" style="text-decoration: none !important">
<div id="siteprogressbar" class="flex items-stretch w-100"> <div id="siteprogressbar" class="flex items-stretch w-100">
{% if sitefundgoal.match_remaining <= 0 %} {% if sitefundgoal1.match_remaining <= 0 %} {# IF LEVEL 0.1.1 #}
<div class="progress matched ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal.fundraiser_so_far_amount }}px"> <div class="progress matched ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal1.fundraiser_so_far_amount }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100 ph1">${{ sitefundgoal.fundraiser_goal_amount|floatformat:0|intcomma }} fully matched!</span> <span id="site-fundraiser-match-count" class="soFarText tc w-100 ph1 done">${{ sitefundgoal1.fundraiser_goal_amount|floatformat:0|intcomma }} fully matched!</span>
</div> </div>
<div class="progress exceeded pv1 b flex items-center" style="flex-basis: {{ sitefundgoal.match_exceeded_by }}px"> {% else %} {# ELSE LEVEL 0.1.1 when sitefundgoal1.match_remaining > 0 #}
<span id="site-fundraiser-match-count" class="soFarText tc w-100 exceeded ph1">${{sitefundgoal.match_exceeded_by|floatformat:0|intcomma }} additional<br> raised!<br></span> <div class="progress ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal1.fundraiser_so_far_amount }}px">
</div> <span id="site-fundraiser-match-count" class="soFarText tc w-100">${{ sitefundgoal1.fundraiser_so_far_amount|floatformat:0|intcomma }} matched!</span>
{% else %} </div>
<div class="progress ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal.fundraiser_so_far_amount }}px"> <div class="final-goal pv1 b flex items-center" style="flex-basis: {{ sitefundgoal1.match_remaining }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100">${{ sitefundgoal.fundraiser_so_far_amount|floatformat:0|intcomma }} matched!</span> <span id="site-fundraiser-final-goal" class="goalText tc w-100 ph1">${{ sitefundgoal1.match_remaining|floatformat:0|intcomma }} to go!</span>
</div> </div>
<div class="final-goal pv1 b flex items-center" style="flex-basis: {{ sitefundgoal.match_remaining }}px"> {% endif %} {# ENDIF LEVEL 0.1.1 testing whether or not sitefundgoal1.match_remaining has anything in it #}
<span id="site-fundraiser-final-goal" class="goalText tc w-100 ph1">${{ sitefundgoal.match_remaining|floatformat:0|intcomma }} to go!</span>
</div>
{% endif %}
</div> </div>
</a> </a>
<a href="/sustainer/" style="text-decoration: none !important">
<div id="siteprogressbar" class="flex items-stretch w-100">
{% if sitefundgoal0.match_remaining <= 0 %} {# IF LEVEL 0.1.2, pointless test of sitefundgoal0.match_remaining (if we get here, else block should never be used!) #}
<div class="progress matched ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.fundraiser_so_far_amount }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100 ph1 done">${{ sitefundgoal0.fundraiser_goal_amount|floatformat:0|intcomma }} fully matched!</span>
</div>
{% else %} {# ELSE LEVEL 0.1.2, sitefundgoal0.match_remaining > 0 , but NOTE! We are here inside IF LEVEL 0.1, so this *should* never appear, included just for consistency #}
<div class="progress ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.fundraiser_so_far_amount }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100">${{ sitefundgoal0.fundraiser_so_far_amount|floatformat:0|intcomma }} matched!</span>
</div>
<div class="final-goal pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.match_remaining }}px">
<span id="site-fundraiser-final-goal" class="goalText tc w-100 ph1">${{ sitefundgoal0.match_remaining|floatformat:0|intcomma }} to go!</span>
</div>
{% endif %} {# ENDIF LEVEL 0.1.2, this ends the pointless block here for consistency, see comment above. #}
</div>
</a>
{% else %} {# ELSE LEVEL 0.1 when (sitefundgoal0.match_remaining > 0) #}
{% if sitefundgoal0.days_remaining >= 0 %} {# IF LEVEL 0.1.3 #}
{% if sitefundgoal0.match_remaining <= 0 %} {# IF LEVEL 0.1.3.0 #}
Thanks to so many donors, we earned our full match!
{% else %} {# ELSE LEVEL 0.1.3.0 when sitefundgoal0.match_remaining > 0 #}
{% if sitefundgoal0.days_remaining == 0 %} {# IF LEVEL 0.1.3.0.0 testing options for sitefundgoal0.days_remaining #}
For <strong>only</strong> the next {{ sitefundgoal0.hours_remaining }} hour{{ sitefundgoal0.hours_remaining|pluralize }}, the
{% elif sitefundgoal0.days_remaining == 1 %} {# ELSIF LEVEL 0.1.3.0.0 testing options for sitefundgoal0.days_remaining #}
Help us reach our goal this season to keep SFC going. Through tomorrow only, the
{% elif sitefundgoal0.days_remaining < 14 %} {# ELSIF LEVEL 0.1.3.0.0 testing options for sitefundgoal0.days_remaining #}
Help us reach our goal this season to keep SFC going. For only {{ sitefundgoal0.days_remaining }} more days, the
{% else %} {# ELSE LEVEL 0.1.3.0.0 testing options for sitefundgoal0.days_remaining #}
Help us reach our goal this season to keep SFC going. Until January 15, the
{% endif %} {# ENDIF LEVEL 0.1.3.0.0 testing options for sitefundgoal0.days_remaining #}
next <b>${{ sitefundgoal0.match_remaining|floatformat:0|intcomma }}</b> of <a href="/sustainer/">support we receive</a> will be matched!
{% endif %} {# ENDIF LEVEL 0.1.3.0 testing if sitefundgoal0.match_remaining has anything left #}
{% else %} {# ENDIF LEVEL 0.1.3, when sitefundgoal0.days_remaining < 0 #}
{# The problem with automating this is that it does not actually test here if we made the match or not; we are usually watching it so carefully that it should not matter? We also have made ever match we did since 2015, so no one has probably thought hard about this problem. -- bkuhn #}
Thanks to all our donors who participated in our historic donation match challenge!
Help us go further to stand up for software freedom &mdash; <a href="/sustainer">sign up now</a>!
{% endif %} {# ENDIF LEVEL 0.1.3, testing if there are any sitefundgoal0.days_remaining left #}
<a href="/sustainer/" style="text-decoration: none !important">
<div id="siteprogressbar" class="flex items-stretch w-100">
{% if sitefundgoal0.match_remaining <= 0 %} {# IF LEVEL 0.1.3.1 #}
<div class="progress matched ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.fundraiser_so_far_amount }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100 ph1 done">${{ sitefundgoal0.fundraiser_goal_amount|floatformat:0|intcomma }} fully matched!</span>
</div>
{% else %} {# ELSE LEVEL 0.1.3.1 sitefundgoal0.match_remaining > 0 #}
<div class="progress ph1 pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.fundraiser_so_far_amount }}px">
<span id="site-fundraiser-match-count" class="soFarText tc w-100">${{ sitefundgoal0.fundraiser_so_far_amount|floatformat:0|intcomma }} matched!</span>
</div>
<div class="final-goal pv1 b flex items-center" style="flex-basis: {{ sitefundgoal0.match_remaining }}px">
<span id="site-fundraiser-final-goal" class="goalText tc w-100 ph1">${{ sitefundgoal0.match_remaining|floatformat:0|intcomma }} to go!</span>
</div>
{% endif %} {# ENDIF LEVEL 0.1.3.1 sitefundgoal0.match_remaining #}
</div>
</a>
{% endif %} {# ENDIF LEVEL 0.1, two choices for based on sitefundgoal0.match_remaining #}
</div> </div>
</div> </div>
{% endif %} </div>
{% endif %} {# ENDIF LEVEL 0 (the fundraiser has been over for > 7 days) #}

View file

@ -162,4 +162,6 @@ USETHESOURCE = {
'LIST_RECIPIENT': 'ccs-review@lists.sfconservancy.org', 'LIST_RECIPIENT': 'ccs-review@lists.sfconservancy.org',
} }
SITE_FUNDGOAL = 'cy2025-end-year-match' SITE_FUNDGOAL_0 = 'cy2025-end-year-match'
SITE_FUNDGOAL_1 = 'fy2025-26-extend-match'

View file

@ -1168,6 +1168,9 @@ body > header {
#siteprogressbar .soFarText { #siteprogressbar .soFarText {
color: white; color: white;
} }
#siteprogressbar .done {
font-size: 130%;
}
#siteprogressbar .exceeded { #siteprogressbar .exceeded {
color: var(--khaki-green); color: var(--khaki-green);
} }

View file

@ -171,8 +171,6 @@
<a href="https://youtu.be/yCCxMfW0LTM">(watch on Youtube)</a> <a href="https://youtu.be/yCCxMfW0LTM">(watch on Youtube)</a>
</video> </video>
Year In Review 2025
<h3>The wide range of work we engage in is supported by people like you.</h3> <h3>The wide range of work we engage in is supported by people like you.</h3>

View file

@ -36,10 +36,13 @@ initiatives that actively make technology more inclusive, and advancing policy
strategies that defend FOSS (such as copyleft). <a href="/about" class="orange">Learn more.</a></p> strategies that defend FOSS (such as copyleft). <a href="/about" class="orange">Learn more.</a></p>
</section> </section>
<section class="w-30-ns mh2 pa3 bg-light-blue ba b--gray"> <section class="w-30-ns mh2 pa3 bg-light-blue ba b--gray">
<h2 class="f4 ttu">Match pledge increase!</h2> <h2 class="f4 ttu">Match Pledge<br/> Stretch Goal!</h2>
<p>SFC's match pledge has just been increased to <b>$251,939</b>! <p>Thanks to our dedicated donors, we raised <strong>$423,854</strong> so far!
If you <a href="https://sfconservancy.org/sustainer/">renew your Sustainership</a> or <a href="https://sfconservancy.org/donate/">donate</a> before January 15th, your contribution will be doubled! <a href="https://sfconservancy.org/news/2026/jan/14/match-challenge-extended-by-40012/">Two
Read more in our <a href="https://sfconservancy.org/sustainer/#YearInReview">Year in Review</a>.</p> anonymous donors pledged</a> <strong>an additional match of $40,012</strong>
through 2026-02-05. <a href="https://sfconservancy.org/sustainer/">Donate <em>now</em></a>
to <em>double</em> your contribution!
Read about our work in <a href="https://sfconservancy.org/sustainer/#YearInReview">2025 in Review&hellip;</a></p>
</section> </section>
</div> </div>