Main Function
Collect Budget Requests (“BFO Offers”) and Capital Projects from departments and agencies.

  • Approximately 90 departments/agencies submit about 200 offers per year.
  • These are saved in three phases: a simple Pre-Submission, a more complete Initial offer, and an ending Final offer.
  • Between phases, teams of Reviewers check the offers for completeness and feasibility to decide which should be funded in the next budget year, and for what amounts.
Detail Functions
  • Allow entry of BFO “offers” and Capital-Project requests  (including from non-City users at the agencies)
    • Note that offers include what looks like a repeating section of Performance Measures, with multiple fields per Measure.  In reality, there are exactly five repeated sections, no more and no less, hard-coded with individual field names.
  • Search function to allow Review and Edit of offers/projects
    • Sub-functions allow print to pdf (or file) of both individual records and also a bulk list of selected records,
  • Allow attachments related to the agencies (financial statements, etc)
    • These are not specific to a single offer or project.  They apply to the agency as a whole.
    • Note: Only one record is allowed per Agency and Year.  This is done via two interacting Formidable Views.
      • The main List view calls the check-for-add view only if the user has rights to enter for the department and year.
      • Check-for-Add shows an Add link only if there is no existing record for the department/year.
      • This was necessary because Formidable does not seem to have a way to do a double condition: Does the record already exist, and does the user have the right to add it.  The two-step process was the solution until a better one can be found.
  • Allow attachments to specific offers/projects for additional documentation as needed
  • Allow entry of reviewer notes and feedback, including scores or ratings of each offer/project
    • The fields entered for review vary between phases: Pre-Submission has a simple color-code rating; Initial has detailed scores; and Final has Approved yes/no and amount.
  • Maintain a drop-list of valid department and agency names.
    • Include a switch for “department”, “agency”, or “quasi” that can be used to control attachments and other fields.
  • Keep separate copies of each offer at each phase, so they can be compared.
  • Copy data forward from one phase to another to prevent re-entry.
    • This is done manually by IT.
      • Export the source phase to csv.
      • Remove unnecessary rows:
        • Keep only the current year, and the phase being copied forward.
        • Also drop any Abandoned records.
      • Fix the columns:
        • Change the columns for phase to the new values
          • initial/Initial Offer/Initial Request or final/Final Offer/Final Project
        • Copy the ID’s from the ID column to the Previous ID column.
        • Blank out the ID column
          • IMPORTANT: This forces the import to create new records instead of updating the original ones.
      • Import back to create brand-new entries.
        • NOTE: There is a very important checkbox on the Import “Import files. If you would like to import files from your CSV, check this box.”.  Without this, the attachments from one phase will not copy forward to the new phase.
        • NOTE 2: Watch out for the fields with calculated titles!  The Performance-Measure Baselines and Targets, and the Capital Project Out-year Amounts, need to be adjusted on the import screen or they will not come in.  You can see the CSV column header on the left matched up to an EMPTY field on the right.  Use the drop-list to get the right-hand field to the correct one.
  • At certain points, lock some parts of previous entries from edit to avoid them changing after being reviewed.
    • As of 2020, this is done via a BFO Configuration form entry (only one entry should ever exist) edited by an Administrator from its own matching page and menu option.
Theme and Tools
  • Divi
  • Formidable Forms
    • Show/hide sections per phase (For 2020, the form was split to multi-page, with pages hidden per phase.)
    • Accordion the multiple Performance Measures
    • Export from one phase, import back as next phase
  • Print-o-Matic plugin to allow pretty screen prints to pdf
  • Ultimate Member for user registration
  • Custom plugin code: Site plugin with several custom functions :
    • Rename and move attachments to custom folders per phase.
    • Determine whether user has right to edit and/or review individual offers/projects;
      • Also whether Adds are allowed depending on Review Mode, and whether a Review Admin can see entries from other reviewers.
    • Some custom handling for user-account registration (includes a custom Department metadata field via Ultimate Member).
    • Allow csv file type to be uploaded.
    • Limit number of words allowed in the “Summary” field.
Possible Enhancements for Budget Year 2022
  • add link to previous phase’s view and reviews to the current phase view of an offer/project

  • add a required field for city approved funding in the prior year for both agency and offer level

Changes for Budget Year 2021
  • Allow for identification of offers by three types: Core with no change, Core with substantial change, or New/Innovative
    • Added a drop-list field for Offer Type to page 1
    • Added a field for “purpose of changes” to page 4”
    • Made the page-4 fields conditional:
      • Core offers have just Outcomes and Additional Info
      • Core/Change offers have those two plus “Purpose of Changes”
      • New/Innovative offers have those two plus “Outcome Plan” and “Problem Solved”
    • Added these fields to the Review at the end of the offer entry, and to the View of existing offers.
    • Added new Offer Type to search criteria
      • Both Initial and Repeat Search forms
        • New data-entry field
        • Add parameter to the url that calls the view
      • List View
        • Add new parameter to selection criteria
        • Display new parameter in header bar
      • Bulk-print for pdf
        • Add parameter to the url that calls the view
      • List-for-pdf View
        • Add new parameter to selection criteria
        • Display new parameter in header bar
  • Fixed styling issue the Print-O-Matic plugin (lost its CSS during server conversion)
  • Tried to find/fix the display of review information on the View page, to keep it from showing too soon (when reviews have started but not yet completed)
    • Ending up blocking display of all reviews (any year or phase) whenever the current year/phase is in Review Mode
Possible enhancements for 2021
  • Automate the copy-forward process.  Caution: Be sure the process also copies all attachments forward.
    • Possible coding technique (but does NOT handle attachments properly):
      • $all_entries = FrmEntry::getAll( array( ‘it.form_key’ = “bfo” ), true ) ;

        // Gets ALL entries, we need to trim down to correct entries to copy

        foreach ($all_entries as $an_entry) {
        $entry = FrmEntry::getOne($an_entry->id);

        if ($entry…meta…year = right one and
        $entry…meta…phase = right one and
        $entry…meta…abandoned <> yes) {

        $new_entry = $entry
        modify $new_entry fields to new phase and
        previous phase id and
        blank id
        create new entry
    • Another possibility: Programmatically output a proper .csv file, then immediately import it back in.  That would take advantage of Formidable import without having to do the manual csv manipulation.
  • Have the List/Edit menu open directly to a list, selected using the default criteria.  This would avoid the initial “stop” to confirm the default criteria before any data is shown.
  • Find a way to compare Final entry to the Initial one, so Reviewers can identify changes made between phases.  Maybe compare fields (one at a time) and highlight in Final if different from from Initial.
  • Condition the Feedback at the end of the Review so it does not show during Review mode of the current phase.  (Keep offerors from seeing partially-entered review information.)
  • Possibly make a way for a reviewer to enter comments only, without being included in the average as a score of 0.  (Justin Steinmann wanted this so he could add his comments to all projects without affecting their average.)
  • Resolve issue with “facilities projects only” scores within project type of City Internal Operations.  When a project of this type is NOT a facilities project, the resulting score of 0 falsely lowers the average.  Probably, best solution is to have Facilities as a separate project type, more normalized that having a conditional score within a single type.
  • Provide agency-upload fields for specific attachments (charter, audit, etc) in addition to a generic upload-anything field.
  • Provide a place for the BFO team to upload agency-related attachments AFTER the end of the process for the agencies to see (like the Award Letters).
  • Allow for true scoring on Final phase similar to Initial.
  • Allow reviewer to enter notes into the offer for their private use prior to entering their review.
  • Re-check with users re: scoring: Multiple reviewers and automated average vs. team lead entering one consensus score.


Changes in Budget Year 2020
  • Greatly increased support for Capital Projects, making it a complete parallel to BFO Offers.
  • Added in-app scoring, with a new Review form to be entered by each Reviewer, for each Offer/Project.
    • See detailed documentation in separate section of this page.
  • Switched data-entry forms to multi-page, with a final “review” page before the main Submit button.
  • Improved singleton View output formatting to match previous-year PDF’s.
    • Included hyperlinks to Attachments (both individual offer and Agency-level).
    • Goal was to prevent need for Reviewers to have anything exported to PDF or hard-copy.
    • However, also provided in-app way to export to pdf, either a single offer or all offers selected for the List/Edit.
  • Added budget-year to Agency Attachments (previously was a single record per Agency, forever).
  • Added BFO Configuration form and entry to control what is the current year, phase, and review mode.
    • This record is checked often, and from many places.  Those include:
      • Data-entry forms, to set default values
      • Views, to limit data and options shown to only relevant year/phase/review-mode
      • If-Menu, to limit menu options to relevant
      • Pages, to limit whether or not to even display the data, or to display a “not available now” message
    • The record can be set from a menu option available only to Administrators.  There are three versions of the phase name: “short”, “offer”, and “capital”.  A plugin function automatically sets “offer” and “capital” to match “short”.
New Formidable Techniques in 2020

Relating one entry to another

  • An Offer or Project Request from one phase knows its predecessor in the previous phase.
  • A Review knows the Offer or Request being Reviewed.
  • The two things above, together, mean that we can show the Review of the previous-phase record while editing the current-phase one.

Number and Math handling

  • The money fields use a RegEx ( ^\$?\d{0,3}\,?\d{0,3}\,?\d{1,3}?(\.\d\d?)?$ )  to validate for optional $-sign, optional commas, optional decimal-and-cents, but require at least one non-decimal digit.
  • The Before-Content of the Reviews-per-Offer (or Project) Views use the frm-math shortcode to compute the average of multiple review scores.  Those scores are summed and counted before averaging, using the frm-stats shortcode.
  • A site-plugin function uses the frm-before-display-content hook to sum all the amounts being listed for a context-sensitive grand total.

Reading to another entry

  • The new BFO Configuration Record has Year, Phase, and Review Mode fields in a specific Formidable Entry.  Those fields are read in many places using the frm-form-field-value shortcode.

frm-condition shortcode

  • Used to base logic on the Configuration Record: frm-condition source=frm-field-value field_id=offer_phase entry=offer equals=”Initial Offer”
  • Used to call a custom shortcode to decide whether to show Edit link: frm-condition source=bfo_check_edit dept=”offer_dept_agency” phase=”offer_phase_hidden” budget_year=”offer_budget_year” equals=1
  • Note: Was not able to find a way to nest conditions.  However, did succeed in nesting an “if” inside a frm-condition to get compound logic.  Also put some of the compound logic into the site plugin used in “bfo_check_edit” above.

Print to PDF

  • Found new plugin Print-O-Matic whose shortcode “print-me” will add a print icon to the page, and print only the main content with no headers, footers, or sidebars.


  • Used just a little custom CSS added in the area allowed by the theme to give pretty styling to the main Detail Offer/Project Views.
  • Made use of those same custom classes to give a bit of header styling to most of the pages.
  • Used the Formidable Styles settings to make the buttons match the custom CSS.

HTML Tables

  • Used tables within the Views to give prettier presentation of the selected records (compared to the 2019 version of the app).

HTML within Forms

  • Used a big HTML block to give a “review” page at the end of the multi-page forms.
    • Note that this block mimics the main Detail View.  But it cannot do any conditioning, and it must refer to fields by numeric ID instead of by Key.

URL parameters

  • Passed features such as previous-phase-ID, ID-being-reviewed, bulk-print-pdf, year, phase, review-mode from one form or page to another.
  • Occasionally set those parameters in a Divi Module on the page, before calling the form or view that uses them.

Multiple features on one page

  • Showed Reviews on page above the Edit form, and at the end of the Detail View.
  • Showed the Detail View from within the List View (as the drill-down for the “view” link)


Offers and Reviews between Phases, as of Budget Year 2020
Added new concept of a separate Review form.  There should be one Review entry per Reviewer, per Offer, per Phase.  Initial phase has multiple reviews; Pre-Submission and Final need only one.  So Offer “I want money” would have:

  • ID 1 in Presub with a single Review associated, giving the red/yellow/green status;
  • ID 2 in Initial Phase with Reviews from multiple reviewers, giving scores in several criteria; and
  • ID 3 in Final with a single Review telling whether the budget was awarded and for what amount.


These need to be displayed in the appropriate places.

  • When reviewing an offer (say ID #2 Initial Phase), the reviewer needs to see details of that offer while doing their data entry in the Review form (which has its own entry ID).
  • When editing an offer (such as ID #2 Initial), the offeror needs to see the reviews associated with the previous phase offer ID (ID #1 Presub).


This is accomplished with a couple of interacting tricks.

  • When copying all offers from one phase forward to another, the original offer ID is preserved in a separate field “previous_phase_id”.
  • Pages are designed with Divi Builder using two sections on the same page, showing the view needed from one entry ID and the form from another, with those ID’s passed in the url.
    • The standard “Entry” argument in the url applies to the “real” record being edited, as required by Formidable.
    • The “Offer” or “Proj” argument applies to specific Offer/Project ID whose detail content (or review content) needs to be displayed in a read-only view.


From the main BFO list drill-downs:

  • View sends the selected “entry” from the list tab to the detail tab as always.  It also sends the same value as “offer” (or “proj” for Capital).
  • Edit sends the selected “entry” for the data-entry Form, and the previous phase entry as the “offer” for the read-only View of related Reviews.
  • Review starts an Add for a new review data-entry Form, and sends the selected offer entry as “offer” for the read-only View of offer details.
    • The review data-entry and the matching view (below) show different fields depending on the phase of the record being reviewed.
    • This option is shown only to users with a role as Reviewer for the phase of that offer.  Separate roles and reviewers are allowed for Presub vs. Initial vs. Final.
  • # of Reviews shows only to Admins.  It tells how many reviews have been entered for that offer, and allows drill-down to a list and detail pages of those reviews.  No one other than Admin should be able to see which reviewer entered which scores or comments.


From the Reviews-per-Reviewer drill-down (which is limited to reviews entered by the current user, so they can modify if necessary):

  • Edit sends the entry of the selected existing review for the data-enty Form, and its reviewed-offer-id as read-only “offer” View.


The Single-offer View does a pretty display of the “offer” value sent, from either the BFO-list “view” or the Review-list “review”.  At the end, it also does a display of the related Review(s).

The reviews-per-offer View does a sum of the multiple reviewers’ scores (or displays the single review for presub or final), and displays all their comments, related to the “offer” value sent.  This is displayed at the end of the single-offer View, and at the top of the page before the offer data-entry form.

Manual changes between phases (for FY 19)
The BFO Configuration form in 2020 replaced all of this.
phase: presub
  • Phase default/only for Add = presub
  • Phase default/only for Search = presub
  • sub-phase: entry
    • Menu option “Add” available for BFO Authors
    • View option “Edit” available
    • “Edit own entries” = logged-in users
    • “Edit other’s entries” = null (not Editor yet)
  • sub-phase: review
    • Menu option “Add” not available for BFO Authors (ever again)
    • View option “Edit” available (but only Editor/Admin‘s, due to below
    • “Edit own entries” = BFO Admin (should not be used
    • “Edit other’s entries” = BFO Editors (in order to enter feedback)


phase: initial
  • Phase default/only for Add = initial (should never be used anyway)
  • Phase default/changeable for Search = initial
  • sub-phase: entry
    • Menu option “Add” not available for BFO Authors
    • View option “Edit” available only for Initial, not for presub
    • “Edit own entries” = logged-in users
    • “Edit other’s entries” = null
  • sub-phase: review
    • Menu option “Add” not available for BFO Authors
    • View option “Edit” available (but only Editor/Admin‘s, see below)
    • “Edit own entries” = BFO Admin
    • “Edit other’s entries” = BFO Editors
phase: final
  • Phase default/only for Add = final (should never be used anyway)
  • Phase default/changeable for Search = final
  • sub-phase: entry
    • Menu option “Add” not available for BFO Authors
    • View option “Edit” available only for Final, not for presub or initial
    • “Edit own entries” = logged-in users
    • “Edit other’s entries” = null
  • sub-phase: review
    • Menu option “Add” not available for BFO Authors
    • View option “Edit” available (but only Editor/Admin’s, see below)
    • “Edit own entries” = BFO Admin
    • “Edit other’s entries” = BFO Editors
Notes and Issues from Budget Year 2019
  • The reviewers were not willing to work inside the app.  Chris Brown used the csv export and a Google add-on to create pdf’s for them.  Their feedback was entered into a spreadsheet (based on the csv export) for import back into the next phase.
    • Per information learned for the 2020 budget year, each reviewer was expected to submit their own feedback.  The app was designed for only one feedback per offer, expecting that the review committee met and entered a consensus feedback.  The mistaken understanding was corrected in the 2020 version of the app.
  • The convenience provided for offerers of defaulting the Search criteria to the current user, was a hindrance to reviewers who needed to see offers across multiple offerers.
    • This was a disincentive for the reviewers to enter feedback into the app.  But they didn’t mention the issue until after the first feedback time frame was complete.  It was a simple 2-minute fix.  But it needed to be put back the other way for the offerers to work in the next phase.  In 2020 the default department is still there, but the email address is no longer being defaulted.
  • The security to prevent offerers from updating one another’s entries interfered with department heads updating an entry (although they could see it, since we didn’t try to limit any read-only access).  It also interfered with collaboration of multiple employees on a single offer.
    • The solution was mostly to instruct users to collaborate in outside documents but have only a single account do the entry.
    • We gave some department heads elevated rights as a workaround so they could update everything they needed.
    • We also manually changed the “owner” of some offers as need arose.
    • The 2020 version modified the logic so that all users registered to the same department could edit all records for the department, regardless of original data-entry “owner”.
  • “Rules” were fluid.  Exceptions were frequent.
    • “No offer entry after deadline” became “Please add this one latecomer…and then this second one”.
    • “No modifications after phase” became “Except for some fields”.  In 2020, some of this was resolved by moving the Review data to its own form, eliminating the need for reviewers to edit the actual main entry.
    • “Everyone do at least an Initial offer, if not a Pre-Submission” became “Some people don’t add their offer until Final phase”.  In 2020, the BFO Configuration form eased this problem.
  • Control of which phase we were in, and which sub-phase (entry or review) was done by manually modifying the Form settings each step.  See documentation of that in a separate section.  In 2020, this was replaced by a BFO Configuration form and entry to specify the current year/phase/review-mode.
Skip to toolbar